Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Merge recent addtional features (integrate, reports, timeline, et al.) from trunk. |
|---|---|
| Timelines: | family | ancestors | descendants | both | ssh-shared-account |
| Files: | files | file ages | folders |
| SHA1: |
a5df66f3aa7a5fe07c715395c4d4be4d |
| User & Date: | andybradford 2013-08-05 17:39:48.915 |
Context
|
2013-08-06
| ||
| 04:03 | Changed prompt to remove ambiguity between SSH user vs Fossil user. check-in: f592b80a17 user: andybradford tags: ssh-shared-account | |
|
2013-08-05
| ||
| 17:39 | Merge recent addtional features (integrate, reports, timeline, et al.) from trunk. check-in: a5df66f3aa user: andybradford tags: ssh-shared-account | |
| 13:04 | Install the latest SQLite 3.8.0 beta from upstream. Fossil does not use any of the new features. This commit is for the purpose of testing SQLite. check-in: 605db92957 user: drh tags: trunk | |
|
2013-08-03
| ||
| 03:09 | Defer output of stats until the transport has been opened. This will also help with HTTPs when using client peer certificates (or unrecognized CAs). check-in: d1771cd138 user: andybradford tags: ssh-shared-account | |
Changes
Changes to src/cgi.c.
| ︙ | ︙ | |||
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 |
va_start(ap, zFormat);
vxprintf(pContent,zFormat,ap);
va_end(ap);
cgi_reply();
fossil_exit(1);
}
}
/*
** Remove the first space-delimited token from a string and return
** a pointer to it. Add a NULL to the string to terminate the token.
** Make *zLeftOver point to the start of the next token.
*/
static char *extract_token(char *zInput, char **zLeftOver){
| > > > > > > > > > > > > > > | 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 |
va_start(ap, zFormat);
vxprintf(pContent,zFormat,ap);
va_end(ap);
cgi_reply();
fossil_exit(1);
}
}
/* z[] is the value of an X-FORWARDED-FOR: line in an HTTP header.
** Return a pointer to a string containing the real IP address, or a
** NULL pointer to stick with the IP address previously computed and
** loaded into g.zIpAddr.
*/
static const char *cgi_accept_forwarded_for(const char *z){
int i;
if( fossil_strcmp(g.zIpAddr, "127.0.0.1")!=0 ) return 0;
i = strlen(z)-1;
while( i>=0 && z[i]!=',' && !fossil_isspace(z[i]) ) i--;
return &z[++i];
}
/*
** Remove the first space-delimited token from a string and return
** a pointer to it. Add a NULL to the string to terminate the token.
** Make *zLeftOver point to the start of the next token.
*/
static char *extract_token(char *zInput, char **zLeftOver){
|
| ︙ | ︙ | |||
1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 |
struct sockaddr_in remoteName;
socklen_t size = sizeof(struct sockaddr_in);
char zLine[2000]; /* A single line of input. */
g.fullHttpReply = 1;
if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
malformed_request();
}
cgi_trace(zLine);
zToken = extract_token(zLine, &z);
if( zToken==0 ){
malformed_request();
}
if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0
&& fossil_strcmp(zToken,"HEAD")!=0 ){
| > | 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 |
struct sockaddr_in remoteName;
socklen_t size = sizeof(struct sockaddr_in);
char zLine[2000]; /* A single line of input. */
g.fullHttpReply = 1;
if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
malformed_request();
}
blob_append(&g.httpHeader, zLine, -1);
cgi_trace(zLine);
zToken = extract_token(zLine, &z);
if( zToken==0 ){
malformed_request();
}
if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0
&& fossil_strcmp(zToken,"HEAD")!=0 ){
|
| ︙ | ︙ | |||
1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 |
/* Get all the optional fields that follow the first line.
*/
while( fgets(zLine,sizeof(zLine),g.httpIn) ){
char *zFieldName;
char *zVal;
cgi_trace(zLine);
zFieldName = extract_token(zLine,&zVal);
if( zFieldName==0 || *zFieldName==0 ) break;
while( fossil_isspace(*zVal) ){ zVal++; }
i = strlen(zVal);
while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
zVal[i] = 0;
for(i=0; zFieldName[i]; i++){
| > | 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 |
/* Get all the optional fields that follow the first line.
*/
while( fgets(zLine,sizeof(zLine),g.httpIn) ){
char *zFieldName;
char *zVal;
cgi_trace(zLine);
blob_append(&g.httpHeader, zLine, -1);
zFieldName = extract_token(zLine,&zVal);
if( zFieldName==0 || *zFieldName==0 ) break;
while( fossil_isspace(*zVal) ){ zVal++; }
i = strlen(zVal);
while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
zVal[i] = 0;
for(i=0; zFieldName[i]; i++){
|
| ︙ | ︙ | |||
1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 |
cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
#if 0
}else if( fossil_strcmp(zFieldName,"referer:")==0 ){
cgi_setenv("HTTP_REFERER", zVal);
#endif
}else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
cgi_setenv("HTTP_USER_AGENT", zVal);
}
}
cgi_init();
cgi_trace(0);
}
#if INTERFACE
| > > > > > > | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 |
cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
#if 0
}else if( fossil_strcmp(zFieldName,"referer:")==0 ){
cgi_setenv("HTTP_REFERER", zVal);
#endif
}else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
cgi_setenv("HTTP_USER_AGENT", zVal);
}else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
const char *zIpAddr = cgi_accept_forwarded_for(zVal);
if( zIpAddr!=0 ){
g.zIpAddr = mprintf("%s", zIpAddr);
cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
}
}
}
cgi_init();
cgi_trace(0);
}
#if INTERFACE
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
}else if( isDeleted ){
blob_appendf(report, "DELETED %s\n", zDisplayName);
}else if( isChnged ){
if( isChnged==2 ){
blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
}else if( isChnged==3 ){
blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
}else if( file_contains_merge_marker(zFullName) ){
blob_appendf(report, "CONFLICT %s\n", zDisplayName);
}else{
blob_appendf(report, "EDITED %s\n", zDisplayName);
}
}else if( isRenamed ){
blob_appendf(report, "RENAMED %s\n", zDisplayName);
| > > > > | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
}else if( isDeleted ){
blob_appendf(report, "DELETED %s\n", zDisplayName);
}else if( isChnged ){
if( isChnged==2 ){
blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
}else if( isChnged==3 ){
blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
}else if( isChnged==4 ){
blob_appendf(report, "UPDATED_BY_INTEGRATE %s\n", zDisplayName);
}else if( isChnged==5 ){
blob_appendf(report, "ADDED_BY_INTEGRATE %s\n", zDisplayName);
}else if( file_contains_merge_marker(zFullName) ){
blob_appendf(report, "CONFLICT %s\n", zDisplayName);
}else{
blob_appendf(report, "EDITED %s\n", zDisplayName);
}
}else if( isRenamed ){
blob_appendf(report, "RENAMED %s\n", zDisplayName);
|
| ︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
" WHERE id<=0");
while( db_step(&q)==SQLITE_ROW ){
const char *zLabel = "MERGED_WITH";
switch( db_column_int(&q, 1) ){
case -1: zLabel = "CHERRYPICK "; break;
case -2: zLabel = "BACKOUT "; break;
}
blob_append(report, zPrefix, nPrefix);
blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
}
db_finalize(&q);
if( nErr ){
fossil_fatal("aborting due to prior errors");
| > | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
" WHERE id<=0");
while( db_step(&q)==SQLITE_ROW ){
const char *zLabel = "MERGED_WITH";
switch( db_column_int(&q, 1) ){
case -1: zLabel = "CHERRYPICK "; break;
case -2: zLabel = "BACKOUT "; break;
case -4: zLabel = "INTEGRATE "; break;
}
blob_append(report, zPrefix, nPrefix);
blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
}
db_finalize(&q);
if( nErr ){
fossil_fatal("aborting due to prior errors");
|
| ︙ | ︙ | |||
330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
type = "MISSING ";
}
}else if( chnged ){
if( chnged==2 ){
type = "UPDATED_BY_MERGE ";
}else if( chnged==3 ){
type = "ADDED_BY_MERGE ";
}else if( file_contains_merge_marker(zFullName) ){
type = "CONFLICT ";
}else{
type = "EDITED ";
}
}else if( renamed ){
type = "RENAMED ";
| > > > > | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
type = "MISSING ";
}
}else if( chnged ){
if( chnged==2 ){
type = "UPDATED_BY_MERGE ";
}else if( chnged==3 ){
type = "ADDED_BY_MERGE ";
}else if( chnged==4 ){
type = "UPDATED_BY_INTEGRATE ";
}else if( chnged==5 ){
type = "ADDED_BY_INTEGRATE ";
}else if( file_contains_merge_marker(zFullName) ){
type = "CONFLICT ";
}else{
type = "EDITED ";
}
}else if( renamed ){
type = "RENAMED ";
|
| ︙ | ︙ | |||
1676 1677 1678 1679 1680 1681 1682 |
/* If the -n|--dry-run option is specified, output the manifest file
** and rollback the transaction.
*/
if( dryRunFlag ){
blob_write_to_file(&manifest, "");
}
| < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 |
/* If the -n|--dry-run option is specified, output the manifest file
** and rollback the transaction.
*/
if( dryRunFlag ){
blob_write_to_file(&manifest, "");
}
if( outputManifest ){
zManifestFile = mprintf("%smanifest", g.zLocalRoot);
blob_write_to_file(&manifest, zManifestFile);
blob_reset(&manifest);
blob_read_from_file(&manifest, zManifestFile);
free(zManifestFile);
}
nvid = content_put(&manifest);
if( nvid==0 ){
fossil_panic("trouble committing manifest: %s", g.zErrMsg);
}
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
manifest_crosslink(nvid, &manifest);
db_prepare(&q, "SELECT uuid,merge FROM vmerge JOIN blob ON merge=rid"
" WHERE id=-4");
while( db_step(&q)==SQLITE_ROW ){
const char *zIntegrateUuid = db_column_text(&q, 0);
int rid = db_column_int(&q, 1);
if( !is_a_leaf(rid) ){
fossil_print("Not_Closed: %s (not a leaf any more)\n", zIntegrateUuid);
}else{
if (!db_exists("SELECT 1 FROM tagxref "
" WHERE tagid=%d AND rid=%d AND tagtype>0",
TAG_CLOSED, rid)
){
Blob ctrl;
Blob cksum;
char *zDate;
int nrid;
blob_zero(&ctrl);
zDate = date_in_standard_format(sCiInfo.zDateOvrd ? sCiInfo.zDateOvrd : "now");
blob_appendf(&ctrl, "D %s\n", zDate);
blob_appendf(&ctrl, "T +closed %s\n", zIntegrateUuid);
blob_appendf(&ctrl, "U %F\n", sCiInfo.zUserOvrd ? sCiInfo.zUserOvrd : g.zLogin);
md5sum_blob(&ctrl, &cksum);
blob_appendf(&ctrl, "Z %b\n", &cksum);
nrid = content_put(&ctrl);
manifest_crosslink(nrid, &ctrl);
assert( blob_is_reset(&ctrl) );
}
fossil_print("Closed: %s\n", zIntegrateUuid);
}
}
db_finalize(&q);
assert( blob_is_reset(&manifest) );
content_deltify(vid, nvid, 0);
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
fossil_print("New_Version: %s\n", zUuid);
if( outputManifest ){
zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot);
blob_zero(&muuid);
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
1441 1442 1443 1444 1445 1446 1447 |
rid = name_to_rid_www("name");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 |
rid = name_to_rid_www("name");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
style_header("Hex Artifact Content");
|
| ︙ | ︙ | |||
1591 1592 1593 1594 1595 1596 1597 |
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 |
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
style_header("Artifact Content");
|
| ︙ | ︙ | |||
1699 1700 1701 1702 1703 1704 1705 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
rid = name_to_rid_www("name");
if( rid==0 ){ fossil_redirect_home(); }
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( g.perm.Admin ){
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
rid = name_to_rid_www("name");
if( rid==0 ){ fossil_redirect_home(); }
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( g.perm.Admin ){
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
pTktChng = manifest_get(rid, CFTYPE_TICKET);
|
| ︙ | ︙ |
Changes to src/json_status.c.
| ︙ | ︙ | |||
155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
" WHERE id<=0");
while( db_step(&q)==SQLITE_ROW ){
const char *zLabel = "MERGED_WITH";
switch( db_column_int(&q, 1) ){
case -1: zLabel = "CHERRYPICK "; break;
case -2: zLabel = "BACKOUT "; break;
}
blob_append(report, zPrefix, nPrefix);
blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
}
db_finalize(&q);
if( nErr ){
fossil_fatal("aborting due to prior errors");
| > | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
" WHERE id<=0");
while( db_step(&q)==SQLITE_ROW ){
const char *zLabel = "MERGED_WITH";
switch( db_column_int(&q, 1) ){
case -1: zLabel = "CHERRYPICK "; break;
case -2: zLabel = "BACKOUT "; break;
case -4: zLabel = "INTEGRATE "; break;
}
blob_append(report, zPrefix, nPrefix);
blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
}
db_finalize(&q);
if( nErr ){
fossil_fatal("aborting due to prior errors");
|
| ︙ | ︙ |
Changes to src/json_timeline.c.
| ︙ | ︙ | |||
96 97 98 99 100 101 102 |
/* Field order MUST match that from json_timeline_temp_table()!!! */
static const char zBaseSql[] =
@ SELECT
@ NULL,
@ blob.rid,
@ uuid,
@ CAST(strftime('%%s',event.mtime) AS INTEGER),
| | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
/* Field order MUST match that from json_timeline_temp_table()!!! */
static const char zBaseSql[] =
@ SELECT
@ NULL,
@ blob.rid,
@ uuid,
@ CAST(strftime('%%s',event.mtime) AS INTEGER),
@ datetime(event.mtime),
@ coalesce(ecomment, comment),
@ coalesce(euser, user),
@ blob.rid IN leaf,
@ bgcolor,
@ event.type,
@ (SELECT group_concat(substr(tagname,5), ',') FROM tag, tagxref
@ WHERE tagname GLOB 'sym-*' AND tag.tagid=tagxref.tagid
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
160 161 162 163 164 165 166 167 168 169 170 171 172 173 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ int clockSkewSeen; /* True if clocks on client and server out of sync */ int wikiFlags; /* Wiki conversion flags applied to %w and %W */ char isHTTP; /* True if server/CGI modes, else assume CLI. */ char javascriptHyperlink; /* If true, set href= using script, not HTML */ int urlIsFile; /* True if a "file:" url */ int urlIsHttps; /* True if a "https:" url */ int urlIsSsh; /* True if an "ssh:" url */ char *urlName; /* Hostname for http: or filename for file: */ char *urlHostname; /* The HOST: parameter on http headers */ char *urlProtocol; /* "http" or "https" */ | > | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ int clockSkewSeen; /* True if clocks on client and server out of sync */ int wikiFlags; /* Wiki conversion flags applied to %w and %W */ char isHTTP; /* True if server/CGI modes, else assume CLI. */ char javascriptHyperlink; /* If true, set href= using script, not HTML */ Blob httpHeader; /* Complete text of the HTTP request header */ int urlIsFile; /* True if a "file:" url */ int urlIsHttps; /* True if a "https:" url */ int urlIsSsh; /* True if an "ssh:" url */ char *urlName; /* Hostname for http: or filename for file: */ char *urlHostname; /* The HOST: parameter on http headers */ char *urlProtocol; /* "http" or "https" */ |
| ︙ | ︙ | |||
528 529 530 531 532 533 534 535 536 537 538 539 540 541 |
{
const char *zCmdName = "unknown";
int idx;
int rc;
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
memset(&g, 0, sizeof(g));
g.now = time(0);
#ifdef FOSSIL_ENABLE_JSON
#if defined(NDEBUG)
g.json.errorDetailParanoia = 2 /* FIXME: make configurable
One problem we have here is that this
code is needed before the db is opened,
so we can't sql for it.*/;
#else
| > | 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 |
{
const char *zCmdName = "unknown";
int idx;
int rc;
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
memset(&g, 0, sizeof(g));
g.now = time(0);
g.httpHeader = empty_blob;
#ifdef FOSSIL_ENABLE_JSON
#if defined(NDEBUG)
g.json.errorDetailParanoia = 2 /* FIXME: make configurable
One problem we have here is that this
code is needed before the db is opened,
so we can't sql for it.*/;
#else
|
| ︙ | ︙ |
Changes to src/merge.c.
| ︙ | ︙ | |||
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
**
** --case-sensitive BOOL Override the case-sensitive setting. If false,
** files whose names differ only in case are taken
** to be the same file.
**
** -f|--force Force the merge even if it would be a no-op.
**
** -n|--dry-run If given, display instead of run actions
**
** -v|--verbose Show additional details of the merge
*/
void merge_cmd(void){
int vid; /* Current version "V" */
int mid; /* Version we are merging from "M" */
int pid; /* The pivot version - most recent common ancestor P */
int verboseFlag; /* True if the -v|--verbose option is present */
int pickFlag; /* True if the --cherrypick option is present */
int backoutFlag; /* True if the --backout option is present */
int dryRunFlag; /* True if the --dry-run or -n option is present */
int forceFlag; /* True if the --force or -f option is present */
const char *zBinGlob; /* The value of --binary */
const char *zPivot; /* The value of --baseline */
int debugFlag; /* True if --debug is present */
| > > > | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
**
** --case-sensitive BOOL Override the case-sensitive setting. If false,
** files whose names differ only in case are taken
** to be the same file.
**
** -f|--force Force the merge even if it would be a no-op.
**
** --integrate Merged branch will be closed when committing.
**
** -n|--dry-run If given, display instead of run actions
**
** -v|--verbose Show additional details of the merge
*/
void merge_cmd(void){
int vid; /* Current version "V" */
int mid; /* Version we are merging from "M" */
int pid; /* The pivot version - most recent common ancestor P */
int verboseFlag; /* True if the -v|--verbose option is present */
int integrateFlag; /* True if the --integrate option is present */
int pickFlag; /* True if the --cherrypick option is present */
int backoutFlag; /* True if the --backout option is present */
int dryRunFlag; /* True if the --dry-run or -n option is present */
int forceFlag; /* True if the --force or -f option is present */
const char *zBinGlob; /* The value of --binary */
const char *zPivot; /* The value of --baseline */
int debugFlag; /* True if --debug is present */
|
| ︙ | ︙ | |||
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
undo_capture_command_line();
verboseFlag = find_option("verbose","v",0)!=0;
if( !verboseFlag ){
verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
}
pickFlag = find_option("cherrypick",0,0)!=0;
backoutFlag = find_option("backout",0,0)!=0;
debugFlag = find_option("debug",0,0)!=0;
zBinGlob = find_option("binary",0,1);
dryRunFlag = find_option("dry-run","n",0)!=0;
if( !dryRunFlag ){
dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */
}
| > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
undo_capture_command_line();
verboseFlag = find_option("verbose","v",0)!=0;
if( !verboseFlag ){
verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
}
pickFlag = find_option("cherrypick",0,0)!=0;
integrateFlag = find_option("integrate",0,0)!=0;
backoutFlag = find_option("backout",0,0)!=0;
debugFlag = find_option("debug",0,0)!=0;
zBinGlob = find_option("binary",0,1);
dryRunFlag = find_option("dry-run","n",0)!=0;
if( !dryRunFlag ){
dryRunFlag = find_option("nochange",0,0)!=0; /* deprecated */
}
|
| ︙ | ︙ | |||
160 161 162 163 164 165 166 |
/* No version specified on the command-line so pick the most recent
** leaf that is (1) not the version currently checked out and (2)
** has not already been merged into the current checkout and (3)
** the leaf is not closed and (4) the leaf is in the same branch
** as the current checkout.
*/
Stmt q;
| | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
/* No version specified on the command-line so pick the most recent
** leaf that is (1) not the version currently checked out and (2)
** has not already been merged into the current checkout and (3)
** the leaf is not closed and (4) the leaf is in the same branch
** as the current checkout.
*/
Stmt q;
if( pickFlag || backoutFlag || integrateFlag){
fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge");
}
mid = db_int(0,
"SELECT leaf.rid"
" FROM leaf, event"
" WHERE leaf.rid=event.objid"
" AND leaf.rid!=%d" /* Constraint (1) */
" AND leaf.rid NOT IN (SELECT merge FROM vmerge)" /* Constraint (2) */
|
| ︙ | ︙ | |||
218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
if( pid==0 || !is_a_version(pid) ){
fossil_fatal("not a version: %s", zPivot);
}
if( pickFlag ){
fossil_fatal("incompatible options: --cherrypick & --baseline");
}
}else if( pickFlag || backoutFlag ){
pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid);
if( pid<=0 ){
fossil_fatal("cannot find an ancestor for %s", g.argv[2]);
}
}else{
pivot_set_primary(mid);
pivot_set_secondary(vid);
| > > > | 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
if( pid==0 || !is_a_version(pid) ){
fossil_fatal("not a version: %s", zPivot);
}
if( pickFlag ){
fossil_fatal("incompatible options: --cherrypick & --baseline");
}
}else if( pickFlag || backoutFlag ){
if( integrateFlag ){
fossil_fatal("incompatible options: --integrate & --cherrypick or --backout");
}
pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid);
if( pid<=0 ){
fossil_fatal("cannot find an ancestor for %s", g.argv[2]);
}
}else{
pivot_set_primary(mid);
pivot_set_secondary(vid);
|
| ︙ | ︙ | |||
249 250 251 252 253 254 255 256 |
fossil_fatal("not a version: record #%d", pid);
}
if( !forceFlag && mid==pid ){
fossil_print("Merge skipped because it is a no-op. "
" Use --force to override.\n");
return;
}
if( verboseFlag ){
| > > > > | | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
fossil_fatal("not a version: record #%d", pid);
}
if( !forceFlag && mid==pid ){
fossil_print("Merge skipped because it is a no-op. "
" Use --force to override.\n");
return;
}
if( integrateFlag && !is_a_leaf(mid) ){
fossil_warning("ignoring --integrate: %s is not a leaf", g.argv[2]);
integrateFlag = 0;
}
if( verboseFlag ){
print_checkin_description(mid, 12, integrateFlag?"integrate:":"merge-from:");
print_checkin_description(pid, 12, "baseline:");
}
vfile_check_signature(vid, CKSIG_ENOTFILE);
db_begin_transaction();
if( !dryRunFlag ) undo_begin();
load_vfile_from_rid(mid);
load_vfile_from_rid(pid);
|
| ︙ | ︙ | |||
432 433 434 435 436 437 438 |
int idm = db_column_int(&q, 0);
int rowid = db_column_int(&q, 1);
int idv;
const char *zName;
char *zFullName;
db_multi_exec(
"INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
| | | | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
int idm = db_column_int(&q, 0);
int rowid = db_column_int(&q, 1);
int idv;
const char *zName;
char *zFullName;
db_multi_exec(
"INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
" SELECT %d,%d,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
vid, integrateFlag?5:3, idm
);
idv = db_last_insert_rowid();
db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
zName = db_column_text(&q, 2);
zFullName = mprintf("%s%s", g.zLocalRoot, zName);
if( file_wd_isfile_or_link(zFullName) ){
fossil_print("ADDED %s (overwrites an unmanaged file)\n", zName);
|
| ︙ | ︙ | |||
472 473 474 475 476 477 478 |
const char *zName = db_column_text(&q, 2);
int islinkm = db_column_int(&q, 3);
/* Copy content from idm over into idv. Overwrite idv. */
fossil_print("UPDATE %s\n", zName);
if( !dryRunFlag ){
undo_save(zName);
db_multi_exec(
| | | | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
const char *zName = db_column_text(&q, 2);
int islinkm = db_column_int(&q, 3);
/* Copy content from idm over into idv. Overwrite idv. */
fossil_print("UPDATE %s\n", zName);
if( !dryRunFlag ){
undo_save(zName);
db_multi_exec(
"UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d "
" WHERE id=%d", ridm, integrateFlag?4:2, islinkm, idv
);
vfile_to_disk(0, idv, 0, 0);
}
}
db_finalize(&q);
/*
|
| ︙ | ︙ | |||
642 643 644 645 646 647 648 649 650 651 652 653 654 |
"REPLACE INTO vvar(name,value)"
" SELECT 'ci-comment', coalesce(ecomment,comment) FROM event"
" WHERE type='ci' AND objid=%d",
mid
);
}else if( backoutFlag ){
db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-2,%d)",pid);
}else{
db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid);
}
undo_finish();
db_end_transaction(dryRunFlag);
}
| > > | 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
"REPLACE INTO vvar(name,value)"
" SELECT 'ci-comment', coalesce(ecomment,comment) FROM event"
" WHERE type='ci' AND objid=%d",
mid
);
}else if( backoutFlag ){
db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-2,%d)",pid);
}else if( integrateFlag ){
db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-4,%d)",mid);
}else{
db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid);
}
undo_finish();
db_end_transaction(dryRunFlag);
}
|
Changes to src/schema.c.
| ︙ | ︙ | |||
473 474 475 476 477 478 479 | @ -- Each entry in the vfile table represents a single file in the @ -- current checkout. @ -- @ -- The file.rid field is 0 for files or folders that have been @ -- added but not yet committed. @ -- @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have | | > | | | < | | | | | > | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 | @ -- Each entry in the vfile table represents a single file in the @ -- current checkout. @ -- @ -- The file.rid field is 0 for files or folders that have been @ -- added but not yet committed. @ -- @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have @ -- been edited or which have been subjected to a 3-way merge. @ -- Vfile.chnged is 2 if the file has been replaced from a different @ -- version by the merge and 3 if the file has been added by a merge. @ -- Vfile.chnged is 4|5 is the same as 2|3, but the operation has been @ -- done by an --integrate merge. The difference between vfile.chnged==2|4 @ -- and a regular add is that with vfile.chnged==2|4 we know that the @ -- current version of the file is already in the repository. @ -- @ CREATE TABLE vfile( @ id INTEGER PRIMARY KEY, -- ID of the checked out file @ vid INTEGER REFERENCES blob, -- The baseline this file is part of. @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add 4:i-chng 5:i-add @ deleted BOOLEAN DEFAULT 0, -- True if deleted @ isexe BOOLEAN, -- True if file should be executable @ islink BOOLEAN, -- True if file should be symlink @ rid INTEGER, -- Originally from this repository record @ mrid INTEGER, -- Based on this record due to a merge @ mtime INTEGER, -- Mtime of file on disk. sec since 1970 @ pathname TEXT, -- Full pathname relative to root @ origname TEXT, -- Original pathname. NULL if unchanged @ UNIQUE(pathname,vid) @ ); @ @ -- This table holds a record of uncommitted merges in the local @ -- file tree. If a VFILE entry with id has merged with another @ -- record, there is an entry in this table with (id,merge) where @ -- merge is the RECORD table entry that the file merged against. @ -- An id of 0 or <-3 here means the version record itself. When @ -- id==(-1) that is a cherrypick merge, id==(-2) that is a @ -- backout merge and id==(-4) is a integrate merge. @ @ CREATE TABLE vmerge( @ id INTEGER REFERENCES vfile, -- VFILE entry that has been merged @ merge INTEGER, -- Merged with this record @ UNIQUE(id, merge) @ ); @ |
| ︙ | ︙ |
Changes to src/shell.c.
| ︙ | ︙ | |||
61 62 63 64 65 66 67 | #endif #if defined(_WIN32) || defined(WIN32) # include <io.h> #define isatty(h) _isatty(h) #define access(f,m) _access((f),(m)) #undef popen | | > > > > > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #endif #if defined(_WIN32) || defined(WIN32) # include <io.h> #define isatty(h) _isatty(h) #define access(f,m) _access((f),(m)) #undef popen #define popen _popen #undef pclose #define pclose _pclose #else /* Make sure isatty() has a prototype. */ extern int isatty(int); #endif /* popen and pclose are not C89 functions and so are sometimes omitted from ** the <stdio.h> header */ FILE *popen(const char*,const char*); int pclose(FILE*); #if defined(_WIN32_WCE) /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() * thus we always assume that we have a console. That can be * overridden with the -batch command line option. */ #define isatty(x) 1 |
| ︙ | ︙ | |||
1793 1794 1795 1796 1797 1798 1799 |
*/
if( nArg==0 ) return 0; /* no tokens, no error */
n = strlen30(azArg[0]);
c = azArg[0][0];
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
const char *zDestFile = 0;
const char *zDb = 0;
| < | < < | 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 |
*/
if( nArg==0 ) return 0; /* no tokens, no error */
n = strlen30(azArg[0]);
c = azArg[0][0];
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
const char *zDestFile = 0;
const char *zDb = 0;
sqlite3 *pDest;
sqlite3_backup *pBackup;
int j;
for(j=1; j<nArg; j++){
const char *z = azArg[j];
if( z[0]=='-' ){
while( z[0]=='-' ) z++;
/* No options to process at this time */
{
fprintf(stderr, "unknown option: %s\n", azArg[j]);
return 1;
}
}else if( zDestFile==0 ){
zDestFile = azArg[j];
}else if( zDb==0 ){
|
| ︙ | ︙ | |||
1829 1830 1831 1832 1833 1834 1835 |
if( zDb==0 ) zDb = "main";
rc = sqlite3_open(zDestFile, &pDest);
if( rc!=SQLITE_OK ){
fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
sqlite3_close(pDest);
return 1;
}
| < < < < < | 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 |
if( zDb==0 ) zDb = "main";
rc = sqlite3_open(zDestFile, &pDest);
if( rc!=SQLITE_OK ){
fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
sqlite3_close(pDest);
return 1;
}
open_db(p);
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
if( pBackup==0 ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
sqlite3_close(pDest);
return 1;
}
|
| ︙ | ︙ | |||
2663 2664 2665 2666 2667 2668 2669 |
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
}
break;
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
if( nArg==3 ){
| | | 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 |
fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
}
break;
/* sqlite3_test_control(int, uint) */
case SQLITE_TESTCTRL_PENDING_BYTE:
if( nArg==3 ){
unsigned int opt = (unsigned int)integerValue(azArg[2]);
rc = sqlite3_test_control(testctrl, opt);
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
} else {
fprintf(stderr,"Error: testctrl %s takes a single unsigned"
" int option\n", azArg[1]);
}
break;
|
| ︙ | ︙ |
Changes to src/shun.c.
| ︙ | ︙ | |||
64 65 66 67 68 69 70 |
memcpy(zCanonical, zUuid, UUID_SIZE+1);
canonical16(zCanonical, UUID_SIZE);
zUuid = zCanonical;
}
}
style_header("Shunned Artifacts");
if( zUuid && P("sub") ){
| < | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
memcpy(zCanonical, zUuid, UUID_SIZE+1);
canonical16(zCanonical, UUID_SIZE);
zUuid = zCanonical;
}
}
style_header("Shunned Artifacts");
if( zUuid && P("sub") ){
db_multi_exec("DELETE FROM shun WHERE uuid='%s'", zUuid);
if( db_exists("SELECT 1 FROM blob WHERE uuid='%s'", zUuid) ){
@ <p class="noMoreShun">Artifact
@ <a href="%s(g.zTop)/artifact/%s(zUuid)">%s(zUuid)</a> is no
@ longer being shunned.</p>
}else{
@ <p class="noMoreShun">Artifact %s(zUuid) will no longer
|
| ︙ | ︙ | |||
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
login_insert_csrf_secret();
@ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
@ <input type="submit" name="add" value="Shun" />
@ </div></form>
@ </blockquote>
@
@ <p>Enter the UUID of a previous shunned artifact to cause it to be
@ accepted again in the repository. The artifact content is not
@ restored because the content is unknown. The only change is that
@ the formerly shunned artifact will be accepted on subsequent sync
@ operations.</p>
@
@ <blockquote>
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
login_insert_csrf_secret();
| > | | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
login_insert_csrf_secret();
@ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
@ <input type="submit" name="add" value="Shun" />
@ </div></form>
@ </blockquote>
@
@ <a name="delshun"></a>
@ <p>Enter the UUID of a previous shunned artifact to cause it to be
@ accepted again in the repository. The artifact content is not
@ restored because the content is unknown. The only change is that
@ the formerly shunned artifact will be accepted on subsequent sync
@ operations.</p>
@
@ <blockquote>
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
login_insert_csrf_secret();
@ <input type="text" name="uuid" value="%h(PD("accept", ""))" size="50" />
@ <input type="submit" name="sub" value="Accept" />
@ </div></form>
@ </blockquote>
@
@ <p>Press the Rebuild button below to rebuild the repository. The
@ content of newly shunned artifacts is not purged until the repository
@ is rebuilt. On larger repositories, the rebuild may take minute or
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
| ︙ | ︙ | |||
397 398 399 400 401 402 403 | ** SQLITE_MEMDEBUG // Debugging version of system malloc() ** ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the ** assert() macro is enabled, each call into the Win32 native heap subsystem ** will cause HeapValidate to be called. If heap validation should fail, an ** assertion will be triggered. ** | < < < | 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | ** SQLITE_MEMDEBUG // Debugging version of system malloc() ** ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the ** assert() macro is enabled, each call into the Win32 native heap subsystem ** will cause HeapValidate to be called. If heap validation should fail, an ** assertion will be triggered. ** ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as ** the default. */ #if defined(SQLITE_SYSTEM_MALLOC) \ + defined(SQLITE_WIN32_MALLOC) \ + defined(SQLITE_ZERO_MALLOC) \ + defined(SQLITE_MEMDEBUG)>1 |
| ︙ | ︙ | |||
437 438 439 440 441 442 443 | ** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit ** it. */ #if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) # define _XOPEN_SOURCE 600 #endif | < < < < < < < | | | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 | ** But _XOPEN_SOURCE define causes problems for Mac OS X, so omit ** it. */ #if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__) # define _XOPEN_SOURCE 600 #endif /* ** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that ** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true, ** make it true by defining or undefining NDEBUG. ** ** Setting NDEBUG makes the code smaller and faster by disabling the ** assert() statements in the code. So we want the default action ** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG ** is set. Thus NDEBUG becomes an opt-in rather than an opt-out ** feature. */ #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif |
| ︙ | ︙ | |||
520 521 522 523 524 525 526 | ** of SQLite to unexpected behavior - to make the code "self-healing" ** or "ductile" rather than being "brittle" and crashing at the first ** hint of unplanned behavior. ** ** In other words, ALWAYS and NEVER are added for defensive code. ** ** When doing coverage testing ALWAYS and NEVER are hard-coded to | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 | ** of SQLite to unexpected behavior - to make the code "self-healing" ** or "ductile" rather than being "brittle" and crashing at the first ** hint of unplanned behavior. ** ** In other words, ALWAYS and NEVER are added for defensive code. ** ** When doing coverage testing ALWAYS and NEVER are hard-coded to ** be true and false so that the unreachable code they specify will ** not be counted as untested code. */ #if defined(SQLITE_COVERAGE_TEST) # define ALWAYS(X) (1) # define NEVER(X) (0) #elif !defined(NDEBUG) # define ALWAYS(X) ((X)?1:(assert(0),0)) |
| ︙ | ︙ | |||
544 545 546 547 548 549 550 | ** macros to verify that we have tested SQLite for large-file support. */ #define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds | | | > < < < < | | < | 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 | ** macros to verify that we have tested SQLite for large-file support. */ #define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0) /* ** The macro unlikely() is a hint that surrounds a boolean ** expression that is usually false. Macro likely() surrounds ** a boolean expression that is usually true. These hints could, ** in theory, be used by the compiler to generate better code, but ** currently they are just comments for human readers. */ #define likely(X) (X) #define unlikely(X) (X) /************** Include sqlite3.h in the middle of sqliteInt.h ***************/ /************** Begin file sqlite3.h *****************************************/ /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of |
| ︙ | ︙ | |||
668 669 670 671 672 673 674 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.0" #define SQLITE_VERSION_NUMBER 3008000 | | | 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.0" #define SQLITE_VERSION_NUMBER 3008000 #define SQLITE_SOURCE_ID "2013-08-05 12:31:41 4b8b426f10f8ae13bf553f7adf5ae09383fa0bd4" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) | > | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| ︙ | ︙ | |||
3120 3121 3122 3123 3124 3125 3126 | ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** ** ^The parameter P is passed through as the only parameter to the ** callback function X. ^The parameter N is the approximate number of ** [virtual machine instructions] that are evaluated between successive | | > | 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 | ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** ** ^The parameter P is passed through as the only parameter to the ** callback function X. ^The parameter N is the approximate number of ** [virtual machine instructions] that are evaluated between successive ** invocations of the callback X. ^If N is less than one then the progress ** handler is disabled. ** ** ^Only a single progress handler may be defined at one time per ** [database connection]; setting a new progress handler cancels the ** old one. ^Setting parameter X to NULL disables the progress handler. ** ^The progress handler is also disabled by setting N to a value less ** than 1. ** |
| ︙ | ︙ | |||
4740 4741 4742 4743 4744 4745 4746 | ** registered the application defined function. */ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data ** | | | | | | > | | < | < | | | | > | | > | | | | > | < < < | | | | | | 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 | ** registered the application defined function. */ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data ** ** These functions may be used by (non-aggregate) SQL functions to ** associate metadata with argument values. If the same value is passed to ** multiple invocations of the same SQL function during query execution, under ** some circumstances the associated metadata may be preserved. An example ** of where this might be useful is in a regular-expression matching ** function. The compiled version of the regular expression can be stored as ** metadata associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata ** associated by the sqlite3_set_auxdata() function with the Nth argument ** value to the application-defined function. ^If there is no metadata ** associated with the function argument, this sqlite3_get_auxdata() interface ** returns a NULL pointer. ** ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th ** argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent ** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or ** NULL if the metadata has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly ** once, when the metadata is discarded. ** SQLite is free to discard the metadata at any time, including: <ul> ** <li> when the corresponding function parameter changes, or ** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement, or ** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or ** <li> during the original sqlite3_set_auxdata() call when a memory ** allocation error occurs. </ul>)^ ** ** Note the last bullet in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after ** sqlite3_set_auxdata() has been called. ** ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** ** These routines must be called from the same thread in which ** the SQL function is running. |
| ︙ | ︙ | |||
6827 6828 6829 6830 6831 6832 6833 | ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> | | | | | 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 | ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been ** resolved.)^ ^The highwater mark is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 |
| ︙ | ︙ | |||
8822 8823 8824 8825 8826 8827 8828 | */ typedef struct Vdbe Vdbe; /* ** The names of the following types declared in vdbeInt.h are required ** for the VdbeOp definition. */ | < | 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 | */ typedef struct Vdbe Vdbe; /* ** The names of the following types declared in vdbeInt.h are required ** for the VdbeOp definition. */ typedef struct Mem Mem; typedef struct SubProgram SubProgram; /* ** A single instruction of the virtual machine has an opcode ** and as many as three operands. The instruction is recorded ** as an instance of the following structure: |
| ︙ | ︙ | |||
8846 8847 8848 8849 8850 8851 8852 |
union { /* fourth parameter */
int i; /* Integer value if p4type==P4_INT32 */
void *p; /* Generic pointer */
char *z; /* Pointer to data for string (char array) types */
i64 *pI64; /* Used when p4type is P4_INT64 */
double *pReal; /* Used when p4type is P4_REAL */
FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
| < | 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 |
union { /* fourth parameter */
int i; /* Integer value if p4type==P4_INT32 */
void *p; /* Generic pointer */
char *z; /* Pointer to data for string (char array) types */
i64 *pI64; /* Used when p4type is P4_INT64 */
double *pReal; /* Used when p4type is P4_REAL */
FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
Mem *pMem; /* Used when p4type is P4_MEM */
VTable *pVtab; /* Used when p4type is P4_VTAB */
KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
int *ai; /* Used when p4type is P4_INTARRAY */
SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */
int (*xAdvance)(BtCursor *, int *);
|
| ︙ | ︙ | |||
8900 8901 8902 8903 8904 8905 8906 | */ #define P4_NOTUSED 0 /* The P4 parameter is not used */ #define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P4_STATIC (-2) /* Pointer to a static string */ #define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */ #define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */ #define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ | < | 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 | */ #define P4_NOTUSED 0 /* The P4 parameter is not used */ #define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P4_STATIC (-2) /* Pointer to a static string */ #define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */ #define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */ #define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ #define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */ #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ #define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */ #define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */ #define P4_REAL (-12) /* P4 is a 64-bit floating point value */ #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ #define P4_INT32 (-14) /* P4 is a 32-bit signed integer */ |
| ︙ | ︙ | |||
9188 9189 9190 9191 9192 9193 9194 | SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); | | | 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 | SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); |
| ︙ | ︙ | |||
10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 | tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ int tnum; /* DB Page containing root of this index */ u16 nColumn; /* Number of columns in table used by this index */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ #ifdef SQLITE_ENABLE_STAT3 | > | 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 | tRowcnt *aiRowEst; /* From ANALYZE: Est. rows selected by each column */ Table *pTable; /* The SQL table being indexed */ char *zColAff; /* String defining the affinity of each column */ Index *pNext; /* The next index associated with the same table */ Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* for each column: True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ Expr *pPartIdxWhere; /* WHERE clause for partial indices */ int tnum; /* DB Page containing root of this index */ u16 nColumn; /* Number of columns in table used by this index */ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ unsigned bUnordered:1; /* Use this index for == or IN queries only */ unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ #ifdef SQLITE_ENABLE_STAT3 |
| ︙ | ︙ | |||
11240 11241 11242 11243 11244 11245 11246 11247 11248 11249 11250 11251 11252 11253 |
*/
#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
#define NC_AsMaybe 0x10 /* Resolve to AS terms of the result set only
** if no other resolution is available */
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
| > | 11225 11226 11227 11228 11229 11230 11231 11232 11233 11234 11235 11236 11237 11238 11239 |
*/
#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
#define NC_AsMaybe 0x10 /* Resolve to AS terms of the result set only
** if no other resolution is available */
#define NC_PartIdx 0x20 /* True if resolving a partial index WHERE */
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
|
| ︙ | ︙ | |||
11424 11425 11426 11427 11428 11429 11430 11431 11432 11433 11434 11435 11436 11437 |
int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
int nSet; /* Number of sets used so far */
int nOnce; /* Number of OP_Once instructions so far */
int ckBase; /* Base register of data during check constraints */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
struct yColCache {
int iTable; /* Table cursor number */
int iColumn; /* Table column number */
u8 tempReg; /* iReg is a temp register that needs to be freed */
int iLevel; /* Nesting level */
| > | 11410 11411 11412 11413 11414 11415 11416 11417 11418 11419 11420 11421 11422 11423 11424 |
int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
int nSet; /* Number of sets used so far */
int nOnce; /* Number of OP_Once instructions so far */
int ckBase; /* Base register of data during check constraints */
int iPartIdxTab; /* Table corresponding to a partial index */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
struct yColCache {
int iTable; /* Table cursor number */
int iColumn; /* Table column number */
u8 tempReg; /* iReg is a temp register that needs to be freed */
int iLevel; /* Nesting level */
|
| ︙ | ︙ | |||
12005 12006 12007 12008 12009 12010 12011 | SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, | | | 11992 11993 11994 11995 11996 11997 11998 11999 12000 12001 12002 12003 12004 12005 12006 |
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *);
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
Expr*, int, int);
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
Expr*,ExprList*,u16,Expr*,Expr*);
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
|
| ︙ | ︙ | |||
12053 12054 12055 12056 12057 12058 12059 | SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *); SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3Vacuum(Parse*); SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*); SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); | | | > | 12040 12041 12042 12043 12044 12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 | SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,int isView,struct SrcList_item *); SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3Vacuum(Parse*); SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*); SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int); SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); SQLITE_PRIVATE void sqlite3PrngSaveState(void); SQLITE_PRIVATE void sqlite3PrngRestoreState(void); SQLITE_PRIVATE void sqlite3PrngResetState(void); |
| ︙ | ︙ | |||
12081 12082 12083 12084 12085 12086 12087 | SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int); SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*); | | | 12069 12070 12071 12072 12073 12074 12075 12076 12077 12078 12079 12080 12081 12082 12083 |
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
int*,int,int,int,int,int*);
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
|
| ︙ | ︙ | |||
12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 12294 12295 12296 12297 | SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*); SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int); SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); SQLITE_PRIVATE char sqlite3AffinityType(const char*); SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); | > | 12272 12273 12274 12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 | SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*); SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int); SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*); SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); SQLITE_PRIVATE char sqlite3AffinityType(const char*); SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); |
| ︙ | ︙ | |||
13255 13256 13257 13258 13259 13260 13261 13262 13263 13264 13265 13266 13267 13268 | /* Opaque type used by code in vdbesort.c */ typedef struct VdbeSorter VdbeSorter; /* Opaque type used by the explainer */ typedef struct Explain Explain; /* ** A cursor is a pointer into a single BTree within a database file. ** The cursor can seek to a BTree entry with a particular key, or ** loop over all entries of the Btree. You can also insert new BTree ** entries or retrieve the key or data from the entry that the cursor ** is currently pointing to. ** | > > > | 13244 13245 13246 13247 13248 13249 13250 13251 13252 13253 13254 13255 13256 13257 13258 13259 13260 | /* Opaque type used by code in vdbesort.c */ typedef struct VdbeSorter VdbeSorter; /* Opaque type used by the explainer */ typedef struct Explain Explain; /* Elements of the linked list at Vdbe.pAuxData */ typedef struct AuxData AuxData; /* ** A cursor is a pointer into a single BTree within a database file. ** The cursor can seek to a BTree entry with a particular key, or ** loop over all entries of the Btree. You can also insert new BTree ** entries or retrieve the key or data from the entry that the cursor ** is currently pointing to. ** |
| ︙ | ︙ | |||
13441 13442 13443 13444 13445 13446 13447 | ** Return true if a memory cell is not marked as invalid. This macro ** is for use inside assert() statements only. */ #ifdef SQLITE_DEBUG #define memIsValid(M) ((M)->flags & MEM_Invalid)==0 #endif | | | < < | | < < > | < < < | > > | | | < > > | 13433 13434 13435 13436 13437 13438 13439 13440 13441 13442 13443 13444 13445 13446 13447 13448 13449 13450 13451 13452 13453 13454 13455 13456 13457 13458 13459 13460 13461 13462 13463 13464 13465 13466 13467 13468 13469 13470 13471 13472 13473 13474 13475 13476 13477 13478 13479 13480 13481 13482 13483 |
** Return true if a memory cell is not marked as invalid. This macro
** is for use inside assert() statements only.
*/
#ifdef SQLITE_DEBUG
#define memIsValid(M) ((M)->flags & MEM_Invalid)==0
#endif
/*
** Each auxilliary data pointer stored by a user defined function
** implementation calling sqlite3_set_auxdata() is stored in an instance
** of this structure. All such structures associated with a single VM
** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
** when the VM is halted (if not before).
*/
struct AuxData {
int iOp; /* Instruction number of OP_Function opcode */
int iArg; /* Index of function argument. */
void *pAux; /* Aux data pointer */
void (*xDelete)(void *); /* Destructor for the aux data */
AuxData *pNext; /* Next element in list */
};
/*
** The "context" argument for a installable function. A pointer to an
** instance of this structure is the first argument to the routines used
** implement the SQL functions.
**
** There is a typedef for this structure in sqlite.h. So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbeInt.h because it uses substructures
** (Mem) which are only defined there.
*/
struct sqlite3_context {
FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
Mem s; /* The return value is stored here */
Mem *pMem; /* Memory cell used to store aggregate context */
CollSeq *pColl; /* Collating sequence */
int isError; /* Error code returned by the function. */
int skipFlag; /* Skip skip accumulator loading if true */
int iOp; /* Instruction number of OP_Function */
Vdbe *pVdbe; /* The VM that owns this context */
};
/*
** An Explain object accumulates indented output which is helpful
** in describing recursive data structures.
*/
struct Explain {
|
| ︙ | ︙ | |||
13579 13580 13581 13582 13583 13584 13585 13586 13587 13588 13589 13590 13591 13592 | VdbeFrame *pFrame; /* Parent frame */ VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ int nFrame; /* Number of frames in pFrame list */ u32 expmask; /* Binding to these vars invalidates VM */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ int nOnceFlag; /* Size of array aOnceFlag[] */ u8 *aOnceFlag; /* Flags for OP_Once */ }; /* ** The following are allowed values for Vdbe.magic */ #define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */ #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ | > | 13568 13569 13570 13571 13572 13573 13574 13575 13576 13577 13578 13579 13580 13581 13582 | VdbeFrame *pFrame; /* Parent frame */ VdbeFrame *pDelFrame; /* List of frame objects to free on VM reset */ int nFrame; /* Number of frames in pFrame list */ u32 expmask; /* Binding to these vars invalidates VM */ SubProgram *pProgram; /* Linked list of all sub-programs used by VM */ int nOnceFlag; /* Size of array aOnceFlag[] */ u8 *aOnceFlag; /* Flags for OP_Once */ AuxData *pAuxData; /* Linked list of auxdata allocations */ }; /* ** The following are allowed values for Vdbe.magic */ #define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */ #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ |
| ︙ | ︙ | |||
13602 13603 13604 13605 13606 13607 13608 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); #endif SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); | | | 13592 13593 13594 13595 13596 13597 13598 13599 13600 13601 13602 13603 13604 13605 13606 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*); #endif SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int); SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); |
| ︙ | ︙ | |||
30497 30498 30499 30500 30501 30502 30503 30504 30505 30506 30507 30508 30509 30510 | ** ** This file contains code that is specific to Windows. */ #if SQLITE_OS_WIN /* This file is used for Windows only */ #ifdef __CYGWIN__ # include <sys/cygwin.h> #endif /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of os_win.c ****************/ /************** Begin file os_common.h ***************************************/ | > | 30487 30488 30489 30490 30491 30492 30493 30494 30495 30496 30497 30498 30499 30500 30501 | ** ** This file contains code that is specific to Windows. */ #if SQLITE_OS_WIN /* This file is used for Windows only */ #ifdef __CYGWIN__ # include <sys/cygwin.h> /* # include <errno.h> */ #endif /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of os_win.c ****************/ /************** Begin file os_common.h ***************************************/ |
| ︙ | ︙ | |||
30917 30918 30919 30920 30921 30922 30923 30924 30925 30926 30927 30928 30929 30930 |
/*
* The extra flags to use in calls to the Win32 heap APIs. This value may be
* zero for the default behavior.
*/
#ifndef SQLITE_WIN32_HEAP_FLAGS
# define SQLITE_WIN32_HEAP_FLAGS (0)
#endif
/*
** The winMemData structure stores information required by the Win32-specific
** sqlite3_mem_methods implementation.
*/
typedef struct winMemData winMemData;
struct winMemData {
| > | 30908 30909 30910 30911 30912 30913 30914 30915 30916 30917 30918 30919 30920 30921 30922 |
/*
* The extra flags to use in calls to the Win32 heap APIs. This value may be
* zero for the default behavior.
*/
#ifndef SQLITE_WIN32_HEAP_FLAGS
# define SQLITE_WIN32_HEAP_FLAGS (0)
#endif
/*
** The winMemData structure stores information required by the Win32-specific
** sqlite3_mem_methods implementation.
*/
typedef struct winMemData winMemData;
struct winMemData {
|
| ︙ | ︙ | |||
34382 34383 34384 34385 34386 34387 34388 34389 |
"winMapfile", pFd->zPath);
/* Log the error, but continue normal operation using xRead/xWrite */
OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
osGetCurrentProcessId(), pFd));
return SQLITE_OK;
}
assert( (nMap % winSysInfo.dwPageSize)==0 );
#if SQLITE_OS_WINRT
| > | < | 34374 34375 34376 34377 34378 34379 34380 34381 34382 34383 34384 34385 34386 34387 34388 34389 34390 34391 |
"winMapfile", pFd->zPath);
/* Log the error, but continue normal operation using xRead/xWrite */
OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
osGetCurrentProcessId(), pFd));
return SQLITE_OK;
}
assert( (nMap % winSysInfo.dwPageSize)==0 );
assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
#if SQLITE_OS_WINRT
pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
#else
pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
#endif
if( pNew==NULL ){
osCloseHandle(pFd->hMap);
pFd->hMap = NULL;
pFd->lastErrno = osGetLastError();
winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
|
| ︙ | ︙ | |||
34554 34555 34556 34557 34558 34559 34560 34561 34562 34563 34564 34565 34566 34567 34568 34569 34570 34571 |
zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
}
#endif
/* caller will handle out of memory */
return zConverted;
}
/*
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at pVfs->mxPathname characters.
*/
static int getTempname(int nBuf, char *zBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
int nTempPath;
| > > > > > > > > > | < < > | | > > > | | | > > > | > > > > > > > > | > > > > > > > > | | 34546 34547 34548 34549 34550 34551 34552 34553 34554 34555 34556 34557 34558 34559 34560 34561 34562 34563 34564 34565 34566 34567 34568 34569 34570 34571 34572 34573 34574 34575 34576 34577 34578 34579 34580 34581 34582 34583 34584 34585 34586 34587 34588 34589 34590 34591 34592 34593 34594 34595 34596 34597 34598 34599 34600 34601 34602 34603 34604 34605 34606 34607 34608 34609 34610 34611 34612 34613 34614 34615 34616 34617 34618 34619 34620 34621 34622 34623 34624 34625 34626 34627 34628 34629 34630 34631 34632 34633 34634 34635 34636 34637 34638 34639 34640 34641 34642 34643 |
zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
}
#endif
/* caller will handle out of memory */
return zConverted;
}
/*
** Maximum pathname length (in bytes) for windows. The MAX_PATH macro is
** in characters, so we allocate 3 bytes per character assuming worst-case
** 3-bytes-per-character UTF8.
*/
#ifndef SQLITE_WIN32_MAX_PATH
# define SQLITE_WIN32_MAX_PATH (MAX_PATH*3)
#endif
/*
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at pVfs->mxPathname characters.
*/
static int getTempname(int nBuf, char *zBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
int nTempPath;
char zTempPath[SQLITE_WIN32_MAX_PATH+2];
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing.
*/
SimulateIOError( return SQLITE_IOERR );
if( sqlite3_temp_directory ){
sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s",
sqlite3_temp_directory);
}
#if !SQLITE_OS_WINRT
else if( isNT() ){
char *zMulti;
WCHAR zWidePath[MAX_PATH];
if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
return SQLITE_IOERR_GETTEMPPATH;
}
zMulti = unicodeToUtf8(zWidePath);
if( zMulti ){
sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti);
sqlite3_free(zMulti);
}else{
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM;
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zUtf8;
char zMbcsPath[SQLITE_WIN32_MAX_PATH];
if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
return SQLITE_IOERR_GETTEMPPATH;
}
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
if( zUtf8 ){
sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8);
sqlite3_free(zUtf8);
}else{
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM;
}
}
#else
else{
/*
** Compiled without ANSI support and the current operating system
** is not Windows NT; therefore, just zero the temporary buffer.
*/
memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
}
#endif /* SQLITE_WIN32_HAS_ANSI */
#else
else{
/*
** Compiled for WinRT and the sqlite3_temp_directory is not set;
** therefore, just zero the temporary buffer.
*/
memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
}
#endif /* !SQLITE_OS_WINRT */
/* Check that the output buffer is large enough for the temporary file
** name. If it is not, return SQLITE_ERROR.
*/
nTempPath = sqlite3Strlen30(zTempPath);
if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
|
| ︙ | ︙ | |||
34693 34694 34695 34696 34697 34698 34699 | void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ int cnt = 0; /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ | | | 34715 34716 34717 34718 34719 34720 34721 34722 34723 34724 34725 34726 34727 34728 34729 | void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ int cnt = 0; /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */ int rc = SQLITE_OK; /* Function Return Code */ #if !defined(NDEBUG) || SQLITE_OS_WINCE int eType = flags&0xFFFFFF00; /* Type of file to open */ #endif int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); |
| ︙ | ︙ | |||
34759 34760 34761 34762 34763 34764 34765 |
#endif
/* If the second argument to this function is NULL, generate a
** temporary file name to use
*/
if( !zUtf8Name ){
assert(isDelete && !isOpenJournal);
| < | | 34781 34782 34783 34784 34785 34786 34787 34788 34789 34790 34791 34792 34793 34794 34795 |
#endif
/* If the second argument to this function is NULL, generate a
** temporary file name to use
*/
if( !zUtf8Name ){
assert(isDelete && !isOpenJournal);
rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname);
if( rc!=SQLITE_OK ){
OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
return rc;
}
zUtf8Name = zTmpname;
}
|
| ︙ | ︙ | |||
35191 35192 35193 35194 35195 35196 35197 |
int nFull, /* Size of output buffer in bytes */
char *zFull /* Output buffer */
){
#if defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
UNUSED_PARAMETER(nFull);
| | | < | | > > > > | > > > > | 35212 35213 35214 35215 35216 35217 35218 35219 35220 35221 35222 35223 35224 35225 35226 35227 35228 35229 35230 35231 35232 35233 35234 35235 35236 35237 35238 35239 35240 35241 35242 35243 35244 35245 35246 35247 35248 35249 |
int nFull, /* Size of output buffer in bytes */
char *zFull /* Output buffer */
){
#if defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
UNUSED_PARAMETER(nFull);
assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH );
assert( nFull>=pVfs->mxPathname );
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a slash.
*/
char zOut[SQLITE_WIN32_MAX_PATH+1];
if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
SQLITE_WIN32_MAX_PATH+1)<0 ){
winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
zRelative);
return SQLITE_CANTOPEN_FULLPATH;
}
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
sqlite3_data_directory, zOut);
}else{
if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
zRelative);
return SQLITE_CANTOPEN_FULLPATH;
}
}
return SQLITE_OK;
#endif
#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
/* WinCE has no concept of a relative pathname, or so I am told. */
|
| ︙ | ︙ | |||
35549 35550 35551 35552 35553 35554 35555 |
/*
** Initialize and deinitialize the operating system interface.
*/
SQLITE_API int sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
3, /* iVersion */
sizeof(winFile), /* szOsFile */
| | | 35577 35578 35579 35580 35581 35582 35583 35584 35585 35586 35587 35588 35589 35590 35591 |
/*
** Initialize and deinitialize the operating system interface.
*/
SQLITE_API int sqlite3_os_init(void){
static sqlite3_vfs winVfs = {
3, /* iVersion */
sizeof(winFile), /* szOsFile */
SQLITE_WIN32_MAX_PATH, /* mxPathname */
0, /* pNext */
"win32", /* zName */
0, /* pAppData */
winOpen, /* xOpen */
winDelete, /* xDelete */
winAccess, /* xAccess */
winFullPathname, /* xFullPathname */
|
| ︙ | ︙ | |||
60174 60175 60176 60177 60178 60179 60180 |
** Resolve label "x" to be the address of the next instruction to
** be inserted. The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
int j = -1-x;
assert( p->magic==VDBE_MAGIC_INIT );
| | | | 60202 60203 60204 60205 60206 60207 60208 60209 60210 60211 60212 60213 60214 60215 60216 60217 |
** Resolve label "x" to be the address of the next instruction to
** be inserted. The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
int j = -1-x;
assert( p->magic==VDBE_MAGIC_INIT );
assert( j<p->nLabel );
if( j>=0 && p->aLabel ){
p->aLabel[j] = p->nOp;
}
}
/*
** Mark the VDBE as one that can only be run one time.
*/
|
| ︙ | ︙ | |||
60499 60500 60501 60502 60503 60504 60505 |
}
/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
| < | | 60527 60528 60529 60530 60531 60532 60533 60534 60535 60536 60537 60538 60539 60540 60541 |
}
/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
}
/*
** If the input FuncDef structure is ephemeral, then free it. If
** the FuncDef is not ephermal, then do nothing.
*/
|
| ︙ | ︙ | |||
60536 60537 60538 60539 60540 60541 60542 |
sqlite3DbFree(db, p4);
break;
}
case P4_MPRINTF: {
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break;
}
| < < < < < < < | 60563 60564 60565 60566 60567 60568 60569 60570 60571 60572 60573 60574 60575 60576 |
sqlite3DbFree(db, p4);
break;
}
case P4_MPRINTF: {
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
break;
}
case P4_FUNCDEF: {
freeEphemeralFunction(db, (FuncDef*)p4);
break;
}
case P4_MEM: {
if( db->pnBytesFreed==0 ){
sqlite3ValueFree((sqlite3_value*)p4);
|
| ︙ | ︙ | |||
61572 61573 61574 61575 61576 61577 61578 61579 61580 61581 61582 61583 61584 61585 |
releaseMemArray(&p->aMem[1], p->nMem);
}
while( p->pDelFrame ){
VdbeFrame *pDel = p->pDelFrame;
p->pDelFrame = pDel->pParent;
sqlite3VdbeFrameDelete(pDel);
}
}
/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open. It also deletes the values of
| > > > > | 61592 61593 61594 61595 61596 61597 61598 61599 61600 61601 61602 61603 61604 61605 61606 61607 61608 61609 |
releaseMemArray(&p->aMem[1], p->nMem);
}
while( p->pDelFrame ){
VdbeFrame *pDel = p->pDelFrame;
p->pDelFrame = pDel->pParent;
sqlite3VdbeFrameDelete(pDel);
}
/* Delete any auxdata allocations made by the VM */
sqlite3VdbeDeleteAuxData(p, -1, 0);
assert( p->pAuxData==0 );
}
/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open. It also deletes the values of
|
| ︙ | ︙ | |||
62370 62371 62372 62373 62374 62375 62376 |
assert( (rc & p->db->errMask)==rc );
}
sqlite3VdbeDelete(p);
return rc;
}
/*
| | > > > > > > > > > > > | < < > | < | > | | > > | > > > | 62394 62395 62396 62397 62398 62399 62400 62401 62402 62403 62404 62405 62406 62407 62408 62409 62410 62411 62412 62413 62414 62415 62416 62417 62418 62419 62420 62421 62422 62423 62424 62425 62426 62427 62428 62429 62430 62431 62432 62433 62434 62435 62436 |
assert( (rc & p->db->errMask)==rc );
}
sqlite3VdbeDelete(p);
return rc;
}
/*
** If parameter iOp is less than zero, then invoke the destructor for
** all auxiliary data pointers currently cached by the VM passed as
** the first argument.
**
** Or, if iOp is greater than or equal to zero, then the destructor is
** only invoked for those auxiliary data pointers created by the user
** function invoked by the OP_Function opcode at instruction iOp of
** VM pVdbe, and only then if:
**
** * the associated function parameter is the 32nd or later (counting
** from left to right), or
**
** * the corresponding bit in argument mask is clear (where the first
** function parameter corrsponds to bit 0 etc.).
*/
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
AuxData **pp = &pVdbe->pAuxData;
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
|| (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
){
if( pAux->xDelete ){
pAux->xDelete(pAux->pAux);
}
*pp = pAux->pNext;
sqlite3DbFree(pVdbe->db, pAux);
}else{
pp= &pAux->pNext;
}
}
}
/*
** Free all memory associated with the Vdbe passed as the second argument,
** except for object itself, which is preserved.
|
| ︙ | ︙ | |||
62902 62903 62904 62905 62906 62907 62908 |
** equal, then the keys are considered to be equal and
** the parts beyond the common prefix are ignored.
*/
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
| | | 62941 62942 62943 62944 62945 62946 62947 62948 62949 62950 62951 62952 62953 62954 62955 |
** equal, then the keys are considered to be equal and
** the parts beyond the common prefix are ignored.
*/
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
int nKey1, const void *pKey1, /* Left key */
UnpackedRecord *pPKey2 /* Right key */
){
u32 d1; /* Offset into aKey[] of next data element */
u32 idx1; /* Offset into aKey[] of next header element */
u32 szHdr1; /* Number of bytes in header */
int i = 0;
int nField;
int rc = 0;
const unsigned char *aKey1 = (const unsigned char *)pKey1;
KeyInfo *pKeyInfo;
|
| ︙ | ︙ | |||
62936 62937 62938 62939 62940 62941 62942 |
nField = pKeyInfo->nField;
assert( pKeyInfo->aSortOrder!=0 );
while( idx1<szHdr1 && i<pPKey2->nField ){
u32 serial_type1;
/* Read the serial types for the next element in each key. */
idx1 += getVarint32( aKey1+idx1, serial_type1 );
| | | 62975 62976 62977 62978 62979 62980 62981 62982 62983 62984 62985 62986 62987 62988 62989 |
nField = pKeyInfo->nField;
assert( pKeyInfo->aSortOrder!=0 );
while( idx1<szHdr1 && i<pPKey2->nField ){
u32 serial_type1;
/* Read the serial types for the next element in each key. */
idx1 += getVarint32( aKey1+idx1, serial_type1 );
if( d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 ) break;
/* Extract the values to be compared.
*/
d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
/* Do the comparison
*/
|
| ︙ | ︙ | |||
63165 63166 63167 63168 63169 63170 63171 | ** Return a pointer to an sqlite3_value structure containing the value bound ** parameter iVar of VM v. Except, if the value is an SQL NULL, return ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_* ** constants) to the value before returning it. ** ** The returned value must be freed by the caller using sqlite3ValueFree(). */ | | | 63204 63205 63206 63207 63208 63209 63210 63211 63212 63213 63214 63215 63216 63217 63218 |
** Return a pointer to an sqlite3_value structure containing the value bound
** parameter iVar of VM v. Except, if the value is an SQL NULL, return
** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
** constants) to the value before returning it.
**
** The returned value must be freed by the caller using sqlite3ValueFree().
*/
SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
assert( iVar>0 );
if( v ){
Mem *pMem = &v->aVar[iVar-1];
if( 0==(pMem->flags & MEM_Null) ){
sqlite3_value *pRet = sqlite3ValueNew(v->db);
if( pRet ){
sqlite3VdbeMemCopy((Mem *)pRet, pMem);
|
| ︙ | ︙ | |||
63782 63783 63784 63785 63786 63787 63788 |
}
/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
| | | | < | > | | < < < < < < < | | < < | | | > > > > > | | > | 63821 63822 63823 63824 63825 63826 63827 63828 63829 63830 63831 63832 63833 63834 63835 63836 63837 63838 63839 63840 63841 63842 63843 63844 63845 63846 63847 63848 63849 63850 63851 63852 63853 63854 63855 63856 63857 63858 63859 63860 63861 63862 63863 63864 63865 63866 63867 63868 63869 63870 63871 63872 63873 63874 63875 |
}
/*
** Return the auxilary data pointer, if any, for the iArg'th argument to
** the user-function defined by pCtx.
*/
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
AuxData *pAuxData;
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
return (pAuxData ? pAuxData->pAux : 0);
}
/*
** Set the auxilary data pointer and delete function, for the iArg'th
** argument to the user-function defined by pCtx. Any previous value is
** deleted by calling the delete function specified when it was set.
*/
SQLITE_API void sqlite3_set_auxdata(
sqlite3_context *pCtx,
int iArg,
void *pAux,
void (*xDelete)(void*)
){
AuxData *pAuxData;
Vdbe *pVdbe = pCtx->pVdbe;
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
if( iArg<0 ) goto failed;
for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
}
if( pAuxData==0 ){
pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
if( !pAuxData ) goto failed;
pAuxData->iOp = pCtx->iOp;
pAuxData->iArg = iArg;
pAuxData->pNext = pVdbe->pAuxData;
pVdbe->pAuxData = pAuxData;
}else if( pAuxData->xDelete ){
pAuxData->xDelete(pAuxData->pAux);
}
pAuxData->pAux = pAux;
pAuxData->xDelete = xDelete;
return;
failed:
if( xDelete ){
xDelete(pAux);
|
| ︙ | ︙ | |||
65437 65438 65439 65440 65441 65442 65443 | int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | | | 65473 65474 65475 65476 65477 65478 65479 65480 65481 65482 65483 65484 65485 65486 65487 | int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ int iCompare = 0; /* Result of last OP_Compare operation */ unsigned nVmStep = 0; /* Number of virtual machine steps */ #ifndef SQLITE_OMIT_PROGRESS_CALLBACK unsigned nProgressLimit; /* Invoke xProgress() when nVmStep reaches this */ #endif Mem *aMem = p->aMem; /* Copy of p->aMem */ Mem *pIn1 = 0; /* 1st input operand */ Mem *pIn2 = 0; /* 2nd input operand */ Mem *pIn3 = 0; /* 3rd input operand */ Mem *pOut = 0; /* Output operand */ int *aPermute = 0; /* Permutation of columns for OP_Compare */ |
| ︙ | ︙ | |||
65896 65897 65898 65899 65900 65901 65902 65903 65904 65905 65906 65907 65908 65909 |
assert( p->bIsReader || p->readOnly!=0 );
p->rc = SQLITE_OK;
assert( p->explain==0 );
p->pResultSet = 0;
db->busyHandler.nBusy = 0;
CHECK_FOR_INTERRUPT;
sqlite3VdbeIOTraceSql(p);
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
int i;
printf("VDBE Program Listing:\n");
sqlite3VdbePrintSql(p);
for(i=0; i<p->nOp; i++){
| > > > > > > > > > > > | 65932 65933 65934 65935 65936 65937 65938 65939 65940 65941 65942 65943 65944 65945 65946 65947 65948 65949 65950 65951 65952 65953 65954 65955 65956 |
assert( p->bIsReader || p->readOnly!=0 );
p->rc = SQLITE_OK;
assert( p->explain==0 );
p->pResultSet = 0;
db->busyHandler.nBusy = 0;
CHECK_FOR_INTERRUPT;
sqlite3VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( db->xProgress ){
assert( 0 < db->nProgressOps );
nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1];
if( nProgressLimit==0 ){
nProgressLimit = db->nProgressOps;
}else{
nProgressLimit %= (unsigned)db->nProgressOps;
}
}
#endif
#ifdef SQLITE_DEBUG
sqlite3BeginBenignMalloc();
if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
int i;
printf("VDBE Program Listing:\n");
sqlite3VdbePrintSql(p);
for(i=0; i<p->nOp; i++){
|
| ︙ | ︙ | |||
66056 66057 66058 66059 66060 66061 66062 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Call the progress callback if it is configured and the required number ** of VDBE ops have been executed (either since this invocation of ** sqlite3VdbeExec() or since last time the progress callback was called). ** If the progress callback returns non-zero, exit the virtual machine with ** a return code SQLITE_ABORT. */ | | | > > | 66103 66104 66105 66106 66107 66108 66109 66110 66111 66112 66113 66114 66115 66116 66117 66118 66119 66120 66121 66122 66123 66124 66125 66126 |
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/* Call the progress callback if it is configured and the required number
** of VDBE ops have been executed (either since this invocation of
** sqlite3VdbeExec() or since last time the progress callback was called).
** If the progress callback returns non-zero, exit the virtual machine with
** a return code SQLITE_ABORT.
*/
if( db->xProgress!=0 && nVmStep>=nProgressLimit ){
int prc;
prc = db->xProgress(db->pProgressArg);
if( prc!=0 ){
rc = SQLITE_INTERRUPT;
goto vdbe_error_halt;
}
if( db->xProgress!=0 ){
nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
}
}
#endif
break;
}
/* Opcode: Gosub P1 P2 * * *
|
| ︙ | ︙ | |||
66749 66750 66751 66752 66753 66754 66755 |
assert( memIsValid(u.ai.pArg) );
u.ai.apVal[u.ai.i] = u.ai.pArg;
Deephemeralize(u.ai.pArg);
sqlite3VdbeMemStoreType(u.ai.pArg);
REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
}
| | < | < < < < < < > > | 66798 66799 66800 66801 66802 66803 66804 66805 66806 66807 66808 66809 66810 66811 66812 66813 66814 66815 66816 66817 66818 66819 |
assert( memIsValid(u.ai.pArg) );
u.ai.apVal[u.ai.i] = u.ai.pArg;
Deephemeralize(u.ai.pArg);
sqlite3VdbeMemStoreType(u.ai.pArg);
REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
}
assert( pOp->p4type==P4_FUNCDEF );
u.ai.ctx.pFunc = pOp->p4.pFunc;
u.ai.ctx.s.flags = MEM_Null;
u.ai.ctx.s.db = db;
u.ai.ctx.s.xDel = 0;
u.ai.ctx.s.zMalloc = 0;
u.ai.ctx.iOp = pc;
u.ai.ctx.pVdbe = p;
/* The output cell may already have a buffer allocated. Move
** the pointer to u.ai.ctx.s so in case the user-function can use
** the already allocated buffer instead of allocating a new one.
*/
sqlite3VdbeMemMove(&u.ai.ctx.s, pOut);
MemSetTypeFlag(&u.ai.ctx.s, MEM_Null);
|
| ︙ | ︙ | |||
66784 66785 66786 66787 66788 66789 66790 | db->lastRowid = lastRowid; (*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */ lastRowid = db->lastRowid; /* If any auxiliary data functions have been called by this user function, ** immediately call the destructor for any non-static values. */ | < | < < < | 66828 66829 66830 66831 66832 66833 66834 66835 66836 66837 66838 66839 66840 66841 66842 |
db->lastRowid = lastRowid;
(*u.ai.ctx.pFunc->xFunc)(&u.ai.ctx, u.ai.n, u.ai.apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid;
/* If any auxiliary data functions have been called by this user function,
** immediately call the destructor for any non-static values.
*/
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
if( db->mallocFailed ){
/* Even though a malloc() has failed, the implementation of the
** user function may have called an sqlite3_result_XXX() function
** to return a value. The following call releases any resources
** associated with such a value.
*/
|
| ︙ | ︙ | |||
74155 74156 74157 74158 74159 74160 74161 |
ExprSetIrreducible(pExpr);
/* Translate the schema name in zDb into a pointer to the corresponding
** schema. If not found, pSchema will remain NULL and nothing will match
** resulting in an appropriate error message toward the end of this routine
*/
if( zDb ){
| > > > > > > > > | | | | | > | 74195 74196 74197 74198 74199 74200 74201 74202 74203 74204 74205 74206 74207 74208 74209 74210 74211 74212 74213 74214 74215 74216 74217 74218 74219 74220 74221 74222 |
ExprSetIrreducible(pExpr);
/* Translate the schema name in zDb into a pointer to the corresponding
** schema. If not found, pSchema will remain NULL and nothing will match
** resulting in an appropriate error message toward the end of this routine
*/
if( zDb ){
testcase( pNC->ncFlags & NC_PartIdx );
testcase( pNC->ncFlags & NC_IsCheck );
if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
/* Silently ignore database qualifiers inside CHECK constraints and partial
** indices. Do not raise errors because that might break legacy and
** because it does not hurt anything to just ignore the database name. */
zDb = 0;
}else{
for(i=0; i<db->nDb; i++){
assert( db->aDb[i].zName );
if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
pSchema = db->aDb[i].pSchema;
break;
}
}
}
}
/* Start at the inner-most context and move outward until a match is found */
while( pNC && cnt==0 ){
ExprList *pEList;
|
| ︙ | ︙ | |||
74436 74437 74438 74439 74440 74441 74442 74443 74444 74445 74446 74447 74448 74449 |
testcase( iCol==BMS-1 );
pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
}
ExprSetProperty(p, EP_Resolved);
}
return p;
}
/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree. Return 0 to continue the search down
** the tree or 2 to abort the tree walk.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 74485 74486 74487 74488 74489 74490 74491 74492 74493 74494 74495 74496 74497 74498 74499 74500 74501 74502 74503 74504 74505 74506 74507 74508 74509 74510 74511 74512 74513 74514 74515 74516 74517 74518 74519 74520 74521 74522 74523 74524 74525 74526 74527 74528 74529 74530 74531 |
testcase( iCol==BMS-1 );
pItem->colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
}
ExprSetProperty(p, EP_Resolved);
}
return p;
}
/*
** Report an error that an expression is not valid for a partial index WHERE
** clause.
*/
static void notValidPartIdxWhere(
Parse *pParse, /* Leave error message here */
NameContext *pNC, /* The name context */
const char *zMsg /* Type of error */
){
if( (pNC->ncFlags & NC_PartIdx)!=0 ){
sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
zMsg);
}
}
#ifndef SQLITE_OMIT_CHECK
/*
** Report an error that an expression is not valid for a CHECK constraint.
*/
static void notValidCheckConstraint(
Parse *pParse, /* Leave error message here */
NameContext *pNC, /* The name context */
const char *zMsg /* Type of error */
){
if( (pNC->ncFlags & NC_IsCheck)!=0 ){
sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg);
}
}
#else
# define notValidCheckConstraint(P,N,M)
#endif
/*
** This routine is callback for sqlite3WalkExpr().
**
** Resolve symbolic names into TK_COLUMN operators for the current
** node in the expression tree. Return 0 to continue the search down
** the tree or 2 to abort the tree walk.
|
| ︙ | ︙ | |||
74536 74537 74538 74539 74540 74541 74542 74543 74544 74545 74546 74547 74548 74549 |
int nId; /* Number of characters in function name */
const char *zId; /* The function name. */
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
testcase( pExpr->op==TK_CONST_FUNC );
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
if( pDef==0 ){
no_such_func = 1;
| > | 74618 74619 74620 74621 74622 74623 74624 74625 74626 74627 74628 74629 74630 74631 74632 |
int nId; /* Number of characters in function name */
const char *zId; /* The function name. */
FuncDef *pDef; /* Information about the function */
u8 enc = ENC(pParse->db); /* The database encoding */
testcase( pExpr->op==TK_CONST_FUNC );
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
notValidPartIdxWhere(pParse, pNC, "functions");
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
if( pDef==0 ){
no_such_func = 1;
|
| ︙ | ︙ | |||
74601 74602 74603 74604 74605 74606 74607 |
case TK_SELECT:
case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
#endif
case TK_IN: {
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
| < | | < < < | | < < | 74684 74685 74686 74687 74688 74689 74690 74691 74692 74693 74694 74695 74696 74697 74698 74699 74700 74701 74702 74703 74704 74705 74706 74707 74708 74709 74710 74711 74712 |
case TK_SELECT:
case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
#endif
case TK_IN: {
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
notValidCheckConstraint(pParse, pNC, "subqueries");
notValidPartIdxWhere(pParse, pNC, "subqueries");
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
}
}
break;
}
case TK_VARIABLE: {
notValidCheckConstraint(pParse, pNC, "parameters");
notValidPartIdxWhere(pParse, pNC, "parameters");
break;
}
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
}
/*
** pEList is a list of expressions which are really the result set of the
** a SELECT statement. pE is a term in an ORDER BY or GROUP BY clause.
|
| ︙ | ︙ | |||
74712 74713 74714 74715 74716 74717 74718 |
if( rc ) return 0;
/* Try to match the ORDER BY expression against an expression
** in the result set. Return an 1-based index of the matching
** result-set entry.
*/
for(i=0; i<pEList->nExpr; i++){
| | | 74789 74790 74791 74792 74793 74794 74795 74796 74797 74798 74799 74800 74801 74802 74803 |
if( rc ) return 0;
/* Try to match the ORDER BY expression against an expression
** in the result set. Return an 1-based index of the matching
** result-set entry.
*/
for(i=0; i<pEList->nExpr; i++){
if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
return i+1;
}
}
/* If no match, return 0. */
return 0;
}
|
| ︙ | ︙ | |||
74940 74941 74942 74943 74944 74945 74946 |
/* Otherwise, treat the ORDER BY term as an ordinary expression */
pItem->iOrderByCol = 0;
if( sqlite3ResolveExprNames(pNC, pE) ){
return 1;
}
for(j=0; j<pSelect->pEList->nExpr; j++){
| | | 75017 75018 75019 75020 75021 75022 75023 75024 75025 75026 75027 75028 75029 75030 75031 |
/* Otherwise, treat the ORDER BY term as an ordinary expression */
pItem->iOrderByCol = 0;
if( sqlite3ResolveExprNames(pNC, pE) ){
return 1;
}
for(j=0; j<pSelect->pEList->nExpr; j++){
if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
pItem->iOrderByCol = j+1;
}
}
}
return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}
|
| ︙ | ︙ | |||
75246 75247 75248 75249 75250 75251 75252 75253 75254 75255 75256 75257 75258 75259 | memset(&w, 0, sizeof(w)); w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; w.pParse = pParse; w.u.pNC = pOuterNC; sqlite3WalkSelect(&w, p); } /************** End of resolve.c *********************************************/ /************** Begin file expr.c ********************************************/ /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 75323 75324 75325 75326 75327 75328 75329 75330 75331 75332 75333 75334 75335 75336 75337 75338 75339 75340 75341 75342 75343 75344 75345 75346 75347 75348 75349 75350 75351 75352 75353 75354 75355 75356 75357 75358 75359 75360 75361 75362 75363 75364 75365 75366 75367 75368 75369 75370 75371 75372 75373 75374 75375 75376 75377 75378 |
memset(&w, 0, sizeof(w));
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pParse;
w.u.pNC = pOuterNC;
sqlite3WalkSelect(&w, p);
}
/*
** Resolve names in expressions that can only reference a single table:
**
** * CHECK constraints
** * WHERE clauses on partial indices
**
** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
** is set to -1 and the Expr.iColumn value is set to the column number.
**
** Any errors cause an error message to be set in pParse.
*/
SQLITE_PRIVATE void sqlite3ResolveSelfReference(
Parse *pParse, /* Parsing context */
Table *pTab, /* The table being referenced */
int type, /* NC_IsCheck or NC_PartIdx */
Expr *pExpr, /* Expression to resolve. May be NULL. */
ExprList *pList /* Expression list to resolve. May be NUL. */
){
SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
NameContext sNC; /* Name context for pParse->pNewTable */
int i; /* Loop counter */
assert( type==NC_IsCheck || type==NC_PartIdx );
memset(&sNC, 0, sizeof(sNC));
memset(&sSrc, 0, sizeof(sSrc));
sSrc.nSrc = 1;
sSrc.a[0].zName = pTab->zName;
sSrc.a[0].pTab = pTab;
sSrc.a[0].iCursor = -1;
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
sNC.ncFlags = type;
if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
if( pList ){
for(i=0; i<pList->nExpr; i++){
if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
return;
}
}
}
}
/************** End of resolve.c *********************************************/
/************** Begin file expr.c ********************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code. In place of
|
| ︙ | ︙ | |||
77612 77613 77614 77615 77616 77617 77618 |
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
pCol->iSorterColumn, target);
break;
}
/* Otherwise, fall thru into the TK_COLUMN case */
}
case TK_COLUMN: {
| | | | > | > | > > > > | | | < | 77731 77732 77733 77734 77735 77736 77737 77738 77739 77740 77741 77742 77743 77744 77745 77746 77747 77748 77749 77750 77751 77752 77753 77754 77755 77756 77757 77758 |
sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
pCol->iSorterColumn, target);
break;
}
/* Otherwise, fall thru into the TK_COLUMN case */
}
case TK_COLUMN: {
int iTab = pExpr->iTable;
if( iTab<0 ){
if( pParse->ckBase>0 ){
/* Generating CHECK constraints or inserting into partial index */
inReg = pExpr->iColumn + pParse->ckBase;
break;
}else{
/* Deleting from a partial index */
iTab = pParse->iPartIdxTab;
}
}
inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
pExpr->iColumn, iTab, target,
pExpr->op2);
break;
}
case TK_INTEGER: {
codeInteger(pParse, pExpr, 0, target);
break;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
|
| ︙ | ︙ | |||
79043 79044 79045 79046 79047 79048 79049 79050 79051 79052 79053 79054 79055 79056 79057 79058 79059 | /* ** Do a deep comparison of two expression trees. Return 0 if the two ** expressions are completely identical. Return 1 if they differ only ** by a COLLATE operator at the top level. Return 2 if there are differences ** other than the top-level COLLATE operator. ** ** Sometimes this routine will return 2 even if the two expressions ** really are equivalent. If we cannot prove that the expressions are ** identical, we return 2 just to be safe. So if this routine ** returns 2, then you do not really know for certain if the two ** expressions are the same. But if you get a 0 or 1 return, then you ** can be sure the expressions are the same. In the places where ** this routine is used, it does not hurt to get an extra 2 - that ** just might result in some slightly slower code. But returning ** an incorrect 0 or 1 could lead to a malfunction. */ | > > > > > > | | | | | | | > | > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 79167 79168 79169 79170 79171 79172 79173 79174 79175 79176 79177 79178 79179 79180 79181 79182 79183 79184 79185 79186 79187 79188 79189 79190 79191 79192 79193 79194 79195 79196 79197 79198 79199 79200 79201 79202 79203 79204 79205 79206 79207 79208 79209 79210 79211 79212 79213 79214 79215 79216 79217 79218 79219 79220 79221 79222 79223 79224 79225 79226 79227 79228 79229 79230 79231 79232 79233 79234 79235 79236 79237 79238 79239 79240 79241 79242 79243 79244 79245 79246 79247 79248 79249 79250 79251 79252 79253 79254 79255 79256 79257 79258 79259 79260 79261 79262 79263 79264 79265 79266 79267 79268 79269 79270 79271 79272 79273 79274 79275 79276 79277 79278 79279 79280 79281 79282 79283 79284 79285 79286 79287 79288 79289 79290 79291 79292 79293 79294 79295 79296 79297 79298 79299 |
/*
** Do a deep comparison of two expression trees. Return 0 if the two
** expressions are completely identical. Return 1 if they differ only
** by a COLLATE operator at the top level. Return 2 if there are differences
** other than the top-level COLLATE operator.
**
** If any subelement of pB has Expr.iTable==(-1) then it is allowed
** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
**
** The pA side might be using TK_REGISTER. If that is the case and pB is
** not using TK_REGISTER but is otherwise equivalent, then still return 0.
**
** Sometimes this routine will return 2 even if the two expressions
** really are equivalent. If we cannot prove that the expressions are
** identical, we return 2 just to be safe. So if this routine
** returns 2, then you do not really know for certain if the two
** expressions are the same. But if you get a 0 or 1 return, then you
** can be sure the expressions are the same. In the places where
** this routine is used, it does not hurt to get an extra 2 - that
** just might result in some slightly slower code. But returning
** an incorrect 0 or 1 could lead to a malfunction.
*/
SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
if( pA==0||pB==0 ){
return pB==pA ? 0 : 2;
}
assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
return 2;
}
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){
if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
return 1;
}
if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){
return 1;
}
return 2;
}
if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
if( pA->iColumn!=pB->iColumn ) return 2;
if( pA->iTable!=pB->iTable
&& pA->op!=TK_REGISTER
&& (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
if( ExprHasProperty(pA, EP_IntValue) ){
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
return 2;
}
}else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return pA->op==TK_COLLATE ? 1 : 2;
}
}
return 0;
}
/*
** Compare two ExprList objects. Return 0 if they are identical and
** non-zero if they differ in any way.
**
** If any subelement of pB has Expr.iTable==(-1) then it is allowed
** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
**
** This routine might return non-zero for equivalent ExprLists. The
** only consequence will be disabled optimizations. But this routine
** must never return 0 if the two ExprList objects are different, or
** a malfunction will result.
**
** Two NULL pointers are considered to be the same. But a NULL pointer
** always differs from a non-NULL pointer.
*/
SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
int i;
if( pA==0 && pB==0 ) return 0;
if( pA==0 || pB==0 ) return 1;
if( pA->nExpr!=pB->nExpr ) return 1;
for(i=0; i<pA->nExpr; i++){
Expr *pExprA = pA->a[i].pExpr;
Expr *pExprB = pB->a[i].pExpr;
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
}
return 0;
}
/*
** Return true if we can prove the pE2 will always be true if pE1 is
** true. Return false if we cannot complete the proof or if pE2 might
** be false. Examples:
**
** pE1: x==5 pE2: x==5 Result: true
** pE1: x>0 pE2: x==5 Result: false
** pE1: x=21 pE2: x=21 OR y=43 Result: true
** pE1: x!=123 pE2: x IS NOT NULL Result: true
** pE1: x!=?1 pE2: x IS NOT NULL Result: true
** pE1: x IS NULL pE2: x IS NOT NULL Result: false
** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false
**
** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
** Expr.iTable<0 then assume a table number given by iTab.
**
** When in doubt, return false. Returning true might give a performance
** improvement. Returning false might cause a performance reduction, but
** it will always give the correct answer and is hence always safe.
*/
SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
return 1;
}
if( pE2->op==TK_OR
&& (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
|| sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
){
return 1;
}
if( pE2->op==TK_NOTNULL
&& sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
&& (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
){
return 1;
}
return 0;
}
/*
** An instance of the following structure is used by the tree walker
** to count references to table columns in the arguments of an
|
| ︙ | ︙ | |||
79295 79296 79297 79298 79299 79300 79301 |
&& pWalker->walkerDepth==pExpr->op2
){
/* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
| | | 79470 79471 79472 79473 79474 79475 79476 79477 79478 79479 79480 79481 79482 79483 79484 |
&& pWalker->walkerDepth==pExpr->op2
){
/* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
break;
}
}
if( i>=pAggInfo->nFunc ){
/* pExpr is original. Make a new entry in pAggInfo->aFunc[]
*/
u8 enc = ENC(pParse->db);
|
| ︙ | ︙ | |||
80712 80713 80714 80715 80716 80717 80718 80719 80720 80721 80722 80723 80724 80725 | int iIdxCur; /* Cursor open on index being analyzed */ Vdbe *v; /* The virtual machine being built up */ int i; /* Loop counter */ int topOfLoop; /* The top of the loop */ int endOfLoop; /* The end of the loop */ int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ int regTabname = iMem++; /* Register containing table name */ int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* The stat column of sqlite_stat1 */ #ifdef SQLITE_ENABLE_STAT3 int regNumEq = regStat1; /* Number of instances. Same as regStat1 */ int regNumLt = iMem++; /* Number of keys less than regSample */ int regNumDLt = iMem++; /* Number of distinct keys less than regSample */ | > | 80887 80888 80889 80890 80891 80892 80893 80894 80895 80896 80897 80898 80899 80900 80901 | int iIdxCur; /* Cursor open on index being analyzed */ Vdbe *v; /* The virtual machine being built up */ int i; /* Loop counter */ int topOfLoop; /* The top of the loop */ int endOfLoop; /* The end of the loop */ int jZeroRows = -1; /* Jump from here if number of rows is zero */ int iDb; /* Index of database containing pTab */ u8 needTableCnt = 1; /* True to count the table */ int regTabname = iMem++; /* Register containing table name */ int regIdxname = iMem++; /* Register containing index name */ int regStat1 = iMem++; /* The stat column of sqlite_stat1 */ #ifdef SQLITE_ENABLE_STAT3 int regNumEq = regStat1; /* Number of instances. Same as regStat1 */ int regNumLt = iMem++; /* Number of keys less than regSample */ int regNumDLt = iMem++; /* Number of distinct keys less than regSample */ |
| ︙ | ︙ | |||
80771 80772 80773 80774 80775 80776 80777 80778 80779 80780 80781 80782 80783 80784 |
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int nCol;
KeyInfo *pKey;
int addrIfNot = 0; /* address of OP_IfNot */
int *aChngAddr; /* Array of jump instruction addresses */
if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
nCol = pIdx->nColumn;
aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
if( aChngAddr==0 ) continue;
pKey = sqlite3IndexKeyinfo(pParse, pIdx);
if( iMem+1+(nCol*2)>pParse->nMem ){
pParse->nMem = iMem+1+(nCol*2);
| > | 80947 80948 80949 80950 80951 80952 80953 80954 80955 80956 80957 80958 80959 80960 80961 |
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
int nCol;
KeyInfo *pKey;
int addrIfNot = 0; /* address of OP_IfNot */
int *aChngAddr; /* Array of jump instruction addresses */
if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
nCol = pIdx->nColumn;
aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
if( aChngAddr==0 ) continue;
pKey = sqlite3IndexKeyinfo(pParse, pIdx);
if( iMem+1+(nCol*2)>pParse->nMem ){
pParse->nMem = iMem+1+(nCol*2);
|
| ︙ | ︙ | |||
80930 80931 80932 80933 80934 80935 80936 |
** I = (K+D-1)/D
**
** If K==0 then no entry is made into the sqlite_stat1 table.
** If K>0 then it is always the case the D>0 so division by zero
** is never possible.
*/
sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
| < | < > > | | | < < < < | | | | | < | > > | 81107 81108 81109 81110 81111 81112 81113 81114 81115 81116 81117 81118 81119 81120 81121 81122 81123 81124 81125 81126 81127 81128 81129 81130 81131 81132 81133 81134 81135 81136 81137 81138 81139 81140 81141 81142 81143 81144 81145 81146 81147 81148 81149 81150 81151 81152 81153 81154 81155 |
** I = (K+D-1)/D
**
** If K==0 then no entry is made into the sqlite_stat1 table.
** If K>0 then it is always the case the D>0 so division by zero
** is never possible.
*/
sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
for(i=0; i<nCol; i++){
sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
}
if( pIdx->pPartIdxWhere!=0 ) sqlite3VdbeJumpHere(v, jZeroRows);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
if( pIdx->pPartIdxWhere==0 ) sqlite3VdbeJumpHere(v, jZeroRows);
}
/* Create a single sqlite_stat1 entry containing NULL as the index
** name and the row count as the content.
*/
if( pOnlyIdx==0 && needTableCnt ){
sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
VdbeComment((v, "%s", pTab->zName));
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
sqlite3VdbeJumpHere(v, jZeroRows);
}
if( pParse->nMem<regRec ) pParse->nMem = regRec;
}
/*
** Generate code that will cause the most recent index analysis to
** be loaded into internal hash tables where is can be used.
*/
|
| ︙ | ︙ | |||
81150 81151 81152 81153 81154 81155 81156 |
z = argv[2];
for(i=0; *z && i<=n; i++){
v = 0;
while( (c=z[0])>='0' && c<='9' ){
v = v*10 + c - '0';
z++;
}
| > | | > | 81324 81325 81326 81327 81328 81329 81330 81331 81332 81333 81334 81335 81336 81337 81338 81339 81340 81341 |
z = argv[2];
for(i=0; *z && i<=n; i++){
v = 0;
while( (c=z[0])>='0' && c<='9' ){
v = v*10 + c - '0';
z++;
}
if( i==0 && (pIndex==0 || pIndex->pPartIdxWhere==0) ){
if( v>0 ) pTable->nRowEst = v;
if( pIndex==0 ) break;
}
pIndex->aiRowEst[i] = v;
if( *z==' ' ) z++;
if( strcmp(z, "unordered")==0 ){
pIndex->bUnordered = 1;
break;
}
}
|
| ︙ | ︙ | |||
82591 82592 82593 82594 82595 82596 82597 82598 82599 82600 82601 82602 82603 82604 |
/*
** Reclaim the memory used by an index
*/
static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
sqlite3DeleteIndexSamples(db, p);
#endif
sqlite3DbFree(db, p->zColAff);
sqlite3DbFree(db, p);
}
/*
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
| > | 82767 82768 82769 82770 82771 82772 82773 82774 82775 82776 82777 82778 82779 82780 82781 |
/*
** Reclaim the memory used by an index
*/
static void freeIndex(sqlite3 *db, Index *p){
#ifndef SQLITE_OMIT_ANALYZE
sqlite3DeleteIndexSamples(db, p);
#endif
sqlite3ExprDelete(db, p->pPartIdxWhere);
sqlite3DbFree(db, p->zColAff);
sqlite3DbFree(db, p);
}
/*
** For the index called zIdxName which is found in the database iDb,
** unlike that index from its Table then remove the index from
|
| ︙ | ︙ | |||
83434 83435 83436 83437 83438 83439 83440 |
}else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
"INTEGER PRIMARY KEY");
#endif
}else{
Index *p;
| | > | 83611 83612 83613 83614 83615 83616 83617 83618 83619 83620 83621 83622 83623 83624 83625 83626 |
}else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
"INTEGER PRIMARY KEY");
#endif
}else{
Index *p;
p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
0, sortOrder, 0);
if( p ){
p->autoIndex = 2;
}
pList = 0;
}
primary_key_exit:
|
| ︙ | ︙ | |||
83729 83730 83731 83732 83733 83734 83735 |
iDb = sqlite3SchemaToIndex(db, p->pSchema);
#ifndef SQLITE_OMIT_CHECK
/* Resolve names in all CHECK constraint expressions.
*/
if( p->pCheck ){
| < < < < | < < < < < < < < < < < < < < < | 83907 83908 83909 83910 83911 83912 83913 83914 83915 83916 83917 83918 83919 83920 83921 |
iDb = sqlite3SchemaToIndex(db, p->pSchema);
#ifndef SQLITE_OMIT_CHECK
/* Resolve names in all CHECK constraint expressions.
*/
if( p->pCheck ){
sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
}
#endif /* !defined(SQLITE_OMIT_CHECK) */
/* If the db->init.busy is 1 it means we are reading the SQL off the
** "sqlite_master" or "sqlite_temp_master" table on the disk.
** So do not write to the disk again. Extract the root page number
** for the table from the db->init.newTnum field. (The page number
|
| ︙ | ︙ | |||
84600 84601 84602 84603 84604 84605 84606 84607 84608 84609 84610 84611 84612 84613 | Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab++; /* Btree cursor used for pTab */ int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ int iSorter; /* Cursor opened by OpenSorter (if in use) */ int addr1; /* Address of top of loop */ int addr2; /* Address to jump to for next iteration */ int tnum; /* Root page of index */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ int regRecord; /* Register holding assemblied index record */ sqlite3 *db = pParse->db; /* The database connection */ int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION | > | 84759 84760 84761 84762 84763 84764 84765 84766 84767 84768 84769 84770 84771 84772 84773 | Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab++; /* Btree cursor used for pTab */ int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ int iSorter; /* Cursor opened by OpenSorter (if in use) */ int addr1; /* Address of top of loop */ int addr2; /* Address to jump to for next iteration */ int tnum; /* Root page of index */ int iPartIdxLabel; /* Jump to this label to skip a row */ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ int regRecord; /* Register holding assemblied index record */ sqlite3 *db = pParse->db; /* The database connection */ int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION |
| ︙ | ︙ | |||
84639 84640 84641 84642 84643 84644 84645 | /* Open the table. Loop through all rows of the table, inserting index ** records into the sorter. */ sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); regRecord = sqlite3GetTempReg(pParse); | | > | 84799 84800 84801 84802 84803 84804 84805 84806 84807 84808 84809 84810 84811 84812 84813 84814 84815 |
/* Open the table. Loop through all rows of the table, inserting index
** records into the sorter. */
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
regRecord = sqlite3GetTempReg(pParse);
sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
sqlite3VdbeJumpHere(v, addr1);
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
if( pIndex->onError!=OE_None ){
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
|
| ︙ | ︙ | |||
84691 84692 84693 84694 84695 84696 84697 | Parse *pParse, /* All information about this parse */ Token *pName1, /* First part of index name. May be NULL */ Token *pName2, /* Second part of index name. May be NULL */ SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */ ExprList *pList, /* A list of columns to be indexed */ int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ Token *pStart, /* The CREATE token that begins this statement */ | | | 84852 84853 84854 84855 84856 84857 84858 84859 84860 84861 84862 84863 84864 84865 84866 |
Parse *pParse, /* All information about this parse */
Token *pName1, /* First part of index name. May be NULL */
Token *pName2, /* Second part of index name. May be NULL */
SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
ExprList *pList, /* A list of columns to be indexed */
int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
Token *pStart, /* The CREATE token that begins this statement */
Expr *pPIWhere, /* WHERE clause for partial indices */
int sortOrder, /* Sort order of primary key when pList==NULL */
int ifNotExist /* Omit error if index already exists */
){
Index *pRet = 0; /* Pointer to return */
Table *pTab = 0; /* Table to be indexed */
Index *pIndex = 0; /* The index to be created */
char *zName = 0; /* Name of the index */
|
| ︙ | ︙ | |||
84713 84714 84715 84716 84717 84718 84719 | int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ struct ExprList_item *pListItem; /* For looping over pList */ int nCol; int nExtra = 0; char *zExtra; | < | 84874 84875 84876 84877 84878 84879 84880 84881 84882 84883 84884 84885 84886 84887 |
int iDb; /* Index of the database that is being written */
Token *pName = 0; /* Unqualified name of the index to create */
struct ExprList_item *pListItem; /* For looping over pList */
int nCol;
int nExtra = 0;
char *zExtra;
assert( pParse->nErr==0 ); /* Never called with prior errors */
if( db->mallocFailed || IN_DECLARE_VTAB ){
goto exit_create_index;
}
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto exit_create_index;
}
|
| ︙ | ︙ | |||
84759 84760 84761 84762 84763 84764 84765 |
/* Because the parser constructs pTblName from a single identifier,
** sqlite3FixSrcList can never fail. */
assert(0);
}
pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
assert( db->mallocFailed==0 || pTab==0 );
if( pTab==0 ) goto exit_create_index;
| | > > > > > | 84919 84920 84921 84922 84923 84924 84925 84926 84927 84928 84929 84930 84931 84932 84933 84934 84935 84936 84937 84938 |
/* Because the parser constructs pTblName from a single identifier,
** sqlite3FixSrcList can never fail. */
assert(0);
}
pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
assert( db->mallocFailed==0 || pTab==0 );
if( pTab==0 ) goto exit_create_index;
if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){
sqlite3ErrorMsg(pParse,
"cannot create a TEMP index on non-TEMP table \"%s\"",
pTab->zName);
goto exit_create_index;
}
}else{
assert( pName==0 );
assert( pStart==0 );
pTab = pParse->pNewTable;
if( !pTab ) goto exit_create_index;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
}
|
| ︙ | ︙ | |||
84908 84909 84910 84911 84912 84913 84914 84915 84916 84917 84918 84919 84920 84921 |
memcpy(pIndex->zName, zName, nName+1);
pIndex->pTable = pTab;
pIndex->nColumn = pList->nExpr;
pIndex->onError = (u8)onError;
pIndex->uniqNotNull = onError==OE_Abort;
pIndex->autoIndex = (u8)(pName==0);
pIndex->pSchema = db->aDb[iDb].pSchema;
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
/* Check to see if we should honor DESC requests on index columns
*/
if( pDb->pSchema->file_format>=4 ){
sortOrderMask = -1; /* Honor DESC */
}else{
| > > > > > | 85073 85074 85075 85076 85077 85078 85079 85080 85081 85082 85083 85084 85085 85086 85087 85088 85089 85090 85091 |
memcpy(pIndex->zName, zName, nName+1);
pIndex->pTable = pTab;
pIndex->nColumn = pList->nExpr;
pIndex->onError = (u8)onError;
pIndex->uniqNotNull = onError==OE_Abort;
pIndex->autoIndex = (u8)(pName==0);
pIndex->pSchema = db->aDb[iDb].pSchema;
if( pPIWhere ){
sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
pIndex->pPartIdxWhere = pPIWhere;
pPIWhere = 0;
}
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
/* Check to see if we should honor DESC requests on index columns
*/
if( pDb->pSchema->file_format>=4 ){
sortOrderMask = -1; /* Honor DESC */
}else{
|
| ︙ | ︙ | |||
85063 85064 85065 85066 85067 85068 85069 | ** we don't want to recreate it. ** ** If pTblName==0 it means this index is generated as a primary key ** or UNIQUE constraint of a CREATE TABLE statement. Since the table ** has just been created, it contains no data and the index initialization ** step can be skipped. */ | | > | | < < | 85233 85234 85235 85236 85237 85238 85239 85240 85241 85242 85243 85244 85245 85246 85247 85248 85249 85250 85251 85252 85253 85254 85255 85256 85257 85258 85259 85260 85261 85262 85263 85264 85265 85266 85267 85268 85269 |
** we don't want to recreate it.
**
** If pTblName==0 it means this index is generated as a primary key
** or UNIQUE constraint of a CREATE TABLE statement. Since the table
** has just been created, it contains no data and the index initialization
** step can be skipped.
*/
else if( pParse->nErr==0 ){
Vdbe *v;
char *zStmt;
int iMem = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto exit_create_index;
/* Create the rootpage for the index
*/
sqlite3BeginWriteOperation(pParse, 1, iDb);
sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
/* Gather the complete text of the CREATE INDEX statement into
** the zStmt variable
*/
if( pStart ){
int n = (pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
if( pName->z[n-1]==';' ) n--;
/* A named index with an explicit CREATE INDEX statement */
zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
onError==OE_None ? "" : " UNIQUE", n, pName->z);
}else{
/* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
/* zStmt = sqlite3MPrintf(""); */
zStmt = 0;
}
/* Add an entry in sqlite_master for this index
|
| ︙ | ︙ | |||
85142 85143 85144 85145 85146 85147 85148 |
}
pRet = pIndex;
pIndex = 0;
}
/* Clean up before exiting */
exit_create_index:
| | < | < | 85311 85312 85313 85314 85315 85316 85317 85318 85319 85320 85321 85322 85323 85324 85325 85326 |
}
pRet = pIndex;
pIndex = 0;
}
/* Clean up before exiting */
exit_create_index:
if( pIndex ) freeIndex(db, pIndex);
sqlite3ExprDelete(db, pPIWhere);
sqlite3ExprListDelete(db, pList);
sqlite3SrcListDelete(db, pTblName);
sqlite3DbFree(db, zName);
return pRet;
}
/*
|
| ︙ | ︙ | |||
87121 87122 87123 87124 87125 87126 87127 87128 87129 87130 |
Table *pTab, /* Table containing the row to be deleted */
int iCur, /* Cursor number for the table */
int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){
int i;
Index *pIdx;
int r1;
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
| > > | | > > > > > > > > | | | | | > > > > > > > > > > > | 87288 87289 87290 87291 87292 87293 87294 87295 87296 87297 87298 87299 87300 87301 87302 87303 87304 87305 87306 87307 87308 87309 87310 87311 87312 87313 87314 87315 87316 87317 87318 87319 87320 87321 87322 87323 87324 87325 87326 87327 87328 87329 87330 87331 87332 87333 87334 87335 87336 87337 87338 87339 87340 87341 87342 87343 87344 87345 87346 87347 87348 87349 87350 87351 87352 87353 87354 |
Table *pTab, /* Table containing the row to be deleted */
int iCur, /* Cursor number for the table */
int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){
int i;
Index *pIdx;
int r1;
int iPartIdxLabel;
Vdbe *v = pParse->pVdbe;
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
}
}
/*
** Generate code that will assemble an index key and put it in register
** regOut. The key with be for index pIdx which is an index on pTab.
** iCur is the index of a cursor open on the pTab table and pointing to
** the entry that needs indexing.
**
** Return a register number which is the first in a block of
** registers that holds the elements of the index key. The
** block of registers has already been deallocated by the time
** this routine returns.
**
** If *piPartIdxLabel is not NULL, fill it in with a label and jump
** to that label if pIdx is a partial index that should be skipped.
** A partial index should be skipped if its WHERE clause evaluates
** to false or null. If pIdx is not a partial index, *piPartIdxLabel
** will be set to zero which is an empty label that is ignored by
** sqlite3VdbeResolveLabel().
*/
SQLITE_PRIVATE int sqlite3GenerateIndexKey(
Parse *pParse, /* Parsing context */
Index *pIdx, /* The index for which to generate a key */
int iCur, /* Cursor number for the pIdx->pTable table */
int regOut, /* Write the new index key to this register */
int doMakeRec, /* Run the OP_MakeRecord instruction if true */
int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */
){
Vdbe *v = pParse->pVdbe;
int j;
Table *pTab = pIdx->pTable;
int regBase;
int nCol;
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
*piPartIdxLabel = sqlite3VdbeMakeLabel(v);
pParse->iPartIdxTab = iCur;
sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
SQLITE_JUMPIFNULL);
}else{
*piPartIdxLabel = 0;
}
}
nCol = pIdx->nColumn;
regBase = sqlite3GetTempRange(pParse, nCol+1);
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
for(j=0; j<nCol; j++){
int idx = pIdx->aiColumn[j];
if( idx==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j);
|
| ︙ | ︙ | |||
91516 91517 91518 91519 91520 91521 91522 91523 91524 91525 91526 91527 91528 91529 91530 91531 91532 91533 91534 91535 91536 91537 91538 91539 91540 91541 91542 91543 91544 91545 91546 91547 91548 91549 91550 91551 |
/* Test all UNIQUE constraints by creating entries for each UNIQUE
** index and making sure that duplicate entries do not already exist.
** Add the new records to the indices as we go.
*/
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
int regIdx;
int regR;
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
/* Create a key for accessing the index entry */
regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
for(i=0; i<pIdx->nColumn; i++){
int idx = pIdx->aiColumn[i];
if( idx==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
}else{
sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
}
}
sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
/* Find out what action to take in case there is an indexing conflict */
onError = pIdx->onError;
if( onError==OE_None ){
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
continue; /* pIdx is not a UNIQUE index */
}
if( overrideError!=OE_Default ){
onError = overrideError;
}else if( onError==OE_Default ){
onError = OE_Abort;
}
| > > > > > > > > > > > | 91704 91705 91706 91707 91708 91709 91710 91711 91712 91713 91714 91715 91716 91717 91718 91719 91720 91721 91722 91723 91724 91725 91726 91727 91728 91729 91730 91731 91732 91733 91734 91735 91736 91737 91738 91739 91740 91741 91742 91743 91744 91745 91746 91747 91748 91749 91750 |
/* Test all UNIQUE constraints by creating entries for each UNIQUE
** index and making sure that duplicate entries do not already exist.
** Add the new records to the indices as we go.
*/
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
int regIdx;
int regR;
int addrSkipRow = 0;
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
addrSkipRow = sqlite3VdbeMakeLabel(v);
pParse->ckBase = regData;
sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
SQLITE_JUMPIFNULL);
pParse->ckBase = 0;
}
/* Create a key for accessing the index entry */
regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
for(i=0; i<pIdx->nColumn; i++){
int idx = pIdx->aiColumn[i];
if( idx==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
}else{
sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
}
}
sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
/* Find out what action to take in case there is an indexing conflict */
onError = pIdx->onError;
if( onError==OE_None ){
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
sqlite3VdbeResolveLabel(v, addrSkipRow);
continue; /* pIdx is not a UNIQUE index */
}
if( overrideError!=OE_Default ){
onError = overrideError;
}else if( onError==OE_Default ){
onError = OE_Abort;
}
|
| ︙ | ︙ | |||
91607 91608 91609 91610 91611 91612 91613 91614 91615 91616 91617 91618 91619 91620 |
pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
);
seenReplace = 1;
break;
}
}
sqlite3VdbeJumpHere(v, j3);
sqlite3ReleaseTempReg(pParse, regR);
}
if( pbMayReplace ){
*pbMayReplace = seenReplace;
}
}
| > | 91806 91807 91808 91809 91810 91811 91812 91813 91814 91815 91816 91817 91818 91819 91820 |
pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace
);
seenReplace = 1;
break;
}
}
sqlite3VdbeJumpHere(v, j3);
sqlite3VdbeResolveLabel(v, addrSkipRow);
sqlite3ReleaseTempReg(pParse, regR);
}
if( pbMayReplace ){
*pbMayReplace = seenReplace;
}
}
|
| ︙ | ︙ | |||
91636 91637 91638 91639 91640 91641 91642 |
int *aRegIdx, /* Register used by each index. 0 for unused indices */
int isUpdate, /* True for UPDATE, False for INSERT */
int appendBias, /* True if this is likely to be an append */
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
int i;
Vdbe *v;
| < | < > > > | 91836 91837 91838 91839 91840 91841 91842 91843 91844 91845 91846 91847 91848 91849 91850 91851 91852 91853 91854 91855 91856 91857 91858 91859 91860 91861 91862 |
int *aRegIdx, /* Register used by each index. 0 for unused indices */
int isUpdate, /* True for UPDATE, False for INSERT */
int appendBias, /* True if this is likely to be an append */
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
){
int i;
Vdbe *v;
Index *pIdx;
u8 pik_flags;
int regData;
int regRec;
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
}
sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
if( useSeekResult ){
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
}
}
regData = regRowid + 1;
regRec = sqlite3GetTempReg(pParse);
|
| ︙ | ︙ | |||
91749 91750 91751 91752 91753 91754 91755 91756 91757 91758 91759 91760 91761 91762 |
** for index pDest in an insert transfer optimization. The rules
** for a compatible index:
**
** * The index is over the same set of columns
** * The same DESC and ASC markings occurs on all columns
** * The same onError processing (OE_Abort, OE_Ignore, etc)
** * The same collating sequence on each column
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
assert( pDest && pSrc );
assert( pDest->pTable!=pSrc->pTable );
if( pDest->nColumn!=pSrc->nColumn ){
return 0; /* Different number of columns */
| > | 91950 91951 91952 91953 91954 91955 91956 91957 91958 91959 91960 91961 91962 91963 91964 |
** for index pDest in an insert transfer optimization. The rules
** for a compatible index:
**
** * The index is over the same set of columns
** * The same DESC and ASC markings occurs on all columns
** * The same onError processing (OE_Abort, OE_Ignore, etc)
** * The same collating sequence on each column
** * The index has the exact same WHERE clause
*/
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
int i;
assert( pDest && pSrc );
assert( pDest->pTable!=pSrc->pTable );
if( pDest->nColumn!=pSrc->nColumn ){
return 0; /* Different number of columns */
|
| ︙ | ︙ | |||
91770 91771 91772 91773 91774 91775 91776 91777 91778 91779 91780 91781 91782 91783 |
}
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
}
if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
return 0; /* Different collating sequences */
}
}
/* If no test above fails then the indices must be compatible */
return 1;
}
/*
| > > > | 91972 91973 91974 91975 91976 91977 91978 91979 91980 91981 91982 91983 91984 91985 91986 91987 91988 |
}
if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){
return 0; /* Different sort orders */
}
if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
return 0; /* Different collating sequences */
}
}
if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
return 0; /* Different WHERE clauses */
}
/* If no test above fails then the indices must be compatible */
return 1;
}
/*
|
| ︙ | ︙ | |||
91926 91927 91928 91929 91930 91931 91932 |
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
if( pSrcIdx==0 ){
return 0; /* pDestIdx has no corresponding index in pSrc */
}
}
#ifndef SQLITE_OMIT_CHECK
| | | 92131 92132 92133 92134 92135 92136 92137 92138 92139 92140 92141 92142 92143 92144 92145 |
if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
}
if( pSrcIdx==0 ){
return 0; /* pDestIdx has no corresponding index in pSrc */
}
}
#ifndef SQLITE_OMIT_CHECK
if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
}
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
/* Disallow the transfer optimization if the destination table constains
** any foreign key constraints. This is more restrictive than necessary.
** But the main beneficiary of the transfer optimization is the VACUUM
|
| ︙ | ︙ | |||
94839 94840 94841 94842 94843 94844 94845 |
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
cnt++;
}
}
/* Make sure sufficient number of registers have been allocated */
| < | < | 95044 95045 95046 95047 95048 95049 95050 95051 95052 95053 95054 95055 95056 95057 95058 |
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->tnum, 2+cnt);
cnt++;
}
}
/* Make sure sufficient number of registers have been allocated */
pParse->nMem = MAX( pParse->nMem, cnt+7 );
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
sqlite3VdbeChangeP5(v, (u8)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
|
| ︙ | ︙ | |||
94866 94867 94868 94869 94870 94871 94872 94873 |
Index *pIdx;
int loopTop;
if( pTab->pIndex==0 ) continue;
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
| > > | > > | < | | > > | | > > > < < < < < < < < < < < < | | | | | < | | | | < < > | 95069 95070 95071 95072 95073 95074 95075 95076 95077 95078 95079 95080 95081 95082 95083 95084 95085 95086 95087 95088 95089 95090 95091 95092 95093 95094 95095 95096 95097 95098 95099 95100 95101 95102 95103 95104 95105 95106 95107 95108 95109 95110 95111 95112 95113 95114 95115 95116 95117 95118 95119 95120 95121 95122 95123 95124 95125 95126 95127 95128 95129 95130 95131 95132 95133 |
Index *pIdx;
int loopTop;
if( pTab->pIndex==0 ) continue;
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
sqlite3ExprCacheClear(pParse);
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */
}
pParse->nMem = MAX(pParse->nMem, 7+j);
loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0) + 1;
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2, jmp3;
int r1;
static const VdbeOpList idxErr[] = {
{ OP_AddImm, 1, -1, 0},
{ OP_String8, 0, 3, 0}, /* 1 */
{ OP_Rowid, 1, 4, 0},
{ OP_String8, 0, 5, 0}, /* 3 */
{ OP_String8, 0, 6, 0}, /* 4 */
{ OP_Concat, 4, 3, 3},
{ OP_Concat, 5, 3, 3},
{ OP_Concat, 6, 3, 3},
{ OP_ResultRow, 3, 1, 0},
{ OP_IfPos, 1, 0, 0}, /* 9 */
{ OP_Halt, 0, 0, 0},
};
r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1); /* increment entry count */
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
sqlite3VdbeJumpHere(v, addr+9);
sqlite3VdbeJumpHere(v, jmp2);
sqlite3VdbeResolveLabel(v, jmp3);
}
sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
"wrong # of entries in index ", P4_STATIC);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeAddOp2(v, OP_Count, j+2, 3);
sqlite3VdbeAddOp3(v, OP_Eq, 7+j, addr+8, 3);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
}
#endif /* SQLITE_OMIT_BTREECOUNT */
}
}
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
sqlite3VdbeChangeP2(v, addr, -mxErr);
sqlite3VdbeJumpHere(v, addr+1);
sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
}else
|
| ︙ | ︙ | |||
100325 100326 100327 100328 100329 100330 100331 | /* If there is both a GROUP BY and an ORDER BY clause and they are ** identical, then disable the ORDER BY clause since the GROUP BY ** will cause elements to come out in the correct order. This is ** an optimization - the correct answer should result regardless. ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER ** to disable this optimization for testing purposes. */ | | | | 100522 100523 100524 100525 100526 100527 100528 100529 100530 100531 100532 100533 100534 100535 100536 100537 100538 100539 100540 100541 100542 100543 100544 100545 100546 100547 100548 100549 100550 100551 100552 100553 100554 100555 100556 100557 |
/* If there is both a GROUP BY and an ORDER BY clause and they are
** identical, then disable the ORDER BY clause since the GROUP BY
** will cause elements to come out in the correct order. This is
** an optimization - the correct answer should result regardless.
** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
** to disable this optimization for testing purposes.
*/
if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0
&& OptimizationEnabled(db, SQLITE_GroupByOrder) ){
pOrderBy = 0;
}
/* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
** if the select-list is the same as the ORDER BY list, then this query
** can be rewritten as a GROUP BY. In other words, this:
**
** SELECT DISTINCT xyz FROM ... ORDER BY xyz
**
** is transformed to:
**
** SELECT xyz FROM ... GROUP BY xyz
**
** The second form is preferred as a single index (or temp-table) may be
** used for both the ORDER BY and DISTINCT processing. As originally
** written the query must use a temp-table for at least one of the ORDER
** BY and DISTINCT, and an index or separate temp-table for the other.
*/
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
&& sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0
){
p->selFlags &= ~SF_Distinct;
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
pGroupBy = p->pGroupBy;
pOrderBy = 0;
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
** the sDistinct.isTnct is still set. Hence, isTnct represents the
|
| ︙ | ︙ | |||
102573 102574 102575 102576 102577 102578 102579 |
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
if( nIdx>0 ){
aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
if( aRegIdx==0 ) goto update_cleanup;
}
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
| | | 102770 102771 102772 102773 102774 102775 102776 102777 102778 102779 102780 102781 102782 102783 102784 |
for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
if( nIdx>0 ){
aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
if( aRegIdx==0 ) goto update_cleanup;
}
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int reg;
if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
reg = ++pParse->nMem;
}else{
reg = 0;
for(i=0; i<pIdx->nColumn; i++){
if( aXRef[pIdx->aiColumn[i]]>=0 ){
reg = ++pParse->nMem;
break;
|
| ︙ | ︙ | |||
105113 105114 105115 105116 105117 105118 105119 |
** WhereTerms. All pointers to WhereTerms should be invalidated after
** calling this routine. Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
WhereTerm *pTerm;
int idx;
| | | 105310 105311 105312 105313 105314 105315 105316 105317 105318 105319 105320 105321 105322 105323 105324 |
** WhereTerms. All pointers to WhereTerms should be invalidated after
** calling this routine. Such pointers may be reinitialized by referencing
** the pWC->a[] array.
*/
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
WhereTerm *pTerm;
int idx;
testcase( wtFlags & TERM_VIRTUAL );
if( pWC->nTerm>=pWC->nSlot ){
WhereTerm *pOld = pWC->a;
sqlite3 *db = pWC->pWInfo->pParse->db;
pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
if( pWC->a==0 ){
if( wtFlags & TERM_DYNAMIC ){
sqlite3ExprDelete(db, p);
|
| ︙ | ︙ | |||
105258 105259 105260 105261 105262 105263 105264 | return mask; } /* ** Return TRUE if the given operator is one of the operators that is ** allowed for an indexable WHERE clause term. The allowed operators are ** "=", "<", ">", "<=", ">=", "IN", and "IS NULL" | < < < < < < < | 105455 105456 105457 105458 105459 105460 105461 105462 105463 105464 105465 105466 105467 105468 |
return mask;
}
/*
** Return TRUE if the given operator is one of the operators that is
** allowed for an indexable WHERE clause term. The allowed operators are
** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
*/
static int allowedOp(int op){
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
assert( TK_LT>TK_EQ && TK_LT<TK_GE );
assert( TK_LE>TK_EQ && TK_LE<TK_GE );
assert( TK_GE==TK_EQ+4 );
return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
|
| ︙ | ︙ | |||
105583 105584 105585 105586 105587 105588 105589 |
op = pRight->op;
if( op==TK_REGISTER ){
op = pRight->op2;
}
if( op==TK_VARIABLE ){
Vdbe *pReprepare = pParse->pReprepare;
int iCol = pRight->iColumn;
| | | 105773 105774 105775 105776 105777 105778 105779 105780 105781 105782 105783 105784 105785 105786 105787 |
op = pRight->op;
if( op==TK_REGISTER ){
op = pRight->op2;
}
if( op==TK_VARIABLE ){
Vdbe *pReprepare = pParse->pReprepare;
int iCol = pRight->iColumn;
pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE);
if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
z = (char *)sqlite3_value_text(pVal);
}
sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
}else if( op==TK_STRING ){
z = pRight->u.zToken;
|
| ︙ | ︙ | |||
105938 105939 105940 105941 105942 105943 105944 |
}
}
}
/* At this point, okToChngToIN is true if original pTerm satisfies
** case 1. In that case, construct a new virtual term that is
** pTerm converted into an IN operator.
| < < | 106128 106129 106130 106131 106132 106133 106134 106135 106136 106137 106138 106139 106140 106141 |
}
}
}
/* At this point, okToChngToIN is true if original pTerm satisfies
** case 1. In that case, construct a new virtual term that is
** pTerm converted into an IN operator.
*/
if( okToChngToIN ){
Expr *pDup; /* A transient duplicate expression */
ExprList *pList = 0; /* The RHS of the IN operator */
Expr *pLeft = 0; /* The LHS of the IN operator */
Expr *pNew; /* The complete IN operator */
|
| ︙ | ︙ | |||
106181 106182 106183 106184 106185 106186 106187 |
if( noCase ){
/* The point is to increment the last character before the first
** wildcard. But if we increment '@', that will push it into the
** alphabetic range where case conversions will mess up the
** inequality. To avoid this, make sure to also run the full
** LIKE on all candidate expressions by clearing the isComplete flag
*/
| | < < | 106369 106370 106371 106372 106373 106374 106375 106376 106377 106378 106379 106380 106381 106382 106383 |
if( noCase ){
/* The point is to increment the last character before the first
** wildcard. But if we increment '@', that will push it into the
** alphabetic range where case conversions will mess up the
** inequality. To avoid this, make sure to also run the full
** LIKE on all candidate expressions by clearing the isComplete flag
*/
if( c=='A'-1 ) isComplete = 0;
c = sqlite3UpperToLower[c];
}
*pC = c + 1;
}
sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
sCollSeqName.n = 6;
pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
|
| ︙ | ︙ | |||
106690 106691 106692 106693 106694 106695 106696 |
sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
(char*)pKeyinfo, P4_KEYINFO_HANDOFF);
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
regRecord = sqlite3GetTempReg(pParse);
| | | 106876 106877 106878 106879 106880 106881 106882 106883 106884 106885 106886 106887 106888 106889 106890 |
sqlite3VdbeAddOp4(v, OP_OpenAutoindex, pLevel->iIdxCur, nColumn+1, 0,
(char*)pKeyinfo, P4_KEYINFO_HANDOFF);
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
regRecord = sqlite3GetTempReg(pParse);
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite3VdbeJumpHere(v, addrTop);
sqlite3ReleaseTempReg(pParse, regRecord);
|
| ︙ | ︙ | |||
107047 107048 107049 107050 107051 107052 107053 |
sqlite3_value **pp
){
if( pExpr->op==TK_VARIABLE
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
){
int iVar = pExpr->iColumn;
sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
| | | 107233 107234 107235 107236 107237 107238 107239 107240 107241 107242 107243 107244 107245 107246 107247 |
sqlite3_value **pp
){
if( pExpr->op==TK_VARIABLE
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
){
int iVar = pExpr->iColumn;
sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
*pp = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, aff);
return SQLITE_OK;
}
return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
}
#endif
/*
|
| ︙ | ︙ | |||
107273 107274 107275 107276 107277 107278 107279 | ** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' ** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' ** ** The t2.z='ok' is disabled in the in (2) because it originates ** in the ON clause. The term is disabled in (3) because it is not part ** of a LEFT OUTER JOIN. In (1), the term is not disabled. ** | < < < | 107459 107460 107461 107462 107463 107464 107465 107466 107467 107468 107469 107470 107471 107472 | ** (2) SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.x AND t2.z='ok' ** (3) SELECT * FROM t1, t2 WHERE t1.a=t2.x AND t2.z='ok' ** ** The t2.z='ok' is disabled in the in (2) because it originates ** in the ON clause. The term is disabled in (3) because it is not part ** of a LEFT OUTER JOIN. In (1), the term is not disabled. ** ** Disabling a term causes that term to not be tested in the inner loop ** of the join. Disabling is an optimization. When terms are satisfied ** by indices, we disable them to prevent redundant tests in the inner ** loop. We would get the correct results if nothing were ever disabled, ** but joins might run a little slower. The trick is to disable as much ** as we can without disabling too much. If we disabled in (1), we'd get ** the wrong answer. See ticket #813. |
| ︙ | ︙ | |||
107505 107506 107507 107508 107509 107510 107511 |
for(j=0; j<nEq; j++){
int r1;
pTerm = pLoop->aLTerm[j];
assert( pTerm!=0 );
/* The following true for indices with redundant columns.
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
| | | 107688 107689 107690 107691 107692 107693 107694 107695 107696 107697 107698 107699 107700 107701 107702 |
for(j=0; j<nEq; j++){
int r1;
pTerm = pLoop->aLTerm[j];
assert( pTerm!=0 );
/* The following true for indices with redundant columns.
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
if( r1!=regBase+j ){
if( nReg==1 ){
sqlite3ReleaseTempReg(pParse, regBase);
regBase = r1;
}else{
sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j);
|
| ︙ | ︙ | |||
107705 107706 107707 107708 107709 107710 107711 107712 107713 107714 107715 107716 107717 107718 107719 107720 107721 107722 107723 107724 107725 107726 107727 107728 107729 |
int omitTable; /* True if we use the index only */
int bRev; /* True if we need to scan in reverse order */
WhereLevel *pLevel; /* The where level to be coded */
WhereLoop *pLoop; /* The WhereLoop object being coded */
WhereClause *pWC; /* Decomposition of the entire WHERE clause */
WhereTerm *pTerm; /* A WHERE clause term */
Parse *pParse; /* Parsing context */
Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
Bitmask newNotReady; /* Return value */
pParse = pWInfo->pParse;
v = pParse->pVdbe;
pWC = &pWInfo->sWC;
pLevel = &pWInfo->a[iLevel];
pLoop = pLevel->pWLoop;
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
iCur = pTabItem->iCursor;
bRev = (pWInfo->revMask>>iLevel)&1;
omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
&& (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
| > > | 107888 107889 107890 107891 107892 107893 107894 107895 107896 107897 107898 107899 107900 107901 107902 107903 107904 107905 107906 107907 107908 107909 107910 107911 107912 107913 107914 |
int omitTable; /* True if we use the index only */
int bRev; /* True if we need to scan in reverse order */
WhereLevel *pLevel; /* The where level to be coded */
WhereLoop *pLoop; /* The WhereLoop object being coded */
WhereClause *pWC; /* Decomposition of the entire WHERE clause */
WhereTerm *pTerm; /* A WHERE clause term */
Parse *pParse; /* Parsing context */
sqlite3 *db; /* Database connection */
Vdbe *v; /* The prepared stmt under constructions */
struct SrcList_item *pTabItem; /* FROM clause term being coded */
int addrBrk; /* Jump here to break out of the loop */
int addrCont; /* Jump here to continue with next cycle */
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
int iReleaseReg = 0; /* Temp register to free before returning */
Bitmask newNotReady; /* Return value */
pParse = pWInfo->pParse;
v = pParse->pVdbe;
pWC = &pWInfo->sWC;
db = pParse->db;
pLevel = &pWInfo->a[iLevel];
pLoop = pLevel->pWLoop;
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
iCur = pTabItem->iCursor;
bRev = (pWInfo->revMask>>iLevel)&1;
omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
&& (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0;
|
| ︙ | ︙ | |||
107814 107815 107816 107817 107818 107819 107820 |
*/
assert( pLoop->u.btree.nEq==1 );
iReleaseReg = sqlite3GetTempReg(pParse);
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
assert( omitTable==0 );
| | | 107999 108000 108001 108002 108003 108004 108005 108006 108007 108008 108009 108010 108011 108012 108013 |
*/
assert( pLoop->u.btree.nEq==1 );
iReleaseReg = sqlite3GetTempReg(pParse);
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
assert( omitTable==0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
addrNxt = pLevel->addrNxt;
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
VdbeComment((v, "pk"));
|
| ︙ | ︙ | |||
107862 107863 107864 107865 107866 107867 107868 |
/* TK_GE */ OP_SeekGe
};
assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
assert( (pStart->wtFlags & TERM_VNULL)==0 );
| | | | 108047 108048 108049 108050 108051 108052 108053 108054 108055 108056 108057 108058 108059 108060 108061 108062 108063 108064 108065 108066 108067 108068 108069 108070 108071 108072 108073 108074 108075 108076 108077 108078 108079 108080 |
/* TK_GE */ OP_SeekGe
};
assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
assert( (pStart->wtFlags & TERM_VNULL)==0 );
testcase( pStart->wtFlags & TERM_VIRTUAL );
pX = pStart->pExpr;
assert( pX!=0 );
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
VdbeComment((v, "pk"));
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
sqlite3ReleaseTempReg(pParse, rTemp);
disableTerm(pLevel, pStart);
}else{
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
}
if( pEnd ){
Expr *pX;
pX = pEnd->pExpr;
assert( pX!=0 );
assert( (pEnd->wtFlags & TERM_VNULL)==0 );
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
testcase( pEnd->wtFlags & TERM_VIRTUAL );
memEndValue = ++pParse->nMem;
sqlite3ExprCode(pParse, pX->pRight, memEndValue);
if( pX->op==TK_LT || pX->op==TK_GT ){
testOp = bRev ? OP_Le : OP_Ge;
}else{
testOp = bRev ? OP_Lt : OP_Gt;
}
|
| ︙ | ︙ | |||
108006 108007 108008 108009 108010 108011 108012 |
}
/* Generate code to evaluate all constraint terms using == or IN
** and store the values of those terms in an array of registers
** starting at regBase.
*/
regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
| | | 108191 108192 108193 108194 108195 108196 108197 108198 108199 108200 108201 108202 108203 108204 108205 |
}
/* Generate code to evaluate all constraint terms using == or IN
** and store the values of those terms in an array of registers
** starting at regBase.
*/
regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
zEndAff = sqlite3DbStrDup(db, zStartAff);
addrNxt = pLevel->addrNxt;
/* If we are doing a reverse order scan on an ascending index, or
** a forward order scan on a descending index, interchange the
** start and end terms (pRangeStart and pRangeEnd).
*/
if( (nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC))
|
| ︙ | ︙ | |||
108047 108048 108049 108050 108051 108052 108053 |
zStartAff[nEq] = SQLITE_AFF_NONE;
}
if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
zStartAff[nEq] = SQLITE_AFF_NONE;
}
}
nConstraint++;
| | | 108232 108233 108234 108235 108236 108237 108238 108239 108240 108241 108242 108243 108244 108245 108246 |
zStartAff[nEq] = SQLITE_AFF_NONE;
}
if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
zStartAff[nEq] = SQLITE_AFF_NONE;
}
}
nConstraint++;
testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
}else if( isMinQuery ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
nConstraint++;
startEq = 0;
start_constraints = 1;
}
codeApplyAffinity(pParse, regBase, nConstraint, zStartAff);
|
| ︙ | ︙ | |||
108089 108090 108091 108092 108093 108094 108095 |
}
if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
zEndAff[nEq] = SQLITE_AFF_NONE;
}
}
codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
nConstraint++;
| | | | | 108274 108275 108276 108277 108278 108279 108280 108281 108282 108283 108284 108285 108286 108287 108288 108289 108290 108291 |
}
if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){
zEndAff[nEq] = SQLITE_AFF_NONE;
}
}
codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
nConstraint++;
testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
}
sqlite3DbFree(db, zStartAff);
sqlite3DbFree(db, zEndAff);
/* Top of the loop body */
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
/* Check if the index cursor is past the end of the range. */
op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
testcase( op==OP_Noop );
|
| ︙ | ︙ | |||
108219 108220 108221 108222 108223 108224 108225 |
** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
*/
if( pWInfo->nLevel>1 ){
int nNotReady; /* The number of notReady tables */
struct SrcList_item *origSrc; /* Original list of tables */
nNotReady = pWInfo->nLevel - iLevel - 1;
| | | 108404 108405 108406 108407 108408 108409 108410 108411 108412 108413 108414 108415 108416 108417 108418 |
** by this loop in the a[0] slot and all notReady tables in a[1..] slots.
** This becomes the SrcList in the recursive call to sqlite3WhereBegin().
*/
if( pWInfo->nLevel>1 ){
int nNotReady; /* The number of notReady tables */
struct SrcList_item *origSrc; /* Original list of tables */
nNotReady = pWInfo->nLevel - iLevel - 1;
pOrTab = sqlite3StackAllocRaw(db,
sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
if( pOrTab==0 ) return notReady;
pOrTab->nAlloc = (u8)(nNotReady + 1);
pOrTab->nSrc = pOrTab->nAlloc;
memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
origSrc = pWInfo->pTabList->a;
for(k=1; k<=nNotReady; k++){
|
| ︙ | ︙ | |||
108273 108274 108275 108276 108277 108278 108279 |
int iTerm;
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
Expr *pExpr = pWC->a[iTerm].pExpr;
if( &pWC->a[iTerm] == pTerm ) continue;
if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
| | | | | 108458 108459 108460 108461 108462 108463 108464 108465 108466 108467 108468 108469 108470 108471 108472 108473 108474 108475 108476 108477 108478 108479 108480 108481 108482 108483 108484 108485 108486 108487 108488 108489 108490 108491 108492 108493 |
int iTerm;
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
Expr *pExpr = pWC->a[iTerm].pExpr;
if( &pWC->a[iTerm] == pTerm ) continue;
if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
pExpr = sqlite3ExprDup(db, pExpr, 0);
pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
}
if( pAndExpr ){
pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
}
}
for(ii=0; ii<pOrWc->nTerm; ii++){
WhereTerm *pOrTerm = &pOrWc->a[ii];
if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
Expr *pOrExpr = pOrTerm->pExpr;
if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
pAndExpr->pLeft = pOrExpr;
pOrExpr = pAndExpr;
}
/* Loop through table entries that match term pOrTerm. */
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
assert( pSubWInfo || pParse->nErr || db->mallocFailed );
if( pSubWInfo ){
WhereLoop *pSubLoop;
explainOneScan(
pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
);
if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
|
| ︙ | ︙ | |||
108349 108350 108351 108352 108353 108354 108355 |
}
}
}
pLevel->u.pCovidx = pCov;
if( pCov ) pLevel->iIdxCur = iCovCur;
if( pAndExpr ){
pAndExpr->pLeft = 0;
| | | < < < < | | 108534 108535 108536 108537 108538 108539 108540 108541 108542 108543 108544 108545 108546 108547 108548 108549 108550 108551 108552 108553 108554 108555 108556 108557 108558 108559 108560 108561 108562 108563 108564 108565 108566 108567 108568 108569 108570 108571 108572 108573 108574 108575 108576 108577 108578 |
}
}
}
pLevel->u.pCovidx = pCov;
if( pCov ) pLevel->iIdxCur = iCovCur;
if( pAndExpr ){
pAndExpr->pLeft = 0;
sqlite3ExprDelete(db, pAndExpr);
}
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
sqlite3VdbeResolveLabel(v, iLoopBody);
if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
if( !untestedTerms ) disableTerm(pLevel, pTerm);
}else
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
{
/* Case 6: There is no usable index. We must do a complete
** scan of the entire table.
*/
static const u8 aStep[] = { OP_Next, OP_Prev };
static const u8 aStart[] = { OP_Rewind, OP_Last };
assert( bRev==0 || bRev==1 );
pLevel->op = aStep[bRev];
pLevel->p1 = iCur;
pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}
newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
/* Insert code to test every subexpression that can be completely
** computed using the current set of tables.
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
Expr *pE;
testcase( pTerm->wtFlags & TERM_VIRTUAL );
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( (pTerm->prereqAll & newNotReady)!=0 ){
testcase( pWInfo->untestedTerms==0
&& (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
pWInfo->untestedTerms = 1;
continue;
|
| ︙ | ︙ | |||
108410 108411 108412 108413 108414 108415 108416 |
**
** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
** and we are coding the t1 loop and the t2 loop has not yet coded,
** then we cannot use the "t1.a=t2.b" constraint, but we can code
** the implied "t1.a=123" constraint.
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
| | < > > | | | > > | | 108591 108592 108593 108594 108595 108596 108597 108598 108599 108600 108601 108602 108603 108604 108605 108606 108607 108608 108609 108610 108611 108612 108613 108614 108615 108616 108617 108618 108619 108620 108621 108622 108623 108624 108625 108626 108627 108628 108629 108630 108631 108632 108633 108634 108635 108636 108637 108638 |
**
** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
** and we are coding the t1 loop and the t2 loop has not yet coded,
** then we cannot use the "t1.a=t2.b" constraint, but we can code
** the implied "t1.a=123" constraint.
*/
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
Expr *pE, *pEAlt;
WhereTerm *pAlt;
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
if( pTerm->leftCursor!=iCur ) continue;
if( pLevel->iLeftJoin ) continue;
pE = pTerm->pExpr;
assert( !ExprHasProperty(pE, EP_FromJoin) );
assert( (pTerm->prereqRight & newNotReady)!=0 );
pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
if( pAlt==0 ) continue;
if( pAlt->wtFlags & (TERM_CODED) ) continue;
testcase( pAlt->eOperator & WO_EQ );
testcase( pAlt->eOperator & WO_IN );
VdbeNoopComment((v, "begin transitive constraint"));
pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
if( pEAlt ){
*pEAlt = *pAlt->pExpr;
pEAlt->pLeft = pE->pLeft;
sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
sqlite3StackFree(db, pEAlt);
}
}
/* For a LEFT OUTER JOIN, generate code that will record the fact that
** at least one row of the right table has matched the left table.
*/
if( pLevel->iLeftJoin ){
pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
VdbeComment((v, "record LEFT JOIN hit"));
sqlite3ExprCacheClear(pParse);
for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
testcase( pTerm->wtFlags & TERM_VIRTUAL );
testcase( pTerm->wtFlags & TERM_CODED );
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
if( (pTerm->prereqAll & newNotReady)!=0 ){
assert( pWInfo->untestedTerms );
continue;
}
assert( pTerm->pExpr );
|
| ︙ | ︙ | |||
108881 108882 108883 108884 108885 108886 108887 |
testcase( pTerm->eOperator & WO_EQ );
testcase( pTerm->eOperator & WO_ISNULL );
rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
}else if( (pTerm->eOperator & WO_IN)
&& !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
}
| > | | 109065 109066 109067 109068 109069 109070 109071 109072 109073 109074 109075 109076 109077 109078 109079 109080 |
testcase( pTerm->eOperator & WO_EQ );
testcase( pTerm->eOperator & WO_ISNULL );
rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
}else if( (pTerm->eOperator & WO_IN)
&& !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
}
assert( nOut==0 || rc==SQLITE_OK );
if( nOut ) pNew->nOut = whereCost(nOut);
}
#endif
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
/* Each row involves a step of the index, then a binary search of
** the main table */
pNew->rRun = whereCostAdd(pNew->rRun, rLogSize>27 ? rLogSize-17 : 10);
}
|
| ︙ | ︙ | |||
108953 108954 108955 108956 108957 108958 108959 108960 108961 108962 108963 108964 108965 108966 |
testcase( x==BMS-1 );
testcase( x==BMS-2 );
if( x<BMS-1 ) m |= MASKBIT(x);
}
return m;
}
/*
** Add all WhereLoop objects for a single table of the join where the table
** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
** a b-tree table, not a virtual table.
*/
static int whereLoopAddBtree(
| > > > > > > > > > > > | 109138 109139 109140 109141 109142 109143 109144 109145 109146 109147 109148 109149 109150 109151 109152 109153 109154 109155 109156 109157 109158 109159 109160 109161 109162 |
testcase( x==BMS-1 );
testcase( x==BMS-2 );
if( x<BMS-1 ) m |= MASKBIT(x);
}
return m;
}
/* Check to see if a partial index with pPartIndexWhere can be used
** in the current query. Return true if it can be and false if not.
*/
static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
int i;
WhereTerm *pTerm;
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
}
return 0;
}
/*
** Add all WhereLoop objects for a single table of the join where the table
** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
** a b-tree table, not a virtual table.
*/
static int whereLoopAddBtree(
|
| ︙ | ︙ | |||
108976 108977 108978 108979 108980 108981 108982 108983 108984 108985 108986 108987 108988 108989 108990 108991 108992 108993 108994 |
struct SrcList_item *pSrc; /* The FROM clause btree term to add */
WhereLoop *pNew; /* Template WhereLoop object */
int rc = SQLITE_OK; /* Return code */
int iSortIdx = 1; /* Index number */
int b; /* A boolean value */
WhereCost rSize; /* number of rows in the table */
WhereCost rLogSize; /* Logarithm of the number of rows in the table */
pNew = pBuilder->pNew;
pWInfo = pBuilder->pWInfo;
pTabList = pWInfo->pTabList;
pSrc = pTabList->a + pNew->iTab;
assert( !IsVirtual(pSrc->pTab) );
if( pSrc->pIndex ){
/* An INDEXED BY clause specifies a particular index to use */
pProbe = pSrc->pIndex;
}else{
/* There is no INDEXED BY clause. Create a fake Index object in local
| > > | 109172 109173 109174 109175 109176 109177 109178 109179 109180 109181 109182 109183 109184 109185 109186 109187 109188 109189 109190 109191 109192 |
struct SrcList_item *pSrc; /* The FROM clause btree term to add */
WhereLoop *pNew; /* Template WhereLoop object */
int rc = SQLITE_OK; /* Return code */
int iSortIdx = 1; /* Index number */
int b; /* A boolean value */
WhereCost rSize; /* number of rows in the table */
WhereCost rLogSize; /* Logarithm of the number of rows in the table */
WhereClause *pWC; /* The parsed WHERE clause */
pNew = pBuilder->pNew;
pWInfo = pBuilder->pWInfo;
pTabList = pWInfo->pTabList;
pSrc = pTabList->a + pNew->iTab;
pWC = pBuilder->pWC;
assert( !IsVirtual(pSrc->pTab) );
if( pSrc->pIndex ){
/* An INDEXED BY clause specifies a particular index to use */
pProbe = pSrc->pIndex;
}else{
/* There is no INDEXED BY clause. Create a fake Index object in local
|
| ︙ | ︙ | |||
109020 109021 109022 109023 109024 109025 109026 |
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
&& pSrc->pIndex==0
&& !pSrc->viaCoroutine
&& !pSrc->notIndexed
&& !pSrc->isCorrelated
){
/* Generate auto-index WhereLoops */
| < | 109218 109219 109220 109221 109222 109223 109224 109225 109226 109227 109228 109229 109230 109231 |
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
&& pSrc->pIndex==0
&& !pSrc->viaCoroutine
&& !pSrc->notIndexed
&& !pSrc->isCorrelated
){
/* Generate auto-index WhereLoops */
WhereTerm *pTerm;
WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
if( pTerm->prereqRight & pNew->maskSelf ) continue;
if( termCanDriveIndex(pTerm, pSrc, 0) ){
pNew->u.btree.nEq = 1;
pNew->u.btree.pIndex = 0;
|
| ︙ | ︙ | |||
109050 109051 109052 109053 109054 109055 109056 109057 109058 109059 109060 109061 109062 109063 |
}
}
}
/* Loop over all indices
*/
for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
pNew->u.btree.nEq = 0;
pNew->nLTerm = 0;
pNew->iSortIdx = 0;
pNew->rSetup = 0;
pNew->prereq = mExtra;
pNew->nOut = rSize;
pNew->u.btree.pIndex = pProbe;
| > > > > | 109247 109248 109249 109250 109251 109252 109253 109254 109255 109256 109257 109258 109259 109260 109261 109262 109263 109264 |
}
}
}
/* Loop over all indices
*/
for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
if( pProbe->pPartIdxWhere!=0
&& !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
continue; /* Partial index inappropriate for this query */
}
pNew->u.btree.nEq = 0;
pNew->nLTerm = 0;
pNew->iSortIdx = 0;
pNew->rSetup = 0;
pNew->prereq = mExtra;
pNew->nOut = rSize;
pNew->u.btree.pIndex = pProbe;
|
| ︙ | ︙ | |||
109990 109991 109992 109993 109994 109995 109996 |
pLoop->aLTerm[0] = pTerm;
pLoop->nLTerm = 1;
pLoop->u.btree.nEq = 1;
/* TUNING: Cost of a rowid lookup is 10 */
pLoop->rRun = 33; /* 33==whereCost(10) */
}else{
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
| | | 110191 110192 110193 110194 110195 110196 110197 110198 110199 110200 110201 110202 110203 110204 110205 |
pLoop->aLTerm[0] = pTerm;
pLoop->nLTerm = 1;
pLoop->u.btree.nEq = 1;
/* TUNING: Cost of a rowid lookup is 10 */
pLoop->rRun = 33; /* 33==whereCost(10) */
}else{
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None || pIdx->pPartIdxWhere!=0 ) continue;
for(j=0; j<pIdx->nColumn; j++){
pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
if( pTerm==0 ) break;
whereLoopResize(pWInfo->pParse->db, pLoop, j);
pLoop->aLTerm[j] = pTerm;
}
if( j!=pIdx->nColumn ) continue;
|
| ︙ | ︙ | |||
110196 110197 110198 110199 110200 110201 110202 | /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. */ initMaskSet(pMaskSet); whereClauseInit(&pWInfo->sWC, pWInfo); sqlite3ExprCodeConstants(pParse, pWhere); | | | 110397 110398 110399 110400 110401 110402 110403 110404 110405 110406 110407 110408 110409 110410 110411 |
/* Split the WHERE clause into separate subexpressions where each
** subexpression is separated by an AND operator.
*/
initMaskSet(pMaskSet);
whereClauseInit(&pWInfo->sWC, pWInfo);
sqlite3ExprCodeConstants(pParse, pWhere);
whereSplit(&pWInfo->sWC, pWhere, TK_AND);
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
/* Special case: a WHERE clause that is constant. Evaluate the
** expression and either jump over all of the code or fall thru.
*/
if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
|
| ︙ | ︙ | |||
110830 110831 110832 110833 110834 110835 110836 | #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse | | | 111031 111032 111033 111034 111035 111036 111037 111038 111039 111040 111041 111042 111043 111044 111045 | #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse #define YYNSTATE 628 #define YYNRULE 327 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) /* The yyzerominor constant is used to initialize instances of |
| ︙ | ︙ | |||
110903 110904 110905 110906 110907 110908 110909 |
** shifting terminals.
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
#define YY_ACTTAB_COUNT (1564)
static const YYACTIONTYPE yy_action[] = {
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 111104 111105 111106 111107 111108 111109 111110 111111 111112 111113 111114 111115 111116 111117 111118 111119 111120 111121 111122 111123 111124 111125 111126 111127 111128 111129 111130 111131 111132 111133 111134 111135 111136 111137 111138 111139 111140 111141 111142 111143 111144 111145 111146 111147 111148 111149 111150 111151 111152 111153 111154 111155 111156 111157 111158 111159 111160 111161 111162 111163 111164 111165 111166 111167 111168 111169 111170 111171 111172 111173 111174 111175 111176 111177 111178 111179 111180 111181 111182 111183 111184 111185 111186 111187 111188 111189 111190 111191 111192 111193 111194 111195 111196 111197 111198 111199 111200 111201 111202 111203 111204 111205 111206 111207 111208 111209 111210 111211 111212 111213 111214 111215 111216 111217 111218 111219 111220 111221 111222 111223 111224 111225 111226 111227 111228 111229 111230 111231 111232 111233 111234 111235 111236 111237 111238 111239 111240 111241 111242 111243 111244 111245 111246 111247 111248 111249 111250 111251 111252 111253 111254 111255 111256 111257 111258 111259 111260 111261 111262 111263 111264 111265 111266 111267 111268 111269 111270 111271 111272 111273 111274 |
** shifting terminals.
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
#define YY_ACTTAB_COUNT (1564)
static const YYACTIONTYPE yy_action[] = {
/* 0 */ 310, 956, 184, 418, 2, 171, 625, 595, 56, 56,
/* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
/* 20 */ 52, 52, 51, 233, 621, 620, 299, 621, 620, 234,
/* 30 */ 588, 582, 56, 56, 56, 56, 19, 54, 54, 54,
/* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 606, 57,
/* 50 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
/* 60 */ 56, 56, 542, 54, 54, 54, 54, 53, 53, 52,
/* 70 */ 52, 52, 51, 233, 310, 595, 326, 196, 195, 194,
/* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 90 */ 51, 233, 618, 617, 165, 618, 617, 381, 378, 377,
/* 100 */ 408, 533, 577, 577, 588, 582, 304, 423, 376, 59,
/* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
/* 120 */ 575, 546, 65, 57, 58, 48, 580, 579, 581, 581,
/* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
/* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 223,
/* 150 */ 540, 421, 170, 176, 138, 281, 384, 276, 383, 168,
/* 160 */ 490, 552, 410, 669, 621, 620, 272, 439, 410, 439,
/* 170 */ 551, 605, 67, 483, 508, 619, 600, 413, 588, 582,
/* 180 */ 601, 484, 619, 413, 619, 599, 91, 440, 441, 440,
/* 190 */ 336, 599, 73, 670, 222, 267, 481, 57, 58, 48,
/* 200 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
/* 210 */ 671, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 220 */ 51, 233, 310, 280, 232, 231, 1, 132, 200, 386,
/* 230 */ 621, 620, 618, 617, 279, 436, 290, 564, 175, 263,
/* 240 */ 410, 265, 438, 498, 437, 166, 442, 569, 337, 569,
/* 250 */ 201, 538, 588, 582, 600, 413, 165, 595, 601, 381,
/* 260 */ 378, 377, 598, 599, 92, 524, 619, 570, 570, 593,
/* 270 */ 376, 57, 58, 48, 580, 579, 581, 581, 55, 55,
/* 280 */ 56, 56, 56, 56, 598, 54, 54, 54, 54, 53,
/* 290 */ 53, 52, 52, 52, 51, 233, 310, 464, 618, 617,
/* 300 */ 591, 591, 591, 174, 273, 397, 410, 273, 410, 549,
/* 310 */ 398, 621, 620, 68, 327, 621, 620, 621, 620, 619,
/* 320 */ 547, 413, 619, 413, 472, 595, 588, 582, 473, 599,
/* 330 */ 92, 599, 92, 52, 52, 52, 51, 233, 514, 513,
/* 340 */ 206, 323, 364, 465, 221, 57, 58, 48, 580, 579,
/* 350 */ 581, 581, 55, 55, 56, 56, 56, 56, 530, 54,
/* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 370 */ 310, 397, 410, 397, 598, 373, 387, 531, 348, 618,
/* 380 */ 617, 576, 202, 618, 617, 618, 617, 413, 621, 620,
/* 390 */ 145, 255, 347, 254, 578, 599, 74, 352, 45, 490,
/* 400 */ 588, 582, 235, 189, 465, 545, 167, 297, 187, 470,
/* 410 */ 480, 67, 62, 39, 619, 547, 598, 346, 574, 57,
/* 420 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
/* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
/* 440 */ 52, 52, 51, 233, 310, 563, 559, 408, 529, 577,
/* 450 */ 577, 345, 255, 347, 254, 182, 618, 617, 504, 505,
/* 460 */ 315, 410, 558, 235, 166, 272, 410, 353, 565, 181,
/* 470 */ 408, 547, 577, 577, 588, 582, 413, 538, 557, 562,
/* 480 */ 518, 413, 619, 249, 599, 16, 7, 36, 468, 599,
/* 490 */ 92, 517, 619, 57, 58, 48, 580, 579, 581, 581,
/* 500 */ 55, 55, 56, 56, 56, 56, 542, 54, 54, 54,
/* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 328,
/* 520 */ 573, 572, 526, 559, 561, 395, 872, 246, 410, 248,
/* 530 */ 171, 393, 595, 219, 408, 410, 577, 577, 503, 558,
/* 540 */ 365, 145, 511, 413, 408, 229, 577, 577, 588, 582,
/* 550 */ 413, 599, 92, 382, 270, 557, 166, 401, 599, 69,
/* 560 */ 502, 420, 946, 199, 946, 198, 547, 57, 58, 48,
/* 570 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
/* 580 */ 569, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 590 */ 51, 233, 310, 318, 420, 945, 509, 945, 309, 598,
/* 600 */ 595, 566, 491, 212, 173, 247, 424, 616, 615, 614,
/* 610 */ 324, 197, 143, 406, 573, 572, 490, 66, 50, 47,
/* 620 */ 146, 595, 588, 582, 232, 231, 560, 428, 67, 556,
/* 630 */ 15, 619, 186, 544, 304, 422, 35, 206, 433, 424,
/* 640 */ 553, 57, 58, 48, 580, 579, 581, 581, 55, 55,
/* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
/* 660 */ 53, 52, 52, 52, 51, 233, 310, 570, 570, 261,
/* 670 */ 269, 598, 12, 374, 569, 166, 410, 314, 410, 421,
/* 680 */ 410, 474, 474, 366, 619, 50, 47, 146, 598, 595,
/* 690 */ 256, 413, 166, 413, 352, 413, 588, 582, 32, 599,
/* 700 */ 94, 599, 97, 599, 95, 628, 626, 330, 142, 50,
/* 710 */ 47, 146, 334, 350, 359, 57, 58, 48, 580, 579,
/* 720 */ 581, 581, 55, 55, 56, 56, 56, 56, 410, 54,
/* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 740 */ 310, 410, 389, 413, 410, 22, 566, 405, 212, 363,
/* 750 */ 390, 599, 104, 360, 410, 156, 413, 410, 604, 413,
/* 760 */ 538, 332, 570, 570, 599, 103, 494, 599, 105, 413,
/* 770 */ 588, 582, 413, 261, 550, 619, 11, 599, 106, 522,
/* 780 */ 599, 133, 169, 458, 457, 170, 35, 602, 619, 57,
/* 790 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
/* 800 */ 56, 56, 410, 54, 54, 54, 54, 53, 53, 52,
/* 810 */ 52, 52, 51, 233, 310, 410, 260, 413, 410, 50,
/* 820 */ 47, 146, 358, 319, 356, 599, 134, 528, 353, 338,
/* 830 */ 413, 410, 357, 413, 358, 410, 358, 619, 599, 98,
/* 840 */ 129, 599, 102, 619, 588, 582, 413, 21, 235, 619,
/* 850 */ 413, 619, 211, 143, 599, 101, 30, 167, 599, 93,
/* 860 */ 351, 536, 203, 57, 58, 48, 580, 579, 581, 581,
/* 870 */ 55, 55, 56, 56, 56, 56, 410, 54, 54, 54,
/* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 410,
/* 890 */ 527, 413, 410, 426, 215, 306, 598, 552, 141, 599,
/* 900 */ 100, 40, 410, 38, 413, 410, 551, 413, 410, 228,
/* 910 */ 220, 315, 599, 77, 501, 599, 96, 413, 588, 582,
/* 920 */ 413, 339, 253, 413, 218, 599, 137, 380, 599, 136,
/* 930 */ 28, 599, 135, 271, 716, 210, 482, 57, 58, 48,
/* 940 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
/* 950 */ 410, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 960 */ 51, 233, 310, 410, 273, 413, 410, 316, 147, 598,
/* 970 */ 273, 627, 2, 599, 76, 209, 410, 127, 413, 619,
/* 980 */ 126, 413, 410, 622, 235, 619, 599, 90, 375, 599,
/* 990 */ 89, 413, 588, 582, 27, 261, 351, 413, 619, 599,
/* 1000 */ 75, 322, 542, 542, 125, 599, 88, 321, 279, 598,
/* 1010 */ 619, 57, 46, 48, 580, 579, 581, 581, 55, 55,
/* 1020 */ 56, 56, 56, 56, 410, 54, 54, 54, 54, 53,
/* 1030 */ 53, 52, 52, 52, 51, 233, 310, 410, 451, 413,
/* 1040 */ 164, 285, 283, 273, 610, 425, 305, 599, 87, 371,
/* 1050 */ 410, 478, 413, 410, 609, 410, 608, 603, 619, 619,
/* 1060 */ 599, 99, 587, 586, 122, 413, 588, 582, 413, 619,
/* 1070 */ 413, 619, 619, 599, 86, 367, 599, 17, 599, 85,
/* 1080 */ 320, 185, 520, 519, 584, 583, 58, 48, 580, 579,
/* 1090 */ 581, 581, 55, 55, 56, 56, 56, 56, 410, 54,
/* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 1110 */ 310, 585, 410, 413, 410, 261, 261, 261, 409, 592,
/* 1120 */ 475, 599, 84, 170, 410, 467, 519, 413, 121, 413,
/* 1130 */ 619, 619, 619, 619, 619, 599, 83, 599, 72, 413,
/* 1140 */ 588, 582, 51, 233, 626, 330, 471, 599, 71, 258,
/* 1150 */ 159, 120, 14, 463, 157, 158, 117, 261, 449, 448,
/* 1160 */ 447, 48, 580, 579, 581, 581, 55, 55, 56, 56,
/* 1170 */ 56, 56, 619, 54, 54, 54, 54, 53, 53, 52,
/* 1180 */ 52, 52, 51, 233, 44, 404, 261, 3, 410, 460,
/* 1190 */ 261, 414, 620, 118, 399, 10, 25, 24, 555, 349,
/* 1200 */ 217, 619, 407, 413, 410, 619, 4, 44, 404, 619,
/* 1210 */ 3, 599, 82, 619, 414, 620, 456, 543, 115, 413,
/* 1220 */ 539, 402, 537, 275, 507, 407, 251, 599, 81, 216,
/* 1230 */ 274, 564, 619, 243, 454, 619, 154, 619, 619, 619,
/* 1240 */ 450, 417, 624, 110, 402, 619, 410, 236, 64, 123,
/* 1250 */ 488, 41, 42, 532, 564, 204, 410, 268, 43, 412,
/* 1260 */ 411, 413, 266, 593, 108, 619, 107, 435, 333, 599,
/* 1270 */ 80, 413, 619, 264, 41, 42, 444, 619, 410, 599,
/* 1280 */ 70, 43, 412, 411, 434, 262, 593, 149, 619, 598,
/* 1290 */ 257, 237, 188, 413, 591, 591, 591, 590, 589, 13,
/* 1300 */ 619, 599, 18, 329, 235, 619, 44, 404, 361, 3,
/* 1310 */ 419, 462, 340, 414, 620, 227, 124, 591, 591, 591,
/* 1320 */ 590, 589, 13, 619, 407, 410, 619, 410, 139, 34,
/* 1330 */ 404, 388, 3, 148, 623, 313, 414, 620, 312, 331,
/* 1340 */ 413, 461, 413, 402, 180, 354, 413, 407, 599, 79,
/* 1350 */ 599, 78, 250, 564, 599, 9, 619, 613, 612, 611,
/* 1360 */ 619, 8, 453, 443, 242, 416, 402, 619, 239, 235,
/* 1370 */ 179, 238, 429, 41, 42, 289, 564, 619, 619, 619,
/* 1380 */ 43, 412, 411, 619, 144, 593, 619, 619, 177, 61,
/* 1390 */ 619, 597, 392, 621, 620, 288, 41, 42, 415, 619,
/* 1400 */ 294, 30, 394, 43, 412, 411, 293, 619, 593, 31,
/* 1410 */ 619, 396, 292, 60, 230, 37, 591, 591, 591, 590,
/* 1420 */ 589, 13, 214, 554, 183, 291, 172, 302, 301, 300,
/* 1430 */ 178, 298, 596, 564, 452, 29, 286, 391, 541, 591,
/* 1440 */ 591, 591, 590, 589, 13, 284, 521, 535, 150, 534,
/* 1450 */ 241, 282, 385, 192, 191, 325, 516, 515, 277, 240,
/* 1460 */ 511, 524, 308, 512, 128, 593, 510, 225, 226, 487,
/* 1470 */ 486, 224, 152, 492, 465, 307, 485, 163, 153, 372,
/* 1480 */ 479, 151, 162, 259, 370, 161, 368, 208, 476, 477,
/* 1490 */ 26, 160, 469, 466, 362, 140, 591, 591, 591, 116,
/* 1500 */ 119, 455, 344, 155, 114, 343, 113, 112, 446, 111,
/* 1510 */ 131, 109, 432, 317, 130, 431, 23, 20, 430, 427,
/* 1520 */ 190, 63, 255, 342, 244, 607, 295, 287, 311, 594,
/* 1530 */ 278, 508, 496, 235, 493, 571, 497, 568, 495, 403,
/* 1540 */ 459, 379, 355, 245, 193, 303, 567, 296, 341, 5,
/* 1550 */ 445, 548, 506, 207, 525, 500, 335, 489, 252, 369,
/* 1560 */ 400, 499, 523, 233,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
/* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
/* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
/* 30 */ 49, 50, 77, 78, 79, 80, 204, 82, 83, 84,
/* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 23, 68,
|
| ︙ | ︙ | |||
111211 111212 111213 111214 111215 111216 111217 | /* 1420 */ 133, 134, 5, 157, 157, 202, 118, 10, 11, 12, /* 1430 */ 13, 14, 203, 66, 17, 104, 210, 121, 211, 129, /* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211, /* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42, /* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175, /* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18, /* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157, | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 111412 111413 111414 111415 111416 111417 111418 111419 111420 111421 111422 111423 111424 111425 111426 111427 111428 111429 111430 111431 111432 111433 111434 111435 111436 111437 111438 111439 111440 111441 111442 111443 111444 111445 111446 111447 111448 111449 111450 111451 111452 111453 111454 111455 111456 111457 111458 111459 111460 111461 111462 111463 111464 111465 111466 111467 111468 111469 111470 111471 111472 111473 111474 111475 111476 111477 111478 111479 111480 111481 111482 111483 111484 111485 111486 111487 111488 111489 111490 111491 111492 111493 111494 111495 111496 111497 111498 111499 111500 111501 111502 111503 111504 111505 111506 111507 111508 111509 111510 111511 111512 111513 111514 111515 111516 111517 111518 111519 111520 111521 111522 111523 111524 111525 111526 111527 111528 111529 111530 111531 111532 111533 111534 111535 111536 111537 111538 111539 111540 111541 111542 111543 111544 111545 111546 111547 111548 111549 111550 111551 111552 111553 111554 111555 111556 111557 111558 111559 111560 111561 111562 111563 111564 111565 111566 111567 111568 111569 111570 111571 111572 111573 111574 111575 111576 111577 111578 111579 111580 111581 111582 111583 |
/* 1420 */ 133, 134, 5, 157, 157, 202, 118, 10, 11, 12,
/* 1430 */ 13, 14, 203, 66, 17, 104, 210, 121, 211, 129,
/* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
/* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
/* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
/* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
/* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
/* 1490 */ 135, 156, 199, 189, 157, 68, 129, 130, 131, 22,
/* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
/* 1510 */ 218, 189, 40, 157, 218, 157, 240, 240, 157, 38,
/* 1520 */ 196, 243, 105, 106, 107, 153, 198, 209, 111, 166,
/* 1530 */ 176, 181, 166, 116, 166, 230, 176, 230, 176, 226,
/* 1540 */ 199, 177, 239, 209, 185, 148, 166, 195, 209, 196,
/* 1550 */ 199, 208, 182, 233, 173, 182, 139, 186, 239, 234,
/* 1560 */ 191, 182, 173, 92,
};
#define YY_SHIFT_USE_DFLT (-70)
#define YY_SHIFT_COUNT (417)
#define YY_SHIFT_MIN (-69)
#define YY_SHIFT_MAX (1487)
static const short yy_shift_ofst[] = {
/* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
/* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
/* 20 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 30 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 40 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287,
/* 50 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 60 */ 1287, 1287, 286, 362, 362, 538, 538, 231, 1253, 55,
/* 70 */ 721, 647, 573, 499, 425, 351, 277, 203, 869, 869,
/* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
/* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
/* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
/* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
/* 130 */ 732, 868, 231, 1051, 1471, -70, -70, -70, 1367, 57,
/* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
/* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
/* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
/* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
/* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
/* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
/* 230 */ 766, 633, 633, 231, 284, 63, 608, 1481, 1308, 1308,
/* 240 */ 1472, 1472, 1308, 1477, 1427, 1275, 1487, 1487, 1487, 1487,
/* 250 */ 1308, 1461, 1275, 1477, 1427, 1427, 1275, 1308, 1461, 1355,
/* 260 */ 1441, 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348,
/* 270 */ 1348, 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408,
/* 280 */ 1348, 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308,
/* 290 */ 1280, 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346,
/* 300 */ 1338, 1338, 1338, 1338, -70, -70, -70, -70, -70, -70,
/* 310 */ 1013, 467, 612, 84, 179, -28, 870, 410, 761, 760,
/* 320 */ 667, 650, 531, 220, 361, 331, 125, 127, 97, 1306,
/* 330 */ 1300, 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174,
/* 340 */ 1139, 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184,
/* 350 */ 1174, 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152,
/* 360 */ 1147, 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960,
/* 370 */ 1057, 1031, 1030, 899, 938, 982, 936, 972, 958, 910,
/* 380 */ 955, 875, 885, 908, 857, 859, 867, 804, 590, 834,
/* 390 */ 747, 818, 513, 611, 741, 673, 637, 611, 606, 603,
/* 400 */ 579, 501, 541, 468, 386, 445, 395, 376, 281, 185,
/* 410 */ 120, 92, 75, 45, 114, 25, 11, 5,
};
#define YY_REDUCE_USE_DFLT (-169)
#define YY_REDUCE_COUNT (309)
#define YY_REDUCE_MIN (-168)
#define YY_REDUCE_MAX (1397)
static const short yy_reduce_ofst[] = {
/* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
/* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
/* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
/* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
/* 40 */ 800, 758, 755, 752, 742, 739, 726, 685, 681, 668,
/* 50 */ 665, 652, 607, 604, 594, 591, 578, 530, 528, 526,
/* 60 */ 385, 18, 477, 466, 519, 444, 350, 435, 405, 488,
/* 70 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 80 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 90 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 100 */ 488, 488, 488, 488, 488, 488, 488, 1040, 678, 1036,
/* 110 */ 1007, 967, 966, 965, 845, 686, 610, 684, 317, 672,
/* 120 */ 893, 327, 623, 522, -7, 820, 814, 157, 154, 101,
/* 130 */ 702, 494, 580, 488, 488, 488, 488, 488, 614, 586,
/* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
/* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
/* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
/* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
/* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
/* 190 */ -168, 1389, 1381, 1371, 1379, 1373, 1370, 1343, 1352, 1369,
/* 200 */ 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1325, 1320, 1352,
/* 210 */ 1352, 1343, 1380, 1353, 1397, 1351, 1339, 1334, 1319, 1341,
/* 220 */ 1303, 1364, 1359, 1368, 1362, 1366, 1360, 1350, 1354, 1318,
/* 230 */ 1313, 1307, 1305, 1363, 1328, 1324, 1372, 1278, 1361, 1358,
/* 240 */ 1277, 1276, 1356, 1296, 1322, 1309, 1317, 1315, 1314, 1312,
/* 250 */ 1345, 1347, 1302, 1292, 1311, 1304, 1293, 1337, 1335, 1252,
/* 260 */ 1248, 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301,
/* 270 */ 1295, 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274,
/* 280 */ 1281, 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266,
/* 290 */ 1189, 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219,
/* 300 */ 1216, 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
};
static const YYACTIONTYPE yy_default[] = {
/* 0 */ 633, 867, 955, 955, 867, 867, 955, 955, 955, 757,
/* 10 */ 955, 955, 955, 865, 955, 955, 785, 785, 929, 955,
/* 20 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 30 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 40 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 50 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 60 */ 955, 955, 955, 955, 955, 955, 955, 672, 761, 791,
/* 70 */ 955, 955, 955, 955, 955, 955, 955, 955, 928, 930,
/* 80 */ 799, 798, 908, 772, 796, 789, 793, 868, 861, 862,
/* 90 */ 860, 864, 869, 955, 792, 828, 845, 827, 839, 844,
/* 100 */ 851, 843, 840, 830, 829, 831, 832, 955, 955, 955,
/* 110 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 120 */ 955, 955, 955, 659, 726, 955, 955, 955, 955, 955,
/* 130 */ 955, 955, 955, 833, 834, 848, 847, 846, 955, 664,
/* 140 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 150 */ 935, 933, 955, 880, 955, 955, 955, 955, 955, 955,
/* 160 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 170 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 180 */ 639, 757, 757, 757, 633, 955, 955, 955, 947, 761,
/* 190 */ 751, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 200 */ 955, 955, 955, 801, 740, 918, 920, 955, 901, 738,
/* 210 */ 661, 759, 674, 749, 641, 795, 774, 774, 913, 795,
/* 220 */ 913, 697, 720, 955, 785, 955, 785, 694, 785, 774,
/* 230 */ 863, 955, 955, 955, 758, 749, 955, 940, 765, 765,
/* 240 */ 932, 932, 765, 807, 730, 795, 737, 737, 737, 737,
/* 250 */ 765, 656, 795, 807, 730, 730, 795, 765, 656, 907,
/* 260 */ 905, 765, 765, 656, 765, 656, 765, 656, 873, 728,
/* 270 */ 728, 728, 712, 877, 877, 873, 728, 697, 728, 712,
/* 280 */ 728, 728, 778, 773, 778, 773, 778, 773, 765, 765,
/* 290 */ 955, 790, 779, 788, 786, 795, 955, 715, 649, 649,
/* 300 */ 638, 638, 638, 638, 952, 952, 947, 699, 699, 682,
/* 310 */ 955, 955, 955, 955, 955, 955, 955, 882, 955, 955,
/* 320 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 330 */ 634, 942, 955, 955, 939, 955, 955, 955, 955, 800,
/* 340 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 350 */ 917, 955, 955, 955, 955, 955, 955, 955, 911, 955,
/* 360 */ 955, 955, 955, 955, 955, 904, 903, 955, 955, 955,
/* 370 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 380 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
/* 390 */ 955, 955, 955, 787, 955, 780, 955, 866, 955, 955,
/* 400 */ 955, 955, 955, 955, 955, 955, 955, 955, 743, 816,
/* 410 */ 955, 815, 819, 814, 666, 955, 647, 955, 630, 635,
/* 420 */ 951, 954, 953, 950, 949, 948, 943, 941, 938, 937,
/* 430 */ 936, 934, 931, 927, 886, 884, 891, 890, 889, 888,
/* 440 */ 887, 885, 883, 881, 802, 797, 794, 926, 879, 739,
/* 450 */ 736, 735, 655, 944, 910, 919, 806, 805, 808, 916,
/* 460 */ 915, 914, 912, 909, 896, 804, 803, 731, 871, 870,
/* 470 */ 658, 900, 899, 898, 902, 906, 897, 767, 657, 654,
/* 480 */ 663, 718, 719, 727, 725, 724, 723, 722, 721, 717,
/* 490 */ 665, 673, 711, 696, 695, 876, 878, 875, 874, 704,
/* 500 */ 703, 709, 708, 707, 706, 705, 702, 701, 700, 693,
/* 510 */ 692, 698, 691, 714, 713, 710, 690, 734, 733, 732,
/* 520 */ 729, 689, 688, 687, 819, 686, 685, 825, 824, 812,
/* 530 */ 855, 754, 753, 752, 764, 763, 776, 775, 810, 809,
/* 540 */ 777, 762, 756, 755, 771, 770, 769, 768, 760, 750,
/* 550 */ 782, 784, 783, 781, 857, 766, 854, 925, 924, 923,
/* 560 */ 922, 921, 859, 858, 826, 823, 677, 678, 894, 893,
/* 570 */ 895, 892, 680, 679, 676, 675, 856, 745, 744, 852,
/* 580 */ 849, 841, 837, 853, 850, 842, 838, 836, 835, 821,
/* 590 */ 820, 818, 817, 813, 822, 668, 746, 742, 741, 811,
/* 600 */ 748, 747, 684, 683, 681, 662, 660, 653, 651, 650,
/* 610 */ 652, 648, 646, 645, 644, 643, 642, 671, 670, 669,
/* 620 */ 667, 666, 640, 637, 636, 632, 631, 629,
};
/* The next table maps tokens into fallback tokens. If a construct
** like the following:
**
** %fallback ID X Y Z.
**
|
| ︙ | ︙ | |||
111840 111841 111842 111843 111844 111845 111846 | /* 235 */ "case_else ::=", /* 236 */ "case_operand ::= expr", /* 237 */ "case_operand ::=", /* 238 */ "exprlist ::= nexprlist", /* 239 */ "exprlist ::=", /* 240 */ "nexprlist ::= nexprlist COMMA expr", /* 241 */ "nexprlist ::= expr", | | | 112041 112042 112043 112044 112045 112046 112047 112048 112049 112050 112051 112052 112053 112054 112055 | /* 235 */ "case_else ::=", /* 236 */ "case_operand ::= expr", /* 237 */ "case_operand ::=", /* 238 */ "exprlist ::= nexprlist", /* 239 */ "exprlist ::=", /* 240 */ "nexprlist ::= nexprlist COMMA expr", /* 241 */ "nexprlist ::= expr", /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt", /* 243 */ "uniqueflag ::= UNIQUE", /* 244 */ "uniqueflag ::=", /* 245 */ "idxlist_opt ::=", /* 246 */ "idxlist_opt ::= LP idxlist RP", /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder", /* 248 */ "idxlist ::= nm collate sortorder", /* 249 */ "collate ::=", |
| ︙ | ︙ | |||
112559 112560 112561 112562 112563 112564 112565 |
{ 226, 0 },
{ 224, 1 },
{ 224, 0 },
{ 220, 1 },
{ 220, 0 },
{ 215, 3 },
{ 215, 1 },
| | | 112760 112761 112762 112763 112764 112765 112766 112767 112768 112769 112770 112771 112772 112773 112774 |
{ 226, 0 },
{ 224, 1 },
{ 224, 0 },
{ 220, 1 },
{ 220, 0 },
{ 215, 3 },
{ 215, 1 },
{ 147, 12 },
{ 227, 1 },
{ 227, 0 },
{ 178, 0 },
{ 178, 3 },
{ 187, 5 },
{ 187, 3 },
{ 228, 0 },
|
| ︙ | ︙ | |||
113563 113564 113565 113566 113567 113568 113569 |
break;
case 240: /* nexprlist ::= nexprlist COMMA expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
break;
case 241: /* nexprlist ::= expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
break;
| | | | | | 113764 113765 113766 113767 113768 113769 113770 113771 113772 113773 113774 113775 113776 113777 113778 113779 113780 113781 113782 |
break;
case 240: /* nexprlist ::= nexprlist COMMA expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
break;
case 241: /* nexprlist ::= expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
break;
case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy442, yymsp[-10].minor.yy392,
&yymsp[-11].minor.yy0, yymsp[0].minor.yy122, SQLITE_SO_ASC, yymsp[-8].minor.yy392);
}
break;
case 243: /* uniqueflag ::= UNIQUE */
case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
{yygotominor.yy392 = OE_Abort;}
break;
case 244: /* uniqueflag ::= */
|
| ︙ | ︙ | |||
114493 114494 114495 114496 114497 114498 114499 |
testcase( z[0]=='\r' );
for(i=1; sqlite3Isspace(z[i]); i++){}
*tokenType = TK_SPACE;
return i;
}
case '-': {
if( z[1]=='-' ){
| < | 114694 114695 114696 114697 114698 114699 114700 114701 114702 114703 114704 114705 114706 114707 |
testcase( z[0]=='\r' );
for(i=1; sqlite3Isspace(z[i]); i++){}
*tokenType = TK_SPACE;
return i;
}
case '-': {
if( z[1]=='-' ){
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
return i;
}
*tokenType = TK_MINUS;
return 1;
}
|
| ︙ | ︙ | |||
114526 114527 114528 114529 114530 114531 114532 |
return 1;
}
case '/': {
if( z[1]!='*' || z[2]==0 ){
*tokenType = TK_SLASH;
return 1;
}
| < | 114726 114727 114728 114729 114730 114731 114732 114733 114734 114735 114736 114737 114738 114739 |
return 1;
}
case '/': {
if( z[1]!='*' || z[2]==0 ){
*tokenType = TK_SLASH;
return 1;
}
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if( c ) i++;
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
return i;
}
case '%': {
*tokenType = TK_REM;
|
| ︙ | ︙ | |||
116371 116372 116373 116374 116375 116376 116377 116378 116379 116380 116381 116382 116383 116384 |
case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break;
case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break;
case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break;
case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break;
case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break;
case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break;
| > | 116570 116571 116572 116573 116574 116575 116576 116577 116578 116579 116580 116581 116582 116583 116584 |
case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break;
case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break;
case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break;
case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break;
case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break;
case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break;
case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break;
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break;
case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break;
|
| ︙ | ︙ | |||
117726 117727 117728 117729 117730 117731 117732 | assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->autoCommit = 1; db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | | | 117926 117927 117928 117929 117930 117931 117932 117933 117934 117935 117936 117937 117938 117939 117940 |
assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
db->autoCommit = 1;
db->nextAutovac = -1;
db->szMmap = sqlite3GlobalConfig.szMmap;
db->nextPagesize = 0;
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger
#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
| SQLITE_AutoIndex
#endif
#if SQLITE_DEFAULT_FILE_FORMAT<4
| SQLITE_LegacyFileFmt
#endif
#ifdef SQLITE_ENABLE_LOAD_EXTENSION
| SQLITE_LoadExtension
|
| ︙ | ︙ | |||
128199 128200 128201 128202 128203 128204 128205 | sqlite3_free(zCopy); return rc; } #ifdef SQLITE_TEST | | | 128399 128400 128401 128402 128403 128404 128405 128406 128407 128408 128409 128410 128411 128412 128413 | sqlite3_free(zCopy); return rc; } #ifdef SQLITE_TEST #include <tcl.h> /* #include <string.h> */ /* ** Implementation of a special SQL scalar function for testing tokenizers ** designed to be used in concert with the Tcl testing framework. This ** function must be called with two or more arguments: ** |
| ︙ | ︙ |
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
105 106 107 108 109 110 111 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.0" #define SQLITE_VERSION_NUMBER 3008000 | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.0" #define SQLITE_VERSION_NUMBER 3008000 #define SQLITE_SOURCE_ID "2013-08-05 12:31:41 4b8b426f10f8ae13bf553f7adf5ae09383fa0bd4" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
474 475 476 477 478 479 480 481 482 483 484 485 486 487 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) | > | 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | #define SQLITE_IOERR_SHMOPEN (SQLITE_IOERR | (18<<8)) #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| ︙ | ︙ | |||
2557 2558 2559 2560 2561 2562 2563 | ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** ** ^The parameter P is passed through as the only parameter to the ** callback function X. ^The parameter N is the approximate number of ** [virtual machine instructions] that are evaluated between successive | | > | 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 | ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** ** ^The parameter P is passed through as the only parameter to the ** callback function X. ^The parameter N is the approximate number of ** [virtual machine instructions] that are evaluated between successive ** invocations of the callback X. ^If N is less than one then the progress ** handler is disabled. ** ** ^Only a single progress handler may be defined at one time per ** [database connection]; setting a new progress handler cancels the ** old one. ^Setting parameter X to NULL disables the progress handler. ** ^The progress handler is also disabled by setting N to a value less ** than 1. ** |
| ︙ | ︙ | |||
4177 4178 4179 4180 4181 4182 4183 | ** registered the application defined function. */ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data ** | | | | | | > | | < | < | | | | > | | > | | | | > | < < < | | | | | | 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 | ** registered the application defined function. */ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data ** ** These functions may be used by (non-aggregate) SQL functions to ** associate metadata with argument values. If the same value is passed to ** multiple invocations of the same SQL function during query execution, under ** some circumstances the associated metadata may be preserved. An example ** of where this might be useful is in a regular-expression matching ** function. The compiled version of the regular expression can be stored as ** metadata associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata ** associated by the sqlite3_set_auxdata() function with the Nth argument ** value to the application-defined function. ^If there is no metadata ** associated with the function argument, this sqlite3_get_auxdata() interface ** returns a NULL pointer. ** ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th ** argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent ** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or ** NULL if the metadata has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly ** once, when the metadata is discarded. ** SQLite is free to discard the metadata at any time, including: <ul> ** <li> when the corresponding function parameter changes, or ** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement, or ** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or ** <li> during the original sqlite3_set_auxdata() call when a memory ** allocation error occurs. </ul>)^ ** ** Note the last bullet in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after ** sqlite3_set_auxdata() has been called. ** ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** ** These routines must be called from the same thread in which ** the SQL function is running. |
| ︙ | ︙ | |||
6264 6265 6266 6267 6268 6269 6270 | ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> | | | | | 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 | ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been ** resolved.)^ ^The highwater mark is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 |
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
655 656 657 658 659 660 661 662 663 664 665 666 667 668 |
@ border: 0;
},
{ "td.timelineTableCell",
"the format for the timeline data cells",
@ vertical-align: top;
@ text-align: left;
},
{ "span.timelineLeaf",
"the format for the timeline leaf marks",
@ font-weight: bold;
},
{ "a.timelineHistLink",
"the format for the timeline version links",
@
| > > > > > | 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 |
@ border: 0;
},
{ "td.timelineTableCell",
"the format for the timeline data cells",
@ vertical-align: top;
@ text-align: left;
},
{ "tr.timelineCurrent td.timelineTableCell",
"the format for the timeline data cell of the current checkout",
@ padding: .1em .2em;
@ border: 1px dashed #446979;
},
{ "span.timelineLeaf",
"the format for the timeline leaf marks",
@ font-weight: bold;
},
{ "a.timelineHistLink",
"the format for the timeline version links",
@
|
| ︙ | ︙ | |||
1172 1173 1174 1175 1176 1177 1178 |
}
zCap[i] = 0;
@ g.userUid = %d(g.userUid)<br />
@ g.zLogin = %h(g.zLogin)<br />
@ capabilities = %s(zCap)<br />
@ <hr>
P("HTTP_USER_AGENT");
| | > > > > > > | 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 |
}
zCap[i] = 0;
@ g.userUid = %d(g.userUid)<br />
@ g.zLogin = %h(g.zLogin)<br />
@ capabilities = %s(zCap)<br />
@ <hr>
P("HTTP_USER_AGENT");
cgi_print_all(showAll);
if( showAll && blob_size(&g.httpHeader)>0 ){
@ <hr>
@ <pre>
@ %h(blob_str(&g.httpHeader))
@ </pre>
}
if( g.perm.Setup ){
const char *zRedir = P("redirect");
if( zRedir ) cgi_redirect(zRedir);
}
style_footer();
}
|
Changes to src/sync.c.
| ︙ | ︙ | |||
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
}
if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
if( find_option("private",0,0)!=0 ){
*pSyncFlags |= SYNC_PRIVATE;
}
if( find_option("verbose","v",0)!=0 ){
*pSyncFlags |= SYNC_VERBOSE;
}
url_proxy_options();
clone_ssh_find_options();
db_find_and_open_repository(0, 0);
db_open_config(0);
if( g.argc==2 ){
if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN;
| > > > > > > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
}
if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
if( find_option("private",0,0)!=0 ){
*pSyncFlags |= SYNC_PRIVATE;
}
if( find_option("verbose","v",0)!=0 ){
*pSyncFlags |= SYNC_VERBOSE;
}
/* The --verily option to sync, push, and pull forces extra igot cards
** to be exchanged. This can overcome malfunctions in the sync protocol.
*/
if( find_option("verily",0,0)!=0 ){
*pSyncFlags |= SYNC_RESYNC;
}
url_proxy_options();
clone_ssh_find_options();
db_find_and_open_repository(0, 0);
db_open_config(0);
if( g.argc==2 ){
if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN;
|
| ︙ | ︙ |
Changes to src/tag.c.
| ︙ | ︙ | |||
346 347 348 349 350 351 352 | ** the tag value propagates to all descendants of CHECK-IN ** ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN ** ** Remove the tag TAGNAME from CHECK-IN, and also remove ** the propagation of the tag to any descendants. ** | | | > | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 | ** the tag value propagates to all descendants of CHECK-IN ** ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN ** ** Remove the tag TAGNAME from CHECK-IN, and also remove ** the propagation of the tag to any descendants. ** ** %fossil tag find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME ** ** List all objects that use TAGNAME. TYPE can be "ci" for ** checkins or "e" for events. The limit option limits the number ** of results to the given value. ** ** %fossil tag list ?--raw? ?CHECK-IN? ** ** List all tags, or if CHECK-IN is supplied, list ** all tags and their values for CHECK-IN. ** ** The option --raw allows the manipulation of all types of tags |
| ︙ | ︙ | |||
385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
** in order to import history from other scm systems
*/
void tag_cmd(void){
int n;
int fRaw = find_option("raw","",0)!=0;
int fPropagate = find_option("propagate","",0)!=0;
const char *zPrefix = fRaw ? "" : "sym-";
db_find_and_open_repository(0, 0);
if( g.argc<3 ){
goto tag_cmd_usage;
}
n = strlen(g.argv[2]);
if( n==0 ){
| > > | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
** in order to import history from other scm systems
*/
void tag_cmd(void){
int n;
int fRaw = find_option("raw","",0)!=0;
int fPropagate = find_option("propagate","",0)!=0;
const char *zPrefix = fRaw ? "" : "sym-";
char const * zFindLimit = find_option("limit","n",1);
int const nFindLimit = zFindLimit ? atoi(zFindLimit) : 0;
db_find_and_open_repository(0, 0);
if( g.argc<3 ){
goto tag_cmd_usage;
}
n = strlen(g.argv[2]);
if( n==0 ){
|
| ︙ | ︙ | |||
426 427 428 429 430 431 432 433 434 |
tag_add_artifact(zPrefix, g.argv[3], g.argv[4], 0, 0, 0, 0);
db_end_transaction(0);
}else
if( strncmp(g.argv[2],"find",n)==0 ){
Stmt q;
const char *zType = find_option("type","t",1);
if( zType==0 || zType[0]==0 ) zType = "*";
if( g.argc!=4 ){
| > | | > > > > > | > > > > > | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 |
tag_add_artifact(zPrefix, g.argv[3], g.argv[4], 0, 0, 0, 0);
db_end_transaction(0);
}else
if( strncmp(g.argv[2],"find",n)==0 ){
Stmt q;
const char *zType = find_option("type","t",1);
Blob sql = empty_blob;
if( zType==0 || zType[0]==0 ) zType = "*";
if( g.argc!=4 ){
usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
}
if( fRaw ){
blob_appendf(&sql,
"SELECT blob.uuid FROM tagxref, blob"
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
" AND tagxref.tagtype>0"
" AND blob.rid=tagxref.rid",
g.argv[3]
);
if(nFindLimit>0){
blob_appendf(&sql, " LIMIT %d", nFindLimit);
}
db_prepare(&q, "%s", blob_str(&sql));
blob_reset(&sql);
while( db_step(&q)==SQLITE_ROW ){
fossil_print("%s\n", db_column_text(&q, 0));
}
db_finalize(&q);
}else{
int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
g.argv[3]);
if( tagid>0 ){
blob_appendf(&sql,
"%s"
" AND event.type GLOB '%q'"
" AND blob.rid IN ("
" SELECT rid FROM tagxref"
" WHERE tagtype>0 AND tagid=%d"
")"
" ORDER BY event.mtime DESC",
timeline_query_for_tty(), zType, tagid
);
if(nFindLimit>0){
blob_appendf(&sql, " LIMIT %d", nFindLimit);
}
db_prepare(&q, "%s", blob_str(&sql));
blob_reset(&sql);
print_timeline(&q, 2000, 0);
db_finalize(&q);
}
}
}else
if( strncmp(g.argv[2],"list",n)==0 ){
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
243 244 245 246 247 248 249 | char zPrevDate[20]; GraphContext *pGraph = 0; int prevWasDivider = 0; /* True if previous output row was <hr> */ int fchngQueryInit = 0; /* True if fchngQuery is initialized */ Stmt fchngQuery; /* Query for file changes on check-ins */ static Stmt qbranch; int pendingEndTr = 0; /* True if a </td></tr> is needed */ | > | > > > | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
char zPrevDate[20];
GraphContext *pGraph = 0;
int prevWasDivider = 0; /* True if previous output row was <hr> */
int fchngQueryInit = 0; /* True if fchngQuery is initialized */
Stmt fchngQuery; /* Query for file changes on check-ins */
static Stmt qbranch;
int pendingEndTr = 0; /* True if a </td></tr> is needed */
int vid = 0; /* Current checkout version */
if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
vid = db_lget_int("checkout", 0);
}
zPrevDate[0] = 0;
mxWikiLen = db_get_int("timeline-max-comment", 0);
if( tmFlags & TIMELINE_GRAPH ){
pGraph = graph_init();
/* style is not moved to css, because this is
** a technical div for the timeline graph
*/
|
| ︙ | ︙ | |||
316 317 318 319 320 321 322 |
sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
@ <tr><td>
@ <div class="divider">%s(zPrevDate)</div>
@ </td><td></td><td></td></tr>
}
memcpy(zTime, &zDate[11], 5);
zTime[5] = 0;
| > > > | > | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 |
sqlite3_snprintf(sizeof(zPrevDate), zPrevDate, "%.10s", zDate);
@ <tr><td>
@ <div class="divider">%s(zPrevDate)</div>
@ </td><td></td><td></td></tr>
}
memcpy(zTime, &zDate[11], 5);
zTime[5] = 0;
if( rid == vid ){
@ <tr class="timelineCurrent">
}else {
@ <tr>
}
@ <td class="timelineTime">%s(zTime)</td>
@ <td class="timelineGraph">
if( tmFlags & TIMELINE_UCOLOR ) zBgClr = zUser ? hash_color(zUser) : 0;
if( zType[0]=='c'
&& (pGraph || zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0)
){
db_reset(&qbranch);
|
| ︙ | ︙ | |||
1864 1865 1866 1867 1868 1869 1870 |
g.zTop, yearPart, zWeek,
nCount, zWeek);
}
db_finalize(&stWeek);
}
/*
| | | 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 |
g.zTop, yearPart, zWeek,
nCount, zWeek);
}
db_finalize(&stWeek);
}
/*
** Implements the "byyear" and "bymonth" reports for /reports.
** If includeMonth is true then it generates the "bymonth" report,
** else the "byyear" report. If zUserName is not NULL and not empty
** then the report is restricted to events created by the named user
** account.
*/
static void stats_report_by_month_year(char includeMonth,
char includeWeeks,
|
| ︙ | ︙ | |||
2018 2019 2020 2021 2022 2023 2024 |
}
if( !includeMonth ){
output_table_sorting_javascript("statsTable","tnx");
}
}
/*
| | | 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 |
}
if( !includeMonth ){
output_table_sorting_javascript("statsTable","tnx");
}
}
/*
** Implements the "byuser" view for /reports.
*/
static void stats_report_by_user(){
Stmt query = empty_Stmt;
int nRowNumber = 0; /* current TR number */
int nEventTotal = 0; /* Total event count */
int rowClass = 0; /* counter for alternating
row colors */
|
| ︙ | ︙ | |||
2199 2200 2201 2202 2203 2204 2205 |
total);
}
output_table_sorting_javascript("statsTable","tnx");
}
}
/*
| | | 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 |
total);
}
output_table_sorting_javascript("statsTable","tnx");
}
}
/*
** WEBPAGE: reports
**
** Shows activity reports for the repository.
**
** Query Parameters:
**
** view=REPORT_NAME Valid values: bymonth, byyear, byuser
** user=NAME Restricts statistics to the given user
|
| ︙ | ︙ |
Changes to src/vfile.c.
| ︙ | ︙ | |||
211 212 213 214 215 216 217 |
db_ephemeral_blob(&q, 5, &origCksum);
if( sha1sum_file(zName, &fileCksum) ){
blob_zero(&fileCksum);
}
if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
blob_reset(&origCksum);
blob_reset(&fileCksum);
| | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
db_ephemeral_blob(&q, 5, &origCksum);
if( sha1sum_file(zName, &fileCksum) ){
blob_zero(&fileCksum);
}
if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
blob_reset(&origCksum);
blob_reset(&fileCksum);
}else if( (chnged==0 || chnged==2 || chnged==4)
&& (useMtime==0 || currentMtime!=oldMtime) ){
/* For files that were formerly believed to be unchanged or that were
** changed by merging, if their mtime changes, or unconditionally
** if --sha1sum is used, check to see if they have been edited by
** looking at their SHA1 sum */
assert( origSize==currentSize );
db_ephemeral_blob(&q, 5, &origCksum);
if( sha1sum_file(zName, &fileCksum) ){
blob_zero(&fileCksum);
}
if( blob_compare(&fileCksum, &origCksum) ){
chnged = 1;
}
blob_reset(&origCksum);
blob_reset(&fileCksum);
}
if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2 || chnged==4) ){
i64 desiredMtime;
if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){
if( currentMtime!=desiredMtime ){
file_set_mtime(zName, desiredMtime);
currentMtime = file_wd_mtime(zName);
}
}
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 |
login_check_credentials();
if( !g.perm.RdWiki ){ login_needed(); return; }
zPageName = P("name");
if( zPageName==0 ){
style_header("Wiki");
@ <ul>
{ char *zHomePageName = db_get("project-name",0);
if( zHomePageName ){
@ <li> %z(href("%R/wiki?name=%t",zHomePageName))
| > > > > > > | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
login_check_credentials();
if( !g.perm.RdWiki ){ login_needed(); return; }
zPageName = P("name");
if( zPageName==0 ){
style_header("Wiki");
@ <ul>
{ char *zWikiHomePageName = db_get("index-page",0);
if( zWikiHomePageName ){
@ <li> %z(href("%R%s",zWikiHomePageName))
@ %h(zWikiHomePageName)</a> wiki home page.</li>
}
}
{ char *zHomePageName = db_get("project-name",0);
if( zHomePageName ){
@ <li> %z(href("%R/wiki?name=%t",zHomePageName))
@ %h(zHomePageName)</a> project home page.</li>
}
}
@ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li>
@ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li>
@ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a>
@ to experiment.</li>
if( g.perm.NewWiki ){
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 | int nGimmeSent; /* Number of gimme cards sent */ int nFileSent; /* Number of files sent */ int nDeltaSent; /* Number of deltas sent */ int nFileRcvd; /* Number of files received */ int nDeltaRcvd; /* Number of deltas received */ int nDanglingFile; /* Number of dangling deltas received */ int mxSend; /* Stop sending "file" with pOut reaches this size */ u8 syncPrivate; /* True to enable syncing private content */ u8 nextIsPrivate; /* If true, next "file" received is a private */ time_t maxTime; /* Time when this transfer should be finished */ }; /* | > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | int nGimmeSent; /* Number of gimme cards sent */ int nFileSent; /* Number of files sent */ int nDeltaSent; /* Number of deltas sent */ int nFileRcvd; /* Number of files received */ int nDeltaRcvd; /* Number of deltas received */ int nDanglingFile; /* Number of dangling deltas received */ int mxSend; /* Stop sending "file" with pOut reaches this size */ int resync; /* Send igot cards for all holdings */ u8 syncPrivate; /* True to enable syncing private content */ u8 nextIsPrivate; /* If true, next "file" received is a private */ time_t maxTime; /* Time when this transfer should be finished */ }; /* |
| ︙ | ︙ | |||
734 735 736 737 738 739 740 |
/*
** Send an igot message for every entry in unclustered table.
** Return the number of cards sent.
*/
static int send_unclustered(Xfer *pXfer){
Stmt q;
int cnt = 0;
| > | > > > > > > > > > > | | | | | > > > | > > | 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 |
/*
** Send an igot message for every entry in unclustered table.
** Return the number of cards sent.
*/
static int send_unclustered(Xfer *pXfer){
Stmt q;
int cnt = 0;
if( pXfer->resync ){
db_prepare(&q,
"SELECT uuid, rid FROM blob"
" WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
" AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
" AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
" AND blob.rid<=%d"
" ORDER BY blob.rid DESC",
pXfer->resync
);
}else{
db_prepare(&q,
"SELECT uuid FROM unclustered JOIN blob USING(rid)"
" WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
" AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
" AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
);
}
while( db_step(&q)==SQLITE_ROW ){
blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0));
cnt++;
if( pXfer->resync && pXfer->mxSend<blob_size(pXfer->pOut) ){
pXfer->resync = db_column_int(&q, 1)-1;
}
}
db_finalize(&q);
if( cnt==0 ) pXfer->resync = 0;
return cnt;
}
/*
** Send an igot message for every artifact.
*/
static void send_all(Xfer *pXfer){
|
| ︙ | ︙ | |||
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 |
login_check_credentials();
if( !g.perm.Private ){
server_private_xfer_not_authorized();
}else{
xfer.syncPrivate = 1;
}
}
}else
/* Unknown message
*/
{
cgi_reset_content();
@ error bad\scommand:\s%F(blob_str(&xfer.line))
| > > > > > > > | 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 |
login_check_credentials();
if( !g.perm.Private ){
server_private_xfer_not_authorized();
}else{
xfer.syncPrivate = 1;
}
}
/* pragma send-catalog
**
** Send igot cards for all known artifacts.
*/
if( blob_eq(&xfer.aToken[1], "send-catalog") ){
xfer.resync = 0x7fffffff;
}
}else
/* Unknown message
*/
{
cgi_reset_content();
@ error bad\scommand:\s%F(blob_str(&xfer.line))
|
| ︙ | ︙ | |||
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 | ** Flag options for controlling client_sync() */ #define SYNC_PUSH 0x0001 #define SYNC_PULL 0x0002 #define SYNC_CLONE 0x0004 #define SYNC_PRIVATE 0x0008 #define SYNC_VERBOSE 0x0010 #endif /* ** Sync to the host identified in g.urlName and g.urlPath. This ** routine is called by the client. ** ** Records are pushed to the server if pushFlag is true. Records | > | 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 | ** Flag options for controlling client_sync() */ #define SYNC_PUSH 0x0001 #define SYNC_PULL 0x0002 #define SYNC_CLONE 0x0004 #define SYNC_PRIVATE 0x0008 #define SYNC_VERBOSE 0x0010 #define SYNC_RESYNC 0x0020 #endif /* ** Sync to the host identified in g.urlName and g.urlPath. This ** routine is called by the client. ** ** Records are pushed to the server if pushFlag is true. Records |
| ︙ | ︙ | |||
1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 |
/* TBD: Request all transferable configuration values */
content_enable_dephantomize(0);
zOpType = "Clone";
}else if( syncFlags & SYNC_PULL ){
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
nCardSent++;
zOpType = (syncFlags & SYNC_PUSH)?"Sync":"Pull";
}
if( syncFlags & SYNC_PUSH ){
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
nCardSent++;
if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
}
manifest_crosslink_begin();
if( syncFlags & SYNC_VERBOSE ){
fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
}
while( go ){
| > > > > > | 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 |
/* TBD: Request all transferable configuration values */
content_enable_dephantomize(0);
zOpType = "Clone";
}else if( syncFlags & SYNC_PULL ){
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
nCardSent++;
zOpType = (syncFlags & SYNC_PUSH)?"Sync":"Pull";
if( (syncFlags & SYNC_RESYNC)!=0 && nCycle<2 ){
blob_appendf(&send, "pragma send-catalog\n");
nCardSent++;
}
}
if( syncFlags & SYNC_PUSH ){
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
nCardSent++;
if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
}
manifest_crosslink_begin();
if( syncFlags & SYNC_VERBOSE ){
fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
}
while( go ){
|
| ︙ | ︙ |
Changes to www/adding_code.wiki.
| ︙ | ︙ | |||
151 152 153 154 155 156 157 | You could also use "printf()" instead of "fossil_print()" to generate the output text, if desired. But "fossil_print()" is recommended as it has extra logic to insert \r characters at the right times on windows systems. Once you have the command running, you can then start adding code to | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | You could also use "printf()" instead of "fossil_print()" to generate the output text, if desired. But "fossil_print()" is recommended as it has extra logic to insert \r characters at the right times on windows systems. Once you have the command running, you can then start adding code to make it do useful things. There are lots of utility functions in Fossil for parsing command-line options and for opening and accessing and manipulating the repository and the working check-out. Study at the implementations of existing commands to get an idea of how things are done. You can easily find the implementations of existing commands by searching for "COMMAND: <i>name</i>" in the files of the "src/" directory. |
| ︙ | ︙ |
Changes to www/changes.wiki.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<title>Change Log</title>
<h2>Changes For Version 1.27 (as yet unreleased)</h2>
* Enhance the [/help?cmd=changes | fossil changes],
[/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
[/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
to restrict operation to files and directories named on the command-line.
<h2>Changes For Version 1.26 (2013-06-18)</h2>
* The argument to the --port option for the [/help?cmd=ui | fossil ui] and
[/help?cmd=server | fossil server] commands can take an IP address in addition
to the port number, causing Fossil to bind to just that one IP address.
* After prompting for a password, also ask if that password should be
remembered.
| > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<title>Change Log</title>
<h2>Changes For Version 1.27 (as yet unreleased)</h2>
* Enhance the [/help?cmd=changes | fossil changes],
[/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
[/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
to restrict operation to files and directories named on the command-line.
* New --integrate option to [/help?cmd=merge | fossil merge], which
automatically closes the merged branch when committing.
* Renamed <tt>/stats_report</tt> page to [/reports]. Graph width is now
relative, not absolute.
* Added <tt>yw=YYYY-WW</tt> (year-week) filter to timeline to limit the results
to a specific year and calendar week number, e.g. [/timeline?yw=2013-01].
<h2>Changes For Version 1.26 (2013-06-18)</h2>
* The argument to the --port option for the [/help?cmd=ui | fossil ui] and
[/help?cmd=server | fossil server] commands can take an IP address in addition
to the port number, causing Fossil to bind to just that one IP address.
* After prompting for a password, also ask if that password should be
remembered.
|
| ︙ | ︙ |
Changes to www/fileformat.wiki.
| ︙ | ︙ | |||
294 295 296 297 298 299 300 | <blockquote> <b>D</b> <i>time-and-date-stamp</i><br /> <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name artifact-id ?value?</i><br /> <b>U</b> <i>user-name</i><br /> <b>Z</b> <i>checksum</i><br /> </blockquote> | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | <blockquote> <b>D</b> <i>time-and-date-stamp</i><br /> <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name artifact-id ?value?</i><br /> <b>U</b> <i>user-name</i><br /> <b>Z</b> <i>checksum</i><br /> </blockquote> A control artifact must have one D card, one U card, one Z card and one or more T cards. No other cards or other text is allowed in a control artifact. Control artifacts might be PGP clearsigned. The D card and the Z card of a control artifact are the same as in a manifest. |
| ︙ | ︙ |