Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | merged/resolved trunk [ee723ed98ddb0a]. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | json-multitag-test | json |
| Files: | files | file ages | folders |
| SHA1: |
a40ac8fdc42a597dbf8a1d676836dacd |
| User & Date: | stephan 2011-10-16 10:04:41.821 |
Context
|
2011-10-16
| ||
| 13:29 | fixed a memleak of parent artifact uuid. long live valgrind. check-in: 3db8bfc5bf user: stephan tags: json-multitag-test, json | |
| 10:04 | merged/resolved trunk [ee723ed98ddb0a]. check-in: a40ac8fdc4 user: stephan tags: json-multitag-test, json | |
| 09:49 | minor doc clarification. check-in: 398b53e059 user: stephan tags: json-multitag-test, json | |
|
2011-10-15
| ||
| 17:36 | Vary the number of columns of displayed files in the File List depending on the length of the longest filename in the list. check-in: ee723ed98d user: drh tags: trunk | |
Changes
Changes to src/browse.c.
| ︙ | ︙ | |||
247 248 249 250 251 252 253 | } /* Generate a multi-column table listing the contents of zD[] ** directory. */ mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/"); cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/"); | | > > | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
}
/* Generate a multi-column table listing the contents of zD[]
** directory.
*/
mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/");
nCol = 100/mxLen;
if( nCol<1 ) nCol = 1;
if( nCol>5 ) nCol = 5;
nRow = (cnt+nCol-1)/nCol;
db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
@ <table class="browser"><tr><td class="browser"><ul class="browser">
i = 0;
while( db_step(&q)==SQLITE_ROW ){
const char *zFN;
if( i==nRow ){
|
| ︙ | ︙ |
Changes to src/cgi.c.
| ︙ | ︙ | |||
360 361 362 363 364 365 366 | } /* ** Do a redirect request to the URL given in the argument. ** ** The URL must be relative to the base of the fossil server. */ | | | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
}
/*
** Do a redirect request to the URL given in the argument.
**
** The URL must be relative to the base of the fossil server.
*/
NORETURN void cgi_redirect(const char *zURL){
char *zLocation;
CGIDEBUG(("redirect to %s\n", zURL));
if( strncmp(zURL,"http:",5)==0 || strncmp(zURL,"https:",6)==0 ){
zLocation = mprintf("Location: %s\r\n", zURL);
}else if( *zURL=='/' ){
zLocation = mprintf("Location: %.*s%s\r\n",
strlen(g.zBaseURL)-strlen(g.zTop), g.zBaseURL, zURL);
}else{
zLocation = mprintf("Location: %s/%s\r\n", g.zBaseURL, zURL);
}
cgi_append_header(zLocation);
cgi_reset_content();
cgi_printf("<html>\n<p>Redirect to %h</p>\n</html>\n", zLocation);
cgi_set_status(302, "Moved Temporarily");
free(zLocation);
cgi_reply();
fossil_exit(0);
}
NORETURN void cgi_redirectf(const char *zFormat, ...){
va_list ap;
va_start(ap, zFormat);
cgi_redirect(vmprintf(zFormat, ap));
va_end(ap);
}
/*
|
| ︙ | ︙ | |||
990 991 992 993 994 995 996 | va_end(ap); return 1; } /* ** Print all query parameters on standard output. Format the ** parameters as HTML. This is used for testing and debugging. | > | < | < < < < < > > | < | > | 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 |
va_end(ap);
return 1;
}
/*
** Print all query parameters on standard output. Format the
** parameters as HTML. This is used for testing and debugging.
**
** Omit the values of the cookies unless showAll is true.
*/
void cgi_print_all(int showAll){
int i;
cgi_parameter("",""); /* Force the parameters into sorted order */
for(i=0; i<nUsedQP; i++){
const char *zName = aParamQP[i].zName;
if( !showAll ){
if( fossil_stricmp("HTTP_COOKIE",zName)==0 ) continue;
if( fossil_strnicmp("fossil-",zName,7)==0 ) continue;
}
cgi_printf("%h = %h <br />\n", zName, aParamQP[i].zValue);
}
}
/*
** This routine works like "printf" except that it has the
** extra formatting capabilities such as %h and %t.
*/
|
| ︙ | ︙ | |||
1032 1033 1034 1035 1036 1037 1038 | vxprintf(pContent,zFormat,ap); } /* ** Send a reply indicating that the HTTP request was malformed */ | | | | 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 |
vxprintf(pContent,zFormat,ap);
}
/*
** Send a reply indicating that the HTTP request was malformed
*/
static NORETURN void malformed_request(void){
cgi_set_status(501, "Not Implemented");
cgi_printf(
"<html><body>Unrecognized HTTP Request</body></html>\n"
);
cgi_reply();
fossil_exit(0);
}
/*
** Panic and die while processing a webpage.
*/
NORETURN void cgi_panic(const char *zFormat, ...){
va_list ap;
cgi_reset_content();
if( g.json.isJsonMode ){
char * zMsg;
va_start(ap, zFormat);
zMsg = vmprintf(zFormat,ap);
va_end(ap);
|
| ︙ | ︙ | |||
1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 |
if( nchildren>MAX_PARALLEL ){
/* Slow down if connections are arriving too fast */
sleep( nchildren-MAX_PARALLEL );
}
delay.tv_sec = 60;
delay.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET( listener, &readfds);
select( listener+1, &readfds, 0, 0, &delay);
if( FD_ISSET(listener, &readfds) ){
lenaddr = sizeof(inaddr);
connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
if( connection>=0 ){
child = fork();
| > | 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 |
if( nchildren>MAX_PARALLEL ){
/* Slow down if connections are arriving too fast */
sleep( nchildren-MAX_PARALLEL );
}
delay.tv_sec = 60;
delay.tv_usec = 0;
FD_ZERO(&readfds);
assert( listener>=0 );
FD_SET( listener, &readfds);
select( listener+1, &readfds, 0, 0, &delay);
if( FD_ISSET(listener, &readfds) ){
lenaddr = sizeof(inaddr);
connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
if( connection>=0 ){
child = fork();
|
| ︙ | ︙ |
Changes to src/config.h.
| ︙ | ︙ | |||
132 133 134 135 136 137 138 139 | # define FOSSIL_INT_TO_PTR(X) ((void*)&((char*)0)[X]) # define FOSSIL_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) #else /* Generates a warning - but it always works */ # define FOSSIL_INT_TO_PTR(X) ((void*)(X)) # define FOSSIL_PTR_TO_INT(X) ((int)(X)) #endif #endif /* _RC_COMPILE_ */ | > > > > > > > > > | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | # define FOSSIL_INT_TO_PTR(X) ((void*)&((char*)0)[X]) # define FOSSIL_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) #else /* Generates a warning - but it always works */ # define FOSSIL_INT_TO_PTR(X) ((void*)(X)) # define FOSSIL_PTR_TO_INT(X) ((int)(X)) #endif /* ** A marker for functions that never return. */ #if defined(__GNUC__) || defined(__clang__) # define NORETURN __attribute__((__noreturn__)) #else # define NORETURN #endif #endif /* _RC_COMPILE_ */ |
Changes to src/db.c.
| ︙ | ︙ | |||
757 758 759 760 761 762 763 |
/*
* * Returns TRUE if zTable exists in the local database.
*/
static int db_local_table_exists(const char *zTable){
return db_exists("SELECT 1 FROM %s.sqlite_master"
| | | | 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 |
/*
* * Returns TRUE if zTable exists in the local database.
*/
static int db_local_table_exists(const char *zTable){
return db_exists("SELECT 1 FROM %s.sqlite_master"
" WHERE name=='%s' /*scan*/",
db_name("localdb"), zTable);
}
/*
** Returns TRUE if zColumn exists in zTable in the local database.
*/
static int db_local_column_exists(const char *zTable, const char *zColumn){
return db_exists("SELECT 1 FROM %s.sqlite_master"
" WHERE name=='%s' AND sql GLOB '* %s *' /*scan*/",
db_name("localdb"), zTable, zColumn);
}
/*
** If zDbName is a valid local database file, open it and return
** true. If it is not a valid local database file, return 0.
*/
|
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
709 710 711 712 713 714 715 | free(p->c.aEdit); p->c.aEdit = 0; p->c.nEdit = 0; p->c.nEditAlloc = 0; /* Clear out the from file */ free(p->c.aFrom); | < | 709 710 711 712 713 714 715 716 717 718 719 720 721 722 | free(p->c.aEdit); p->c.aEdit = 0; p->c.nEdit = 0; p->c.nEditAlloc = 0; /* Clear out the from file */ free(p->c.aFrom); /* Return no errors */ return 0; } /* |
| ︙ | ︙ |
Changes to src/http.c.
| ︙ | ︙ | |||
134 135 136 137 138 139 140 |
*/
int http_exchange(Blob *pSend, Blob *pReply, int useLogin){
Blob login; /* The login card */
Blob payload; /* The complete payload including login card */
Blob hdr; /* The HTTP request header */
int closeConnection; /* True to close the connection when done */
int iLength; /* Length of the reply payload */
| | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
*/
int http_exchange(Blob *pSend, Blob *pReply, int useLogin){
Blob login; /* The login card */
Blob payload; /* The complete payload including login card */
Blob hdr; /* The HTTP request header */
int closeConnection; /* True to close the connection when done */
int iLength; /* Length of the reply payload */
int rc = 0; /* Result code */
int iHttpVersion; /* Which version of HTTP protocol server uses */
char *zLine; /* A single line of the reply header */
int i; /* Loop counter */
int isError = 0; /* True if the reply is an error message */
int isCompressed = 1; /* True if the reply is compressed */
if( transport_open() ){
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
795 796 797 798 799 800 801 |
" WHERE tagid=%d AND tagtype>0 AND rid=mlink.mid),'trunk')"
" FROM mlink, filename, event, blob a, blob b"
" WHERE filename.fnid=mlink.fnid"
" AND event.objid=mlink.mid"
" AND a.rid=mlink.fid"
" AND b.rid=mlink.mid"
" AND mlink.fid=%d"
| | | 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 |
" WHERE tagid=%d AND tagtype>0 AND rid=mlink.mid),'trunk')"
" FROM mlink, filename, event, blob a, blob b"
" WHERE filename.fnid=mlink.fnid"
" AND event.objid=mlink.mid"
" AND a.rid=mlink.fid"
" AND b.rid=mlink.mid"
" AND mlink.fid=%d"
" ORDER BY filename.name, event.mtime /*sort*/",
TAG_BRANCH, rid
);
@ <ul>
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
const char *zDate = db_column_text(&q, 1);
const char *zCom = db_column_text(&q, 2);
|
| ︙ | ︙ |
Changes to src/json.c.
| ︙ | ︙ | |||
2229 2230 2231 2232 2233 2234 2235 |
** Impl of /json/user/get. Requires admin rights.
*/
static cson_value * json_user_get(){
cson_value * payV = NULL;
char const * pUser = NULL;
Stmt q;
if(!g.perm.Admin){
| | > | 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 |
** Impl of /json/user/get. Requires admin rights.
*/
static cson_value * json_user_get(){
cson_value * payV = NULL;
char const * pUser = NULL;
Stmt q;
if(!g.perm.Admin){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'a' privileges.");
return NULL;
}
pUser = json_command_arg(g.json.dispatchDepth+1);
if( g.isHTTP && (!pUser || !*pUser) ){
pUser = json_getenv_cstr("name")
/* ACHTUNG: fossil apparently internally sets name=user/get/XYZ
if we pass the name as part of the path, which is why we check
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
89 90 91 92 93 94 95 |
char *login_cookie_name(void){
static char *zCookieName = 0;
if( zCookieName==0 ){
zCookieName = db_text(0,
"SELECT 'fossil-' || substr(value,1,16)"
" FROM config"
" WHERE name IN ('project-code','login-group-code')"
| | | 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
char *login_cookie_name(void){
static char *zCookieName = 0;
if( zCookieName==0 ){
zCookieName = db_text(0,
"SELECT 'fossil-' || substr(value,1,16)"
" FROM config"
" WHERE name IN ('project-code','login-group-code')"
" ORDER BY name /*sort*/"
);
}
return zCookieName;
}
/*
** Redirect to the page specified by the "g" query parameter.
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
489 490 491 492 493 494 495 | return g.argv[0]; #endif } /* ** Exit. Take care to close the database first. */ | | | | 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
return g.argv[0];
#endif
}
/*
** Exit. Take care to close the database first.
*/
NORETURN void fossil_exit(int rc){
db_close(1);
exit(rc);
}
/*
** Print an error message, rollback all databases, and quit. These
** routines never return.
*/
NORETURN void fossil_panic(const char *zFormat, ...){
char *z;
va_list ap;
int rc = 1;
static int once = 1;
mainInFatalError = 1;
va_start(ap, zFormat);
z = vmprintf(zFormat, ap);
|
| ︙ | ︙ | |||
525 526 527 528 529 530 531 |
fossil_puts(zOut, 1);
}
free(z);
db_force_rollback();
fossil_exit(rc);
}
| | | 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 |
fossil_puts(zOut, 1);
}
free(z);
db_force_rollback();
fossil_exit(rc);
}
NORETURN void fossil_fatal(const char *zFormat, ...){
char *z;
int rc = 1;
va_list ap;
mainInFatalError = 1;
va_start(ap, zFormat);
z = vmprintf(zFormat, ap);
va_end(ap);
|
| ︙ | ︙ | |||
1031 1032 1033 1034 1035 1036 1037 |
g.zTop = &g.zBaseURL[7+strlen(zHost)];
}
}
/*
** Send an HTTP redirect back to the designated Index Page.
*/
| | | 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 |
g.zTop = &g.zBaseURL[7+strlen(zHost)];
}
}
/*
** Send an HTTP redirect back to the designated Index Page.
*/
NORETURN void fossil_redirect_home(void){
cgi_redirectf("%s%s", g.zTop, db_get("index-page", "/index"));
}
/*
** If running as root, chroot to the directory containing the
** repository zRepo and then drop root privileges. Return the
** new repository name.
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
152 153 154 155 156 157 158 |
"SELECT blob.uuid"
" FROM tag, tagxref, event, blob"
" WHERE tag.tagname='sym-%q' "
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
" AND event.objid=tagxref.rid "
" AND blob.rid=event.objid "
" AND event.type GLOB '%q'"
| | | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
"SELECT blob.uuid"
" FROM tag, tagxref, event, blob"
" WHERE tag.tagname='sym-%q' "
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
" AND event.objid=tagxref.rid "
" AND blob.rid=event.objid "
" AND event.type GLOB '%q'"
" ORDER BY event.mtime DESC /*sort*/",
zTag, zType
);
if( zUuid==0 ){
int nTag = strlen(zTag);
int i;
for(i=0; i<nTag-10; i++){
if( zTag[i]==':' && is_date(&zTag[i+1]) ){
|
| ︙ | ︙ | |||
178 179 180 181 182 183 184 |
" FROM tag, tagxref, event, blob"
" WHERE tag.tagname='sym-%q' "
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
" AND event.objid=tagxref.rid "
" AND blob.rid=event.objid "
" AND event.mtime<=julianday(%Q %s)"
" AND event.type GLOB '%q'"
| | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
" FROM tag, tagxref, event, blob"
" WHERE tag.tagname='sym-%q' "
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
" AND event.objid=tagxref.rid "
" AND blob.rid=event.objid "
" AND event.mtime<=julianday(%Q %s)"
" AND event.type GLOB '%q'"
" ORDER BY event.mtime DESC /*sort*/ ",
zTagBase, zDate, (useUtc ? "" : ",'utc'"), zType
);
break;
}
}
if( zUuid==0 && fossil_strcmp(zTag, "tip")==0 ){
zUuid = db_text(0,
|
| ︙ | ︙ |
Changes to src/path.c.
| ︙ | ︙ | |||
93 94 95 96 97 98 99 | bag_clear(&path.seen); memset(&path, 0, sizeof(&path)); } /* ** Construct the path from path.pStart to path.pEnd in the u.pTo fields. */ | | > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
bag_clear(&path.seen);
memset(&path, 0, sizeof(&path));
}
/*
** Construct the path from path.pStart to path.pEnd in the u.pTo fields.
*/
static void path_reverse_path(void){
PathNode *p;
assert( path.pEnd!=0 );
for(p=path.pEnd; p && p->pFrom; p = p->pFrom){
p->pFrom->u.pTo = p;
}
path.pEnd->u.pTo = 0;
assert( p==path.pStart );
}
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
846 847 848 849 850 851 852 853 854 855 856 857 858 859 |
@ <li> The server is started using either of the
@ <a href="%s(g.zTop)/help/server">fossil server</a> or
@ <a href="%s(g.zTop)/help/server">fossil http</a> commands
@ without the "--localauth" option.
@ <li> The server is started from CGI without the "localauth" keyword
@ in the CGI script.
@ </ol>
@ <hr />
onoff_attribute("Allow REMOTE_USER authentication",
"remote_user_ok", "remote_user_ok", 0);
@ <p>When enabled, if the REMOTE_USER environment variable is set to the
@ login name of a valid user and no other login credentials are available,
@ then the REMOTE_USER is accepted as an authenticated user.
@ </p>
| > > > > > > > > > | | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 |
@ <li> The server is started using either of the
@ <a href="%s(g.zTop)/help/server">fossil server</a> or
@ <a href="%s(g.zTop)/help/server">fossil http</a> commands
@ without the "--localauth" option.
@ <li> The server is started from CGI without the "localauth" keyword
@ in the CGI script.
@ </ol>
@
@ <hr />
onoff_attribute("Enable /test_env",
"test_env_enable", "test_env_enable", 0);
@ <p>When enabled, the %h(g.zBaseURL)/test_env URL is available to all
@ users. When disabled (the default) only users Admin and Setup can visit
@ the /test_env page.
@ </p>
@
@ <hr />
onoff_attribute("Allow REMOTE_USER authentication",
"remote_user_ok", "remote_user_ok", 0);
@ <p>When enabled, if the REMOTE_USER environment variable is set to the
@ login name of a valid user and no other login credentials are available,
@ then the REMOTE_USER is accepted as an authenticated user.
@ </p>
@
@ <hr />
entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
@ <p>The number of hours for which a login is valid. This must be a
@ positive number. The default is 8760 hours which is approximately equal
@ to a year.</p>
@ <hr />
|
| ︙ | ︙ |
Changes to src/shell.c.
| ︙ | ︙ | |||
334 335 336 337 338 339 340 |
** The interface is like "readline" but no command-line editing
** is done.
*/
static char *local_getline(char *zPrompt, FILE *in){
char *zLine;
int nLine;
int n;
| < < | < | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 |
** The interface is like "readline" but no command-line editing
** is done.
*/
static char *local_getline(char *zPrompt, FILE *in){
char *zLine;
int nLine;
int n;
if( zPrompt && *zPrompt ){
printf("%s",zPrompt);
fflush(stdout);
}
nLine = 100;
zLine = malloc( nLine );
if( zLine==0 ) return 0;
n = 0;
while( 1 ){
if( n+100>nLine ){
nLine = nLine*2 + 100;
zLine = realloc(zLine, nLine);
if( zLine==0 ) return 0;
}
if( fgets(&zLine[n], nLine - n, in)==0 ){
if( n==0 ){
free(zLine);
return 0;
}
zLine[n] = 0;
break;
}
while( zLine[n] ){ n++; }
if( n>0 && zLine[n-1]=='\n' ){
n--;
if( n>0 && zLine[n-1]=='\r' ) n--;
zLine[n] = 0;
break;
}
}
zLine = realloc( zLine, n+1 );
return zLine;
}
/*
|
| ︙ | ︙ | |||
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 |
int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
/* (not the same as sqlite3_exec) */
struct callback_data *pArg, /* Pointer to struct callback_data */
char **pzErrMsg /* Error msg written here */
){
sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
int rc = SQLITE_OK; /* Return Code */
const char *zLeftover; /* Tail of unprocessed SQL */
if( pzErrMsg ){
*pzErrMsg = NULL;
}
while( zSql[0] && (SQLITE_OK == rc) ){
| > | 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 |
int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
/* (not the same as sqlite3_exec) */
struct callback_data *pArg, /* Pointer to struct callback_data */
char **pzErrMsg /* Error msg written here */
){
sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
int rc = SQLITE_OK; /* Return Code */
int rc2;
const char *zLeftover; /* Tail of unprocessed SQL */
if( pzErrMsg ){
*pzErrMsg = NULL;
}
while( zSql[0] && (SQLITE_OK == rc) ){
|
| ︙ | ︙ | |||
1186 1187 1188 1189 1190 1191 1192 |
if( pArg && pArg->statsOn ){
display_stats(db, pArg, 0);
}
/* Finalize the statement just executed. If this fails, save a
** copy of the error message. Otherwise, set zSql to point to the
** next statement to execute. */
| | > | 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 |
if( pArg && pArg->statsOn ){
display_stats(db, pArg, 0);
}
/* Finalize the statement just executed. If this fails, save a
** copy of the error message. Otherwise, set zSql to point to the
** next statement to execute. */
rc2 = sqlite3_finalize(pStmt);
if( rc!=SQLITE_NOMEM ) rc = rc2;
if( rc==SQLITE_OK ){
zSql = zLeftover;
while( IsSpace(zSql[0]) ) zSql++;
}else if( pzErrMsg ){
*pzErrMsg = save_err_msg(db);
}
|
| ︙ | ︙ | |||
1758 1759 1760 1761 1762 1763 1764 |
sqlite3_finalize(pStmt);
return 1;
}
sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
zCommit = "COMMIT";
while( (zLine = local_getline(0, in))!=0 ){
char *z;
| < | 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 |
sqlite3_finalize(pStmt);
return 1;
}
sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
zCommit = "COMMIT";
while( (zLine = local_getline(0, in))!=0 ){
char *z;
lineno++;
azCol[0] = zLine;
for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
*z = 0;
i++;
if( i<nCol ){
|
| ︙ | ︙ | |||
2233 2234 2235 2236 2237 2238 2239 |
** of the option name, or a numerical value. */
n = strlen30(azArg[1]);
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
if( testctrl<0 ){
testctrl = aCtrl[i].ctrlCode;
}else{
| | | 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 |
** of the option name, or a numerical value. */
n = strlen30(azArg[1]);
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
if( testctrl<0 ){
testctrl = aCtrl[i].ctrlCode;
}else{
fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
testctrl = -1;
break;
}
}
}
if( testctrl<0 ) testctrl = atoi(azArg[1]);
if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
|
| ︙ | ︙ | |||
2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 |
/* Need to check for batch mode here to so we can avoid printing
** informational messages (like from process_sqliterc) before
** we do the actual processing of arguments later in a second pass.
*/
}else if( strcmp(argv[i],"-batch")==0 ){
stdin_is_interactive = 0;
}else if( strcmp(argv[i],"-heap")==0 ){
int j, c;
const char *zSize;
sqlite3_int64 szHeap;
zSize = argv[++i];
szHeap = atoi(zSize);
for(j=0; (c = zSize[j])!=0; j++){
if( c=='M' ){ szHeap *= 1000000; break; }
if( c=='K' ){ szHeap *= 1000; break; }
if( c=='G' ){ szHeap *= 1000000000; break; }
}
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
| > < | 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 |
/* Need to check for batch mode here to so we can avoid printing
** informational messages (like from process_sqliterc) before
** we do the actual processing of arguments later in a second pass.
*/
}else if( strcmp(argv[i],"-batch")==0 ){
stdin_is_interactive = 0;
}else if( strcmp(argv[i],"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
int j, c;
const char *zSize;
sqlite3_int64 szHeap;
zSize = argv[++i];
szHeap = atoi(zSize);
for(j=0; (c = zSize[j])!=0; j++){
if( c=='M' ){ szHeap *= 1000000; break; }
if( c=='K' ){ szHeap *= 1000; break; }
if( c=='G' ){ szHeap *= 1000000000; break; }
}
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
#endif
#ifdef SQLITE_ENABLE_VFSTRACE
}else if( strcmp(argv[i],"-vfstrace")==0 ){
extern int vfstrace_register(
const char *zTraceName,
const char *zOldVfsName,
|
| ︙ | ︙ | |||
2794 2795 2796 2797 2798 2799 2800 |
#endif
}else{
#ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:";
#else
data.zDbFilename = 0;
#endif
| | | 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 |
#endif
}else{
#ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:";
#else
data.zDbFilename = 0;
#endif
/***** Begin Fossil Patch *****/
{
extern void fossil_open(const char **);
fossil_open(&data.zDbFilename);
}
/***** End Fossil Patch *****/
}
if( i<argc ){
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
| ︙ | ︙ | |||
654 655 656 657 658 659 660 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.9" #define SQLITE_VERSION_NUMBER 3007009 | | | 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.7.9" #define SQLITE_VERSION_NUMBER 3007009 #define SQLITE_SOURCE_ID "2011-10-15 00:16:30 39408702a989f907261c298bf0947f3e68bd10fe" /* ** 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 |
| ︙ | ︙ | |||
3349 3350 3351 3352 3353 3354 3355 | ** first zero terminator. ^If nByte is non-negative, then it is the maximum ** number of bytes read from zSql. ^When nByte is non-negative, the ** zSql string ends at either the first '\000' or '\u0000' character or ** the nByte-th byte, whichever comes first. If the caller knows ** that the supplied string is nul-terminated, then there is a small ** performance advantage to be gained by passing an nByte parameter that ** is equal to the number of bytes in the input string <i>including</i> | | > | 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 | ** first zero terminator. ^If nByte is non-negative, then it is the maximum ** number of bytes read from zSql. ^When nByte is non-negative, the ** zSql string ends at either the first '\000' or '\u0000' character or ** the nByte-th byte, whichever comes first. If the caller knows ** that the supplied string is nul-terminated, then there is a small ** performance advantage to be gained by passing an nByte parameter that ** is equal to the number of bytes in the input string <i>including</i> ** the nul-terminator bytes as this saves SQLite from having to ** make a copy of the input string. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only ** compile the first statement in zSql, so *pzTail is left pointing to ** what remains uncompiled. ** ** ^*ppStmt is left pointing to a compiled [prepared statement] that can be |
| ︙ | ︙ | |||
3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 | ** ^The third argument is the value to bind to the parameter. ** ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of <u>bytes</u> in the value, not the number of characters.)^ ** ^If the fourth parameter is negative, the length of the string is ** the number of bytes up to the first zero terminator. ** ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or ** string after SQLite has finished with it. ^The destructor is called ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(), ** sqlite3_bind_text(), or sqlite3_bind_text16() fails. ** ^If the fifth argument is | > > > > > > > | 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 | ** ^The third argument is the value to bind to the parameter. ** ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of <u>bytes</u> in the value, not the number of characters.)^ ** ^If the fourth parameter is negative, the length of the string is ** the number of bytes up to the first zero terminator. ** If a non-negative fourth parameter is provided to sqlite3_bind_text() ** or sqlite3_bind_text16() then that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL ** terminated. If any NUL characters occur at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. ** ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or ** string after SQLite has finished with it. ^The destructor is called ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(), ** sqlite3_bind_text(), or sqlite3_bind_text16() fails. ** ^If the fifth argument is |
| ︙ | ︙ | |||
4588 4589 4590 4591 4592 4593 4594 | ** the 2nd parameter of the sqlite3_result_text* interfaces. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is negative, then SQLite takes result text from the 2nd parameter ** through the first zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined | | > > > > > | 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 | ** the 2nd parameter of the sqlite3_result_text* interfaces. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is negative, then SQLite takes result text from the 2nd parameter ** through the first zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would ** appear if the string where NUL terminated. If any NUL characters occur ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. ** ^If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or BLOB result when it has ** finished using that result. ** ^If the 4th parameter to the sqlite3_result_text* interfaces or to ** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite ** assumes that the text or BLOB result is in constant space and does not |
| ︙ | ︙ | |||
9313 9314 9315 9316 9317 9318 9319 | #ifdef SQLITE_MUTEX_OMIT /* ** If this is a no-op implementation, implement everything as macros. */ #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) #define sqlite3_mutex_free(X) | | | > > > | 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 | #ifdef SQLITE_MUTEX_OMIT /* ** If this is a no-op implementation, implement everything as macros. */ #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) #define sqlite3_mutex_free(X) #define sqlite3_mutex_enter(X) #define sqlite3_mutex_try(X) SQLITE_OK #define sqlite3_mutex_leave(X) #define sqlite3_mutex_held(X) ((void)(X),1) #define sqlite3_mutex_notheld(X) ((void)(X),1) #define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) #define sqlite3MutexInit() SQLITE_OK #define sqlite3MutexEnd() #define MUTEX_LOGIC(X) #else #define MUTEX_LOGIC(X) X #endif /* defined(SQLITE_MUTEX_OMIT) */ /************** End of mutex.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ /* |
| ︙ | ︙ | |||
11752 11753 11754 11755 11756 11757 11758 11759 11760 11761 11762 11763 11764 11765 11766 11767 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 | # define sqlite3VtabRollback(X) # define sqlite3VtabCommit(X) # define sqlite3VtabInSync(db) 0 # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK #else SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **); SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); SQLITE_PRIVATE void sqlite3VtabLock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*); SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*); SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*); SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*); SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); | > > < | 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 11787 11788 11789 11790 11791 11792 11793 11794 11795 11796 11797 11798 11799 11800 11801 11802 11803 11804 11805 11806 11807 11808 11809 11810 11811 | # define sqlite3VtabRollback(X) # define sqlite3VtabCommit(X) # define sqlite3VtabInSync(db) 0 # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK # define sqlite3GetVTable(X,Y) ((VTable*)0) #else SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **); SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); SQLITE_PRIVATE void sqlite3VtabLock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*); SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*); SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*); SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*); SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); SQLITE_PRIVATE const char *sqlite3JournalModename(int); SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); /* Declarations for functions in fkey.c. All of these are replaced by ** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign ** key functionality is available. If OMIT_TRIGGER is defined but |
| ︙ | ︙ | |||
13556 13557 13558 13559 13560 13561 13562 |
if( p->validTZ ){
computeJD(p);
}
return 0;
}
/*
| | > > | | | > > > > | 13573 13574 13575 13576 13577 13578 13579 13580 13581 13582 13583 13584 13585 13586 13587 13588 13589 13590 13591 13592 13593 13594 13595 13596 13597 13598 |
if( p->validTZ ){
computeJD(p);
}
return 0;
}
/*
** Set the time to the current time reported by the VFS.
**
** Return the number of errors.
*/
static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
sqlite3 *db = sqlite3_context_db_handle(context);
if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
p->validJD = 1;
return 0;
}else{
return 1;
}
}
/*
** Attempt to parse the given string into a Julian Day Number. Return
** the number of errors.
**
** The following are acceptable forms for the input string:
|
| ︙ | ︙ | |||
13591 13592 13593 13594 13595 13596 13597 |
){
double r;
if( parseYyyyMmDd(zDate,p)==0 ){
return 0;
}else if( parseHhMmSs(zDate, p)==0 ){
return 0;
}else if( sqlite3StrICmp(zDate,"now")==0){
| | < | 13614 13615 13616 13617 13618 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 |
){
double r;
if( parseYyyyMmDd(zDate,p)==0 ){
return 0;
}else if( parseHhMmSs(zDate, p)==0 ){
return 0;
}else if( sqlite3StrICmp(zDate,"now")==0){
return setDateTimeToCurrent(context, p);
}else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
p->validJD = 1;
return 0;
}
return 1;
}
|
| ︙ | ︙ | |||
14019 14020 14021 14022 14023 14024 14025 |
DateTime *p
){
int i;
const unsigned char *z;
int eType;
memset(p, 0, sizeof(*p));
if( argc==0 ){
| | > | | 14041 14042 14043 14044 14045 14046 14047 14048 14049 14050 14051 14052 14053 14054 14055 14056 14057 |
DateTime *p
){
int i;
const unsigned char *z;
int eType;
memset(p, 0, sizeof(*p));
if( argc==0 ){
return setDateTimeToCurrent(context, p);
}
if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
|| eType==SQLITE_INTEGER ){
p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
p->validJD = 1;
}else{
z = sqlite3_value_text(argv[0]);
if( !z || parseDateOrTime(context, (char*)z, p) ){
return 1;
|
| ︙ | ︙ | |||
14332 14333 14334 14335 14336 14337 14338 14339 14340 14341 14342 14343 14344 |
int argc,
sqlite3_value **argv
){
time_t t;
char *zFormat = (char *)sqlite3_user_data(context);
sqlite3 *db;
sqlite3_int64 iT;
char zBuf[20];
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv);
db = sqlite3_context_db_handle(context);
| > > | < < | < < < < | | | | < | > | > | 14355 14356 14357 14358 14359 14360 14361 14362 14363 14364 14365 14366 14367 14368 14369 14370 14371 14372 14373 14374 14375 14376 14377 14378 14379 14380 14381 14382 14383 14384 14385 14386 14387 14388 14389 14390 |
int argc,
sqlite3_value **argv
){
time_t t;
char *zFormat = (char *)sqlite3_user_data(context);
sqlite3 *db;
sqlite3_int64 iT;
struct tm *pTm;
struct tm sNow;
char zBuf[20];
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv);
db = sqlite3_context_db_handle(context);
if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
t = iT/1000 - 10000*(sqlite3_int64)21086676;
#ifdef HAVE_GMTIME_R
pTm = gmtime_r(&t, &sNow);
#else
sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
pTm = gmtime(&t);
if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
#endif
if( pTm ){
strftime(zBuf, 20, zFormat, &sNow);
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
}
}
#endif
/*
** This function registered all of the above C functions as SQL
** functions. This should be the only routine in this file with
** external linkage.
|
| ︙ | ︙ | |||
14691 14692 14693 14694 14695 14696 14697 |
/*
** Register a VFS with the system. It is harmless to register the same
** VFS multiple times. The new VFS becomes the default if makeDflt is
** true.
*/
SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
| | | | 14711 14712 14713 14714 14715 14716 14717 14718 14719 14720 14721 14722 14723 14724 14725 14726 14727 14728 14729 14730 |
/*
** Register a VFS with the system. It is harmless to register the same
** VFS multiple times. The new VFS becomes the default if makeDflt is
** true.
*/
SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
MUTEX_LOGIC(sqlite3_mutex *mutex;)
#ifndef SQLITE_OMIT_AUTOINIT
int rc = sqlite3_initialize();
if( rc ) return rc;
#endif
MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
sqlite3_mutex_enter(mutex);
vfsUnlink(pVfs);
if( makeDflt || vfsList==0 ){
pVfs->pNext = vfsList;
vfsList = pVfs;
}else{
pVfs->pNext = vfsList->pNext;
|
| ︙ | ︙ | |||
18944 18945 18946 18947 18948 18949 18950 | ** the public domain. The original comments are included here for ** completeness. They are very out-of-date but might be useful as ** an historical reference. Most of the "enhancements" have been backed ** out so that the functionality is now the same as standard printf(). ** ************************************************************************** ** | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < | | < < | 18964 18965 18966 18967 18968 18969 18970 18971 18972 18973 18974 18975 18976 18977 18978 18979 18980 18981 | ** the public domain. The original comments are included here for ** completeness. They are very out-of-date but might be useful as ** an historical reference. Most of the "enhancements" have been backed ** out so that the functionality is now the same as standard printf(). ** ************************************************************************** ** ** This file contains code for a set of "printf"-like routines. These ** routines format strings much like the printf() from the standard C ** library, though the implementation here has enhancements to support ** SQLlite. */ /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ |
| ︙ | ︙ | |||
19123 19124 19125 19126 19127 19128 19129 |
if( N>0 ){
sqlite3StrAccumAppend(pAccum, zSpaces, N);
}
}
/*
** On machines with a small stack size, you can redefine the
| | < < < < < | < < < < < < < < < < < < < < < < < < < | 19105 19106 19107 19108 19109 19110 19111 19112 19113 19114 19115 19116 19117 19118 19119 19120 19121 19122 19123 19124 19125 19126 19127 |
if( N>0 ){
sqlite3StrAccumAppend(pAccum, zSpaces, N);
}
}
/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
*/
#ifndef SQLITE_PRINT_BUF_SIZE
# define SQLITE_PRINT_BUF_SIZE 70
#endif
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
/*
** Render a string given by "fmt" into the StrAccum object.
*/
SQLITE_PRIVATE void sqlite3VXPrintf(
StrAccum *pAccum, /* Accumulate results here */
int useExtended, /* Allow extended %-conversions */
const char *fmt, /* Format string */
va_list ap /* arguments */
){
|
| ︙ | ︙ | |||
19178 19179 19180 19181 19182 19183 19184 19185 19186 19187 | etByte flag_blanksign; /* True if " " flag is present */ etByte flag_alternateform; /* True if "#" flag is present */ etByte flag_altform2; /* True if "!" flag is present */ etByte flag_zeropad; /* True if field width constant starts with zero */ etByte flag_long; /* True if "l" flag is present */ etByte flag_longlong; /* True if the "ll" flag is present */ etByte done; /* Loop termination flag */ sqlite_uint64 longvalue; /* Value for integer types */ LONGDOUBLE_TYPE realvalue; /* Value for real types */ const et_info *infop; /* Pointer to the appropriate info structure */ | > > < < < | > < > < | 19136 19137 19138 19139 19140 19141 19142 19143 19144 19145 19146 19147 19148 19149 19150 19151 19152 19153 19154 19155 19156 19157 19158 19159 19160 19161 19162 19163 19164 19165 19166 |
etByte flag_blanksign; /* True if " " flag is present */
etByte flag_alternateform; /* True if "#" flag is present */
etByte flag_altform2; /* True if "!" flag is present */
etByte flag_zeropad; /* True if field width constant starts with zero */
etByte flag_long; /* True if "l" flag is present */
etByte flag_longlong; /* True if the "ll" flag is present */
etByte done; /* Loop termination flag */
etByte xtype = 0; /* Conversion paradigm */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
sqlite_uint64 longvalue; /* Value for integer types */
LONGDOUBLE_TYPE realvalue; /* Value for real types */
const et_info *infop; /* Pointer to the appropriate info structure */
char *zOut; /* Rendering buffer */
int nOut; /* Size of the rendering buffer */
char *zExtra; /* Malloced memory used by some conversion */
#ifndef SQLITE_OMIT_FLOATING_POINT
int exp, e2; /* exponent of real numbers */
int nsd; /* Number of significant digits returned */
double rounder; /* Used for rounding floating point values */
etByte flag_dp; /* True if decimal point should be shown */
etByte flag_rtz; /* True if trailing zeros should be removed */
#endif
char buf[etBUFSIZE]; /* Conversion buffer */
bufpt = 0;
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
int amt;
bufpt = (char *)fmt;
amt = 1;
while( (c=(*++fmt))!='%' && c!=0 ) amt++;
|
| ︙ | ︙ | |||
19690 19691 19692 19693 19694 19695 19696 19697 19698 19699 19700 19701 19702 19703 |
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 || N==0 );
if( p->tooBig | p->mallocFailed ){
testcase(p->tooBig);
testcase(p->mallocFailed);
return;
}
if( N<0 ){
N = sqlite3Strlen30(z);
}
if( N==0 || NEVER(z==0) ){
return;
}
if( p->nChar+N >= p->nAlloc ){
| > | 19647 19648 19649 19650 19651 19652 19653 19654 19655 19656 19657 19658 19659 19660 19661 |
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
assert( z!=0 || N==0 );
if( p->tooBig | p->mallocFailed ){
testcase(p->tooBig);
testcase(p->mallocFailed);
return;
}
assert( p->zText!=0 || p->nChar==0 );
if( N<0 ){
N = sqlite3Strlen30(z);
}
if( N==0 || NEVER(z==0) ){
return;
}
if( p->nChar+N >= p->nAlloc ){
|
| ︙ | ︙ | |||
19721 19722 19723 19724 19725 19726 19727 |
}
if( p->useMalloc==1 ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite3_realloc(zOld, p->nAlloc);
}
if( zNew ){
| | > | 19679 19680 19681 19682 19683 19684 19685 19686 19687 19688 19689 19690 19691 19692 19693 19694 19695 19696 19697 19698 19699 19700 19701 19702 |
}
if( p->useMalloc==1 ){
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
}else{
zNew = sqlite3_realloc(zOld, p->nAlloc);
}
if( zNew ){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
p->mallocFailed = 1;
sqlite3StrAccumReset(p);
return;
}
}
}
assert( p->zText );
memcpy(&p->zText[p->nChar], z, N);
p->nChar += N;
}
/*
** Finish off a string by making sure it is zero-terminated.
** Return a pointer to the resulting string. Return a NULL
|
| ︙ | ︙ | |||
25170 25171 25172 25173 25174 25175 25176 |
#ifdef SQLITE_DEBUG
static int unixMutexHeld(void) {
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
#endif
| | | 25129 25130 25131 25132 25133 25134 25135 25136 25137 25138 25139 25140 25141 25142 25143 |
#ifdef SQLITE_DEBUG
static int unixMutexHeld(void) {
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
#endif
#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
/*
** Helper function for printing out trace information from debugging
** binaries. This returns the string represetation of the supplied
** integer lock-type.
*/
static const char *azFileLock(int eFileLock){
switch( eFileLock ){
|
| ︙ | ︙ | |||
26005 26006 26007 26008 26009 26010 26011 | ** The reason a single byte cannot be used instead of the 'shared byte ** range' is that some versions of windows do not support read-locks. By ** locking a random byte from a range, concurrent SHARED locks may exist ** even if the locking primitive used is always a write-lock. */ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; | | | | 25964 25965 25966 25967 25968 25969 25970 25971 25972 25973 25974 25975 25976 25977 25978 25979 25980 25981 25982 25983 25984 25985 |
** The reason a single byte cannot be used instead of the 'shared byte
** range' is that some versions of windows do not support read-locks. By
** locking a random byte from a range, concurrent SHARED locks may exist
** even if the locking primitive used is always a write-lock.
*/
int rc = SQLITE_OK;
unixFile *pFile = (unixFile*)id;
unixInodeInfo *pInode;
struct flock lock;
int tErrno = 0;
assert( pFile );
OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
azFileLock(eFileLock), azFileLock(pFile->eFileLock),
azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
/* If there is already a lock of this type or more restrictive on the
** unixFile, do nothing. Don't use the end_lock: exit path, as
** unixEnterMutex() hasn't been called yet.
*/
if( pFile->eFileLock>=eFileLock ){
OSTRACE(("LOCK %d %s ok (already held) (unix)\n", pFile->h,
|
| ︙ | ︙ | |||
26216 26217 26218 26219 26220 26221 26222 |
** remove the write lock on a region when a read lock is set.
*/
static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
unixFile *pFile = (unixFile*)id;
unixInodeInfo *pInode;
struct flock lock;
int rc = SQLITE_OK;
| < < < < < < < < < < | 26175 26176 26177 26178 26179 26180 26181 26182 26183 26184 26185 26186 26187 26188 26189 26190 26191 26192 26193 26194 26195 26196 26197 26198 26199 26200 26201 26202 26203 26204 26205 26206 26207 26208 26209 26210 26211 26212 26213 |
** remove the write lock on a region when a read lock is set.
*/
static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
unixFile *pFile = (unixFile*)id;
unixInodeInfo *pInode;
struct flock lock;
int rc = SQLITE_OK;
assert( pFile );
OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
getpid()));
assert( eFileLock<=SHARED_LOCK );
if( pFile->eFileLock<=eFileLock ){
return SQLITE_OK;
}
unixEnterMutex();
pInode = pFile->pInode;
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
#ifndef NDEBUG
/* When reducing a lock such that other processes can start
** reading the database file again, make sure that the
** transaction counter was updated if any part of the database
** file changed. If the transaction counter is not updated,
** other connections to the same file might not realize that
** the file has changed and hence might not know to flush their
** cache. The use of a stale cache can lead to database corruption.
*/
pFile->inNormalWrite = 0;
#endif
/* downgrading to a shared lock on NFS involves clearing the write lock
** before establishing the readlock - to avoid a race condition we downgrade
** the lock in 2 blocks, so that part of the range will be covered by a
** write lock until the rest is covered by a read lock:
|
| ︙ | ︙ | |||
26352 26353 26354 26355 26356 26357 26358 |
** the lock.
*/
pInode->nShared--;
if( pInode->nShared==0 ){
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
lock.l_start = lock.l_len = 0L;
| < < < | 26301 26302 26303 26304 26305 26306 26307 26308 26309 26310 26311 26312 26313 26314 |
** the lock.
*/
pInode->nShared--;
if( pInode->nShared==0 ){
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
lock.l_start = lock.l_len = 0L;
if( unixFileLock(pFile, &lock)==0 ){
pInode->eFileLock = NO_LOCK;
}else{
rc = SQLITE_IOERR_UNLOCK;
pFile->lastErrno = errno;
pInode->eFileLock = NO_LOCK;
pFile->eFileLock = NO_LOCK;
|
| ︙ | ︙ | |||
29189 29190 29191 29192 29193 29194 29195 29196 29197 29198 29199 29200 29201 29202 |
*/
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
assert( zFilename==0 || zFilename[0]=='/'
|| pVfs->pAppData==(void*)&autolockIoFinder );
#else
assert( zFilename==0 || zFilename[0]=='/' );
#endif
OSTRACE(("OPEN %-3d %s\n", h, zFilename));
pNew->h = h;
pNew->zPath = zFilename;
if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
pNew->ctrlFlags = UNIXFILE_EXCL;
}else{
| > > > | 29135 29136 29137 29138 29139 29140 29141 29142 29143 29144 29145 29146 29147 29148 29149 29150 29151 |
*/
#if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
assert( zFilename==0 || zFilename[0]=='/'
|| pVfs->pAppData==(void*)&autolockIoFinder );
#else
assert( zFilename==0 || zFilename[0]=='/' );
#endif
/* No locking occurs in temporary files */
assert( zFilename!=0 || noLock );
OSTRACE(("OPEN %-3d %s\n", h, zFilename));
pNew->h = h;
pNew->zPath = zFilename;
if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
pNew->ctrlFlags = UNIXFILE_EXCL;
}else{
|
| ︙ | ︙ | |||
29291 29292 29293 29294 29295 29296 29297 29298 29299 29300 29301 29302 29303 29304 |
else if( pLockingStyle == &dotlockIoMethods ){
/* Dotfile locking uses the file path so it needs to be included in
** the dotlockLockingContext
*/
char *zLockFile;
int nFilename;
nFilename = (int)strlen(zFilename) + 6;
zLockFile = (char *)sqlite3_malloc(nFilename);
if( zLockFile==0 ){
rc = SQLITE_NOMEM;
}else{
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
}
| > | 29240 29241 29242 29243 29244 29245 29246 29247 29248 29249 29250 29251 29252 29253 29254 |
else if( pLockingStyle == &dotlockIoMethods ){
/* Dotfile locking uses the file path so it needs to be included in
** the dotlockLockingContext
*/
char *zLockFile;
int nFilename;
assert( zFilename!=0 );
nFilename = (int)strlen(zFilename) + 6;
zLockFile = (char *)sqlite3_malloc(nFilename);
if( zLockFile==0 ){
rc = SQLITE_NOMEM;
}else{
sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename);
}
|
| ︙ | ︙ | |||
30070 30071 30072 30073 30074 30075 30076 | /* ** Find the current time (in Universal Coordinated Time). Write into *piNow ** the current time and date as a Julian Day number times 86_400_000. In ** other words, write into *piNow the number of milliseconds since the Julian ** epoch of noon in Greenwich on November 24, 4714 B.C according to the ** proleptic Gregorian calendar. ** | > | > | | > > > | | > | | | 30020 30021 30022 30023 30024 30025 30026 30027 30028 30029 30030 30031 30032 30033 30034 30035 30036 30037 30038 30039 30040 30041 30042 30043 30044 30045 30046 30047 30048 30049 30050 30051 30052 30053 30054 30055 30056 30057 30058 30059 30060 30061 30062 30063 30064 30065 30066 30067 30068 30069 30070 30071 30072 30073 30074 30075 30076 30077 |
/*
** Find the current time (in Universal Coordinated Time). Write into *piNow
** the current time and date as a Julian Day number times 86_400_000. In
** other words, write into *piNow the number of milliseconds since the Julian
** epoch of noon in Greenwich on November 24, 4714 B.C according to the
** proleptic Gregorian calendar.
**
** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
** cannot be found.
*/
static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
int rc = SQLITE_OK;
#if defined(NO_GETTOD)
time_t t;
time(&t);
*piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
#elif OS_VXWORKS
struct timespec sNow;
clock_gettime(CLOCK_REALTIME, &sNow);
*piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
#else
struct timeval sNow;
if( gettimeofday(&sNow, 0)==0 ){
*piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
}else{
rc = SQLITE_ERROR;
}
#endif
#ifdef SQLITE_TEST
if( sqlite3_current_time ){
*piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
}
#endif
UNUSED_PARAMETER(NotUsed);
return rc;
}
/*
** Find the current time (in Universal Coordinated Time). Write the
** current time and date as a Julian Day number into *prNow and
** return 0. Return 1 if the time and date cannot be found.
*/
static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
sqlite3_int64 i = 0;
int rc;
UNUSED_PARAMETER(NotUsed);
rc = unixCurrentTimeInt64(0, &i);
*prNow = i/86400000.0;
return rc;
}
/*
** We added the xGetLastError() method with the intention of providing
** better low-level error messages when operating-system problems come up
** during SQLite operation. But so far, none of that has been implemented
** in the core. So this routine is never called. For now, it is merely
|
| ︙ | ︙ | |||
34610 34611 34612 34613 34614 34615 34616 |
free(zConverted);
return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
UNUSED_PARAMETER(pVfs);
getLastErrorMsg(nBuf, zBufOut);
}
| | | | 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 |
free(zConverted);
return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
UNUSED_PARAMETER(pVfs);
getLastErrorMsg(nBuf, zBufOut);
}
static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
UNUSED_PARAMETER(pVfs);
#if SQLITE_OS_WINCE
/* The GetProcAddressA() routine is only available on wince. */
return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
#else
/* All other windows platforms expect GetProcAddress() to take
** an Ansi string regardless of the _UNICODE setting */
return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
#endif
}
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
UNUSED_PARAMETER(pVfs);
FreeLibrary((HANDLE)pHandle);
}
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
#define winDlOpen 0
#define winDlError 0
#define winDlSym 0
|
| ︙ | ︙ | |||
34695 34696 34697 34698 34699 34700 34701 | /* ** Find the current time (in Universal Coordinated Time). Write into *piNow ** the current time and date as a Julian Day number times 86_400_000. In ** other words, write into *piNow the number of milliseconds since the Julian ** epoch of noon in Greenwich on November 24, 4714 B.C according to the ** proleptic Gregorian calendar. ** | > | | | | | 34651 34652 34653 34654 34655 34656 34657 34658 34659 34660 34661 34662 34663 34664 34665 34666 34667 34668 34669 34670 34671 34672 34673 34674 34675 34676 34677 34678 34679 34680 34681 34682 34683 34684 34685 34686 34687 34688 34689 34690 34691 34692 34693 34694 34695 34696 34697 34698 34699 34700 34701 34702 34703 34704 34705 34706 34707 34708 34709 34710 |
/*
** Find the current time (in Universal Coordinated Time). Write into *piNow
** the current time and date as a Julian Day number times 86_400_000. In
** other words, write into *piNow the number of milliseconds since the Julian
** epoch of noon in Greenwich on November 24, 4714 B.C according to the
** proleptic Gregorian calendar.
**
** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
** cannot be found.
*/
static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
/* FILETIME structure is a 64-bit value representing the number of
100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
*/
FILETIME ft;
static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
#ifdef SQLITE_TEST
static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
#endif
/* 2^32 - to avoid use of LL and warnings in gcc */
static const sqlite3_int64 max32BitValue =
(sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
#if SQLITE_OS_WINCE
SYSTEMTIME time;
GetSystemTime(&time);
/* if SystemTimeToFileTime() fails, it returns zero. */
if (!SystemTimeToFileTime(&time,&ft)){
return SQLITE_ERROR;
}
#else
GetSystemTimeAsFileTime( &ft );
#endif
*piNow = winFiletimeEpoch +
((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
(sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
#ifdef SQLITE_TEST
if( sqlite3_current_time ){
*piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
}
#endif
UNUSED_PARAMETER(pVfs);
return SQLITE_OK;
}
/*
** Find the current time (in Universal Coordinated Time). Write the
** current time and date as a Julian Day number into *prNow and
** return 0. Return 1 if the time and date cannot be found.
*/
static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
int rc;
sqlite3_int64 i;
rc = winCurrentTimeInt64(pVfs, &i);
if( !rc ){
*prNow = i/86400000.0;
}
return rc;
|
| ︙ | ︙ | |||
40066 40067 40068 40069 40070 40071 40072 |
if( needPagerReset ){
pager_reset(pPager);
needPagerReset = 0;
}
rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_DONE ){
| < | 40023 40024 40025 40026 40027 40028 40029 40030 40031 40032 40033 40034 40035 40036 |
if( needPagerReset ){
pager_reset(pPager);
needPagerReset = 0;
}
rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_DONE ){
pPager->journalOff = szJ;
break;
}else if( rc==SQLITE_IOERR_SHORT_READ ){
/* If the journal has been truncated, simply stop reading and
** processing the journal. This might happen if the journal was
** not completely written and synced prior to a crash. In that
** case, the database should have never been written in the
|
| ︙ | ︙ | |||
40328 40329 40330 40331 40332 40333 40334 40335 40336 40337 40338 40339 40340 40341 |
){
int rc; /* Return code */
#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
PgHdr *p; /* For looping over pages */
#endif
assert( pPager->pWal );
#ifdef SQLITE_DEBUG
/* Verify that the page list is in accending order */
for(p=pList; p && p->pDirty; p=p->pDirty){
assert( p->pgno < p->pDirty->pgno );
}
#endif
| > | 40284 40285 40286 40287 40288 40289 40290 40291 40292 40293 40294 40295 40296 40297 40298 |
){
int rc; /* Return code */
#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
PgHdr *p; /* For looping over pages */
#endif
assert( pPager->pWal );
assert( pList );
#ifdef SQLITE_DEBUG
/* Verify that the page list is in accending order */
for(p=pList; p && p->pDirty; p=p->pDirty){
assert( p->pgno < p->pDirty->pgno );
}
#endif
|
| ︙ | ︙ | |||
46564 46565 46566 46567 46568 46569 46570 |
/* If iRead is non-zero, then it is the log frame number that contains the
** required page. Read and return data from the log file.
*/
if( iRead ){
int sz;
i64 iOffset;
sz = pWal->hdr.szPage;
| | | 46521 46522 46523 46524 46525 46526 46527 46528 46529 46530 46531 46532 46533 46534 46535 |
/* If iRead is non-zero, then it is the log frame number that contains the
** required page. Read and return data from the log file.
*/
if( iRead ){
int sz;
i64 iOffset;
sz = pWal->hdr.szPage;
sz = (sz&0xfe00) + ((sz&0x0001)<<16);
testcase( sz<=32768 );
testcase( sz>=65536 );
iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
*pInWal = 1;
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
}
|
| ︙ | ︙ | |||
49877 49878 49879 49880 49881 49882 49883 |
** If this Btree is a candidate for shared cache, try to find an
** existing BtShared object that we can share with
*/
if( isMemdb==0 && isTempDb==0 ){
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
int nFullPathname = pVfs->mxPathname+1;
char *zFullPathname = sqlite3Malloc(nFullPathname);
| | > > | 49834 49835 49836 49837 49838 49839 49840 49841 49842 49843 49844 49845 49846 49847 49848 49849 49850 49851 49852 49853 49854 49855 49856 49857 49858 49859 49860 |
** If this Btree is a candidate for shared cache, try to find an
** existing BtShared object that we can share with
*/
if( isMemdb==0 && isTempDb==0 ){
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
int nFullPathname = pVfs->mxPathname+1;
char *zFullPathname = sqlite3Malloc(nFullPathname);
MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
p->sharable = 1;
if( !zFullPathname ){
sqlite3_free(p);
return SQLITE_NOMEM;
}
sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
#if SQLITE_THREADSAFE
mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
sqlite3_mutex_enter(mutexOpen);
mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
sqlite3_mutex_enter(mutexShared);
#endif
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
assert( pBt->nRef>0 );
if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
&& sqlite3PagerVfs(pBt->pPager)==pVfs ){
int iDb;
for(iDb=db->nDb-1; iDb>=0; iDb--){
Btree *pExisting = db->aDb[iDb].pBt;
|
| ︙ | ︙ | |||
49993 49994 49995 49996 49997 49998 49999 |
pBt->usableSize = pBt->pageSize - nReserve;
assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
/* Add the new BtShared object to the linked list sharable BtShareds.
*/
if( p->sharable ){
| | | | 49952 49953 49954 49955 49956 49957 49958 49959 49960 49961 49962 49963 49964 49965 49966 49967 49968 |
pBt->usableSize = pBt->pageSize - nReserve;
assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
/* Add the new BtShared object to the linked list sharable BtShareds.
*/
if( p->sharable ){
MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
pBt->nRef = 1;
MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);)
if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
if( pBt->mutex==0 ){
rc = SQLITE_NOMEM;
db->mallocFailed = 0;
goto btree_open_out;
}
|
| ︙ | ︙ | |||
50077 50078 50079 50080 50081 50082 50083 |
** Decrement the BtShared.nRef counter. When it reaches zero,
** remove the BtShared structure from the sharing list. Return
** true if the BtShared.nRef counter reaches zero and return
** false if it is still positive.
*/
static int removeFromSharingList(BtShared *pBt){
#ifndef SQLITE_OMIT_SHARED_CACHE
| | | | 50036 50037 50038 50039 50040 50041 50042 50043 50044 50045 50046 50047 50048 50049 50050 50051 50052 50053 50054 50055 |
** Decrement the BtShared.nRef counter. When it reaches zero,
** remove the BtShared structure from the sharing list. Return
** true if the BtShared.nRef counter reaches zero and return
** false if it is still positive.
*/
static int removeFromSharingList(BtShared *pBt){
#ifndef SQLITE_OMIT_SHARED_CACHE
MUTEX_LOGIC( sqlite3_mutex *pMaster; )
BtShared *pList;
int removed = 0;
assert( sqlite3_mutex_notheld(pBt->mutex) );
MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
sqlite3_mutex_enter(pMaster);
pBt->nRef--;
if( pBt->nRef<=0 ){
if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
}else{
pList = GLOBAL(BtShared*,sqlite3SharedCacheList);
|
| ︙ | ︙ | |||
52696 52697 52698 52699 52700 52701 52702 |
c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
sqlite3_free(pCellKey);
}
}
if( c==0 ){
if( pPage->intKey && !pPage->leaf ){
lwr = idx;
| < | | 52655 52656 52657 52658 52659 52660 52661 52662 52663 52664 52665 52666 52667 52668 52669 52670 52671 52672 52673 52674 52675 52676 52677 52678 52679 52680 52681 52682 52683 52684 52685 52686 |
c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
sqlite3_free(pCellKey);
}
}
if( c==0 ){
if( pPage->intKey && !pPage->leaf ){
lwr = idx;
break;
}else{
*pRes = 0;
rc = SQLITE_OK;
goto moveto_finish;
}
}
if( c<0 ){
lwr = idx+1;
}else{
upr = idx-1;
}
if( lwr>upr ){
break;
}
pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
}
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
assert( pPage->isInit );
if( pPage->leaf ){
chldPg = 0;
}else if( lwr>=pPage->nCell ){
chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
}else{
chldPg = get4byte(findCell(pPage, lwr));
|
| ︙ | ︙ | |||
52979 52980 52981 52982 52983 52984 52985 52986 52987 52988 52989 52990 52991 52992 |
}else{
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
}
if( rc ){
pTrunk = 0;
goto end_allocate_page;
}
k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
if( k==0 && !searchList ){
/* The trunk has no leaves and the list is not being searched.
** So extract the trunk page itself and use it as the newly
** allocated page */
assert( pPrevTrunk==0 );
| > > | 52937 52938 52939 52940 52941 52942 52943 52944 52945 52946 52947 52948 52949 52950 52951 52952 |
}else{
rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
}
if( rc ){
pTrunk = 0;
goto end_allocate_page;
}
assert( pTrunk!=0 );
assert( pTrunk->aData!=0 );
k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
if( k==0 && !searchList ){
/* The trunk has no leaves and the list is not being searched.
** So extract the trunk page itself and use it as the newly
** allocated page */
assert( pPrevTrunk==0 );
|
| ︙ | ︙ | |||
54106 54107 54108 54109 54110 54111 54112 |
/* Drop the cell from the parent page. apDiv[i] still points to
** the cell within the parent, even though it has been dropped.
** This is safe because dropping a cell only overwrites the first
** four bytes of it, and this function does not need the first
** four bytes of the divider cell. So the pointer is safe to use
** later on.
**
| | > > | | 54066 54067 54068 54069 54070 54071 54072 54073 54074 54075 54076 54077 54078 54079 54080 54081 54082 54083 54084 54085 54086 54087 54088 |
/* Drop the cell from the parent page. apDiv[i] still points to
** the cell within the parent, even though it has been dropped.
** This is safe because dropping a cell only overwrites the first
** four bytes of it, and this function does not need the first
** four bytes of the divider cell. So the pointer is safe to use
** later on.
**
** But not if we are in secure-delete mode. In secure-delete mode,
** the dropCell() routine will overwrite the entire cell with zeroes.
** In this case, temporarily copy the cell into the aOvflSpace[]
** buffer. It will be copied out again as soon as the aSpace[] buffer
** is allocated. */
if( pBt->secureDelete ){
int iOff;
iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
if( (iOff+szNew[i])>(int)pBt->usableSize ){
rc = SQLITE_CORRUPT_BKPT;
memset(apOld, 0, (i+1)*sizeof(MemPage*));
goto balance_cleanup;
}else{
memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]);
apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData];
|
| ︙ | ︙ | |||
54532 54533 54534 54535 54536 54537 54538 54539 54540 54541 54542 54543 54544 54545 |
k = 0; /* Current 'new' sibling page */
for(i=0; i<nCell; i++){
int isDivider = 0;
while( i==iNextOld ){
/* Cell i is the cell immediately following the last cell on old
** sibling page j. If the siblings are not leaf pages of an
** intkey b-tree, then cell i was a divider cell. */
pOld = apCopy[++j];
iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
if( pOld->nOverflow ){
nOverflow = pOld->nOverflow;
iOverflow = i + !leafData + pOld->aOvfl[0].idx;
}
isDivider = !leafData;
| > | 54494 54495 54496 54497 54498 54499 54500 54501 54502 54503 54504 54505 54506 54507 54508 |
k = 0; /* Current 'new' sibling page */
for(i=0; i<nCell; i++){
int isDivider = 0;
while( i==iNextOld ){
/* Cell i is the cell immediately following the last cell on old
** sibling page j. If the siblings are not leaf pages of an
** intkey b-tree, then cell i was a divider cell. */
assert( j+1 < ArraySize(apCopy) );
pOld = apCopy[++j];
iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
if( pOld->nOverflow ){
nOverflow = pOld->nOverflow;
iOverflow = i + !leafData + pOld->aOvfl[0].idx;
}
isDivider = !leafData;
|
| ︙ | ︙ | |||
56874 56875 56876 56877 56878 56879 56880 |
}
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
| | | | 56837 56838 56839 56840 56841 56842 56843 56844 56845 56846 56847 56848 56849 56850 56851 56852 56853 56854 56855 56856 56857 56858 |
}
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
int rc; /* Value to return */
/* Enter the mutexes */
if( p==0 ) return SQLITE_OK;
sqlite3_mutex_enter(p->pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
if( p->pDestDb ){
sqlite3_mutex_enter(p->pDestDb->mutex);
}
/* Detach this backup from the source pager. */
if( p->pDestDb ){
p->pSrc->nBackup--;
|
| ︙ | ︙ | |||
58981 58982 58983 58984 58985 58986 58987 | #ifndef NDEBUG /* ** Change the comment on the the most recently coded instruction. Or ** insert a No-op and add the comment to that new instruction. This ** makes the code easier to read during debugging. None of this happens ** in a production build. */ | | < < > | > > > > > > < | | | < < < < < | | 58944 58945 58946 58947 58948 58949 58950 58951 58952 58953 58954 58955 58956 58957 58958 58959 58960 58961 58962 58963 58964 58965 58966 58967 58968 58969 58970 58971 58972 58973 58974 58975 58976 58977 58978 58979 58980 |
#ifndef NDEBUG
/*
** Change the comment on the the most recently coded instruction. Or
** insert a No-op and add the comment to that new instruction. This
** makes the code easier to read during debugging. None of this happens
** in a production build.
*/
static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
assert( p->nOp>0 || p->aOp==0 );
assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
if( p->nOp ){
assert( p->aOp );
sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
}
}
SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
va_list ap;
if( p ){
va_start(ap, zFormat);
vdbeVComment(p, zFormat, ap);
va_end(ap);
}
}
SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
va_list ap;
if( p ){
sqlite3VdbeAddOp0(p, OP_Noop);
va_start(ap, zFormat);
vdbeVComment(p, zFormat, ap);
va_end(ap);
}
}
#endif /* NDEBUG */
/*
** Return the opcode for a given address. If the address is -1, then
|
| ︙ | ︙ | |||
61264 61265 61266 61267 61268 61269 61270 | /* Get the size of the index entry. Only indices entries of less ** than 2GiB are support - anything large must be database corruption. ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so ** this code can safely assume that nCellKey is 32-bits */ assert( sqlite3BtreeCursorIsValid(pCur) ); | | | 61226 61227 61228 61229 61230 61231 61232 61233 61234 61235 61236 61237 61238 61239 61240 |
/* Get the size of the index entry. Only indices entries of less
** than 2GiB are support - anything large must be database corruption.
** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
** this code can safely assume that nCellKey is 32-bits
*/
assert( sqlite3BtreeCursorIsValid(pCur) );
VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
/* Read in the complete content of the index entry */
memset(&m, 0, sizeof(m));
rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m);
if( rc ){
|
| ︙ | ︙ | |||
61339 61340 61341 61342 61343 61344 61345 |
){
i64 nCellKey = 0;
int rc;
BtCursor *pCur = pC->pCursor;
Mem m;
assert( sqlite3BtreeCursorIsValid(pCur) );
| | | 61301 61302 61303 61304 61305 61306 61307 61308 61309 61310 61311 61312 61313 61314 61315 |
){
i64 nCellKey = 0;
int rc;
BtCursor *pCur = pC->pCursor;
Mem m;
assert( sqlite3BtreeCursorIsValid(pCur) );
VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
/* nCellKey will always be between 0 and 0xffffffff because of the say
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
if( nCellKey<=0 || nCellKey>0x7fffffff ){
*res = 0;
return SQLITE_CORRUPT_BKPT;
}
|
| ︙ | ︙ | |||
65615 65616 65617 65618 65619 65620 65621 |
if( u.am.pC->nullRow ){
u.am.payloadSize = 0;
}else if( u.am.pC->cacheStatus==p->cacheCtr ){
u.am.payloadSize = u.am.pC->payloadSize;
u.am.zRec = (char*)u.am.pC->aRow;
}else if( u.am.pC->isIndex ){
assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
| | | | 65577 65578 65579 65580 65581 65582 65583 65584 65585 65586 65587 65588 65589 65590 65591 65592 65593 65594 65595 65596 65597 65598 65599 65600 |
if( u.am.pC->nullRow ){
u.am.payloadSize = 0;
}else if( u.am.pC->cacheStatus==p->cacheCtr ){
u.am.payloadSize = u.am.pC->payloadSize;
u.am.zRec = (char*)u.am.pC->aRow;
}else if( u.am.pC->isIndex ){
assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
VVA_ONLY(rc =) sqlite3BtreeKeySize(u.am.pCrsr, &u.am.payloadSize64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
/* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
** payload size, so it is impossible for u.am.payloadSize64 to be
** larger than 32 bits. */
assert( (u.am.payloadSize64 & SQLITE_MAX_U32)==(u64)u.am.payloadSize64 );
u.am.payloadSize = (u32)u.am.payloadSize64;
}else{
assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
VVA_ONLY(rc =) sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize);
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
}
}else if( ALWAYS(u.am.pC->pseudoTableReg>0) ){
u.am.pReg = &aMem[u.am.pC->pseudoTableReg];
assert( u.am.pReg->flags & MEM_Blob );
assert( memIsValid(u.am.pReg) );
u.am.payloadSize = u.am.pReg->n;
|
| ︙ | ︙ | |||
67676 67677 67678 67679 67680 67681 67682 |
*/
assert( u.bk.pC->deferredMoveto==0 );
rc = sqlite3VdbeCursorMoveto(u.bk.pC);
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
if( u.bk.pC->isIndex ){
assert( !u.bk.pC->isTable );
| | | | 67638 67639 67640 67641 67642 67643 67644 67645 67646 67647 67648 67649 67650 67651 67652 67653 67654 67655 67656 67657 67658 67659 |
*/
assert( u.bk.pC->deferredMoveto==0 );
rc = sqlite3VdbeCursorMoveto(u.bk.pC);
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
if( u.bk.pC->isIndex ){
assert( !u.bk.pC->isTable );
VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
u.bk.n = (u32)u.bk.n64;
}else{
VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n);
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
}
if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){
goto no_mem;
|
| ︙ | ︙ | |||
73320 73321 73322 73323 73324 73325 73326 |
if( pToken ){
if( nExtra==0 ){
pNew->flags |= EP_IntValue;
pNew->u.iValue = iValue;
}else{
int c;
pNew->u.zToken = (char*)&pNew[1];
| > | | 73282 73283 73284 73285 73286 73287 73288 73289 73290 73291 73292 73293 73294 73295 73296 73297 |
if( pToken ){
if( nExtra==0 ){
pNew->flags |= EP_IntValue;
pNew->u.iValue = iValue;
}else{
int c;
pNew->u.zToken = (char*)&pNew[1];
assert( pToken->z!=0 || pToken->n==0 );
if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
pNew->u.zToken[pToken->n] = 0;
if( dequote && nExtra>=3
&& ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
sqlite3Dequote(pNew->u.zToken);
if( c=='"' ) pNew->flags |= EP_DblQuoted;
}
}
|
| ︙ | ︙ | |||
74359 74360 74361 74362 74363 74364 74365 |
/* Check to see if an existing table or index can be used to
** satisfy the query. This is preferable to generating a new
** ephemeral table.
*/
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */
| < < | > > > > > > > > > > | 74322 74323 74324 74325 74326 74327 74328 74329 74330 74331 74332 74333 74334 74335 74336 74337 74338 74339 74340 74341 74342 74343 74344 74345 74346 74347 74348 |
/* Check to see if an existing table or index can be used to
** satisfy the query. This is preferable to generating a new
** ephemeral table.
*/
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
sqlite3 *db = pParse->db; /* Database connection */
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
Table *pTab; /* Table <table>. */
Expr *pExpr; /* Expression <column> */
int iCol; /* Index of column <column> */
int iDb; /* Database idx for pTab */
assert( p ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
pTab = p->pSrc->a[0].pTab;
pExpr = p->pEList->a[0].pExpr;
iCol = pExpr->iColumn;
/* Code an OP_VerifyCookie and OP_TableLock for <table>. */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
/* This function is only called from two places. In both cases the vdbe
|
| ︙ | ︙ | |||
76370 76371 76372 76373 76374 76375 76376 |
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) 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 && pA->u.zToken ){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
| | | 76341 76342 76343 76344 76345 76346 76347 76348 76349 76350 76351 76352 76353 76354 76355 |
if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) 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 && 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 2;
}
}
if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
return 0;
}
|
| ︙ | ︙ | |||
81776 81777 81778 81779 81780 81781 81782 |
** the index already exists and must be cleared before being refilled and
** the root page number of the index is taken from pIndex->tnum.
*/
static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
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 */
| | > > | 81747 81748 81749 81750 81751 81752 81753 81754 81755 81756 81757 81758 81759 81760 81761 81762 81763 81764 81765 81766 81767 81768 81769 |
** the index already exists and must be cleared before being refilled and
** the root page number of the index is taken from pIndex->tnum.
*/
static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
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 */
#ifdef SQLITE_OMIT_MERGE_SORT
int regIdxKey; /* Registers containing the index key */
#endif
int regRecord; /* Register holding assemblied index record */
sqlite3 *db = pParse->db; /* The database connection */
int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
db->aDb[iDb].zName ) ){
|
| ︙ | ︙ | |||
81816 81817 81818 81819 81820 81821 81822 81823 81824 81825 81826 81827 81828 |
sqlite3VdbeChangeP5(v, 1);
}
#ifndef SQLITE_OMIT_MERGE_SORT
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
#endif
/* 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);
| > > < < > > > | 81789 81790 81791 81792 81793 81794 81795 81796 81797 81798 81799 81800 81801 81802 81803 81804 81805 81806 81807 81808 81809 81810 81811 81812 81813 81814 81815 81816 81817 81818 81819 81820 81821 81822 81823 81824 81825 81826 81827 81828 81829 81830 81831 81832 81833 81834 81835 |
sqlite3VdbeChangeP5(v, 1);
}
#ifndef SQLITE_OMIT_MERGE_SORT
/* Open the sorter cursor if we are to use one. */
iSorter = pParse->nTab++;
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
#else
iSorter = iTab;
#endif
/* 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);
#ifndef SQLITE_OMIT_MERGE_SORT
sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
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);
sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
sqlite3HaltConstraint(
pParse, OE_Abort, "indexed columns are not unique", P4_STATIC
);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
}
sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
#else
regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
addr2 = addr1 + 1;
if( pIndex->onError!=OE_None ){
const int regRowid = regIdxKey + pIndex->nColumn;
const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
/* The registers accessed by the OP_IsUnique opcode were allocated
** using sqlite3GetTempRange() inside of the sqlite3GenerateIndexKey()
|
| ︙ | ︙ | |||
81943 81944 81945 81946 81947 81948 81949 81950 81951 81952 81953 81954 81955 81956 |
/* Use the two-part index name to determine the database
** to search for the table. 'Fix' the table name to this db
** before looking up the table.
*/
assert( pName1 && pName2 );
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
if( iDb<0 ) goto exit_create_index;
#ifndef SQLITE_OMIT_TEMPDB
/* If the index name was unqualified, check if the the table
** is a temp table. If so, set the database to 1. Do not do this
** if initialising a database schema.
*/
if( !db->init.busy ){
| > | 81919 81920 81921 81922 81923 81924 81925 81926 81927 81928 81929 81930 81931 81932 81933 |
/* Use the two-part index name to determine the database
** to search for the table. 'Fix' the table name to this db
** before looking up the table.
*/
assert( pName1 && pName2 );
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
if( iDb<0 ) goto exit_create_index;
assert( pName && pName->z );
#ifndef SQLITE_OMIT_TEMPDB
/* If the index name was unqualified, check if the the table
** is a temp table. If so, set the database to 1. Do not do this
** if initialising a database schema.
*/
if( !db->init.busy ){
|
| ︙ | ︙ | |||
81970 81971 81972 81973 81974 81975 81976 81977 81978 81979 81980 81981 81982 81983 |
}
pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName,
pTblName->a[0].zDatabase);
if( !pTab || db->mallocFailed ) goto exit_create_index;
assert( db->aDb[iDb].pSchema==pTab->pSchema );
}else{
assert( pName==0 );
pTab = pParse->pNewTable;
if( !pTab ) goto exit_create_index;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
}
pDb = &db->aDb[iDb];
assert( pTab!=0 );
| > | 81947 81948 81949 81950 81951 81952 81953 81954 81955 81956 81957 81958 81959 81960 81961 |
}
pTab = sqlite3LocateTable(pParse, 0, pTblName->a[0].zName,
pTblName->a[0].zDatabase);
if( !pTab || db->mallocFailed ) goto exit_create_index;
assert( db->aDb[iDb].pSchema==pTab->pSchema );
}else{
assert( pName==0 );
assert( pStart==0 );
pTab = pParse->pNewTable;
if( !pTab ) goto exit_create_index;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
}
pDb = &db->aDb[iDb];
assert( pTab!=0 );
|
| ︙ | ︙ | |||
82012 82013 82014 82015 82016 82017 82018 82019 82020 82021 82022 82023 82024 82025 |
** If pName==0 it means that we are
** dealing with a primary key or UNIQUE constraint. We have to invent our
** own name.
*/
if( pName ){
zName = sqlite3NameFromToken(db, pName);
if( zName==0 ) goto exit_create_index;
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
goto exit_create_index;
}
if( !db->init.busy ){
if( sqlite3FindTable(db, zName, 0)!=0 ){
sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
| > | 81990 81991 81992 81993 81994 81995 81996 81997 81998 81999 82000 82001 82002 82003 82004 |
** If pName==0 it means that we are
** dealing with a primary key or UNIQUE constraint. We have to invent our
** own name.
*/
if( pName ){
zName = sqlite3NameFromToken(db, pName);
if( zName==0 ) goto exit_create_index;
assert( pName->z!=0 );
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
goto exit_create_index;
}
if( !db->init.busy ){
if( sqlite3FindTable(db, zName, 0)!=0 ){
sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
|
| ︙ | ︙ | |||
82867 82868 82869 82870 82871 82872 82873 |
sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
}
/*
** Commit a transaction
*/
SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
| < | < < < | < < | 82846 82847 82848 82849 82850 82851 82852 82853 82854 82855 82856 82857 82858 82859 82860 82861 82862 82863 82864 82865 82866 82867 82868 82869 82870 82871 82872 82873 82874 82875 82876 82877 82878 82879 82880 |
sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
}
/*
** Commit a transaction
*/
SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
Vdbe *v;
assert( pParse!=0 );
assert( pParse->db!=0 );
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
return;
}
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
}
}
/*
** Rollback a transaction
*/
SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
Vdbe *v;
assert( pParse!=0 );
assert( pParse->db!=0 );
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
return;
}
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 1);
}
|
| ︙ | ︙ | |||
84699 84700 84701 84702 84703 84704 84705 |
z2 = (char*)sqlite3_value_text(argv[0]);
n = sqlite3_value_bytes(argv[0]);
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
assert( z2==(char*)sqlite3_value_text(argv[0]) );
if( z2 ){
z1 = contextMalloc(context, ((i64)n)+1);
if( z1 ){
| < | | | | < | | | | 84672 84673 84674 84675 84676 84677 84678 84679 84680 84681 84682 84683 84684 84685 84686 84687 84688 84689 84690 84691 84692 84693 84694 84695 84696 84697 84698 84699 84700 84701 84702 84703 84704 84705 84706 84707 84708 |
z2 = (char*)sqlite3_value_text(argv[0]);
n = sqlite3_value_bytes(argv[0]);
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
assert( z2==(char*)sqlite3_value_text(argv[0]) );
if( z2 ){
z1 = contextMalloc(context, ((i64)n)+1);
if( z1 ){
for(i=0; i<n; i++){
z1[i] = (char)sqlite3Toupper(z2[i]);
}
sqlite3_result_text(context, z1, n, sqlite3_free);
}
}
}
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
char *z1;
const char *z2;
int i, n;
UNUSED_PARAMETER(argc);
z2 = (char*)sqlite3_value_text(argv[0]);
n = sqlite3_value_bytes(argv[0]);
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
assert( z2==(char*)sqlite3_value_text(argv[0]) );
if( z2 ){
z1 = contextMalloc(context, ((i64)n)+1);
if( z1 ){
for(i=0; i<n; i++){
z1[i] = sqlite3Tolower(z2[i]);
}
sqlite3_result_text(context, z1, n, sqlite3_free);
}
}
}
#if 0 /* This function is never used. */
/*
|
| ︙ | ︙ | |||
87100 87101 87102 87103 87104 87105 87106 87107 87108 87109 87110 87111 87112 87113 |
sqlite3ExprDelete(db, pWhen);
sqlite3ExprListDelete(db, pList);
sqlite3SelectDelete(db, pSelect);
if( db->mallocFailed==1 ){
fkTriggerDelete(db, pTrigger);
return 0;
}
switch( action ){
case OE_Restrict:
pStep->op = TK_SELECT;
break;
case OE_Cascade:
if( !pChanges ){
| > | 87071 87072 87073 87074 87075 87076 87077 87078 87079 87080 87081 87082 87083 87084 87085 |
sqlite3ExprDelete(db, pWhen);
sqlite3ExprListDelete(db, pList);
sqlite3SelectDelete(db, pSelect);
if( db->mallocFailed==1 ){
fkTriggerDelete(db, pTrigger);
return 0;
}
assert( pStep!=0 );
switch( action ){
case OE_Restrict:
pStep->op = TK_SELECT;
break;
case OE_Cascade:
if( !pChanges ){
|
| ︙ | ︙ | |||
90023 90024 90025 90026 90027 90028 90029 |
char **pzErrMsg /* Put error message here if not 0 */
){
sqlite3_vfs *pVfs = db->pVfs;
void *handle;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
char *zErrmsg = 0;
void **aHandle;
| | | 89995 89996 89997 89998 89999 90000 90001 90002 90003 90004 90005 90006 90007 90008 90009 |
char **pzErrMsg /* Put error message here if not 0 */
){
sqlite3_vfs *pVfs = db->pVfs;
void *handle;
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
char *zErrmsg = 0;
void **aHandle;
int nMsg = 300 + sqlite3Strlen30(zFile);
if( pzErrMsg ) *pzErrMsg = 0;
/* Ticket #1863. To avoid a creating security problems for older
** applications that relink against newer versions of SQLite, the
** ability to run load_extension is turned off by default. One
** must call sqlite3_enable_load_extension() to turn on extension
|
| ︙ | ︙ | |||
90060 90061 90062 90063 90064 90065 90066 90067 90068 90069 90070 90071 90072 90073 |
}
return SQLITE_ERROR;
}
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
sqlite3OsDlSym(pVfs, handle, zProc);
if( xInit==0 ){
if( pzErrMsg ){
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"no entry point [%s] in shared library [%s]", zProc,zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
sqlite3OsDlClose(pVfs, handle);
| > | 90032 90033 90034 90035 90036 90037 90038 90039 90040 90041 90042 90043 90044 90045 90046 |
}
return SQLITE_ERROR;
}
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
sqlite3OsDlSym(pVfs, handle, zProc);
if( xInit==0 ){
if( pzErrMsg ){
nMsg += sqlite3Strlen30(zProc);
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
if( zErrmsg ){
sqlite3_snprintf(nMsg, zErrmsg,
"no entry point [%s] in shared library [%s]", zProc,zFile);
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
}
sqlite3OsDlClose(pVfs, handle);
|
| ︙ | ︙ | |||
90745 90746 90747 90748 90749 90750 90751 |
if( sqlite3StrICmp(zLeft,"page_count")==0
|| sqlite3StrICmp(zLeft,"max_page_count")==0
){
int iReg;
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3CodeVerifySchema(pParse, iDb);
iReg = ++pParse->nMem;
| | | 90718 90719 90720 90721 90722 90723 90724 90725 90726 90727 90728 90729 90730 90731 90732 |
if( sqlite3StrICmp(zLeft,"page_count")==0
|| sqlite3StrICmp(zLeft,"max_page_count")==0
){
int iReg;
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
sqlite3CodeVerifySchema(pParse, iDb);
iReg = ++pParse->nMem;
if( sqlite3Tolower(zLeft[0])=='p' ){
sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
}else{
sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight));
}
sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT);
|
| ︙ | ︙ | |||
91358 91359 91360 91361 91362 91363 91364 |
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
{ OP_IfNeg, 1, 0, 0}, /* 1 */
{ OP_String8, 0, 3, 0}, /* 2 */
{ OP_ResultRow, 3, 1, 0},
};
| | | 91331 91332 91333 91334 91335 91336 91337 91338 91339 91340 91341 91342 91343 91344 91345 |
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
{ OP_IfNeg, 1, 0, 0}, /* 1 */
{ OP_String8, 0, 3, 0}, /* 2 */
{ OP_ResultRow, 3, 1, 0},
};
int isQuick = (sqlite3Tolower(zLeft[0])=='q');
/* Initialize the VDBE program */
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
pParse->nMem = 6;
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", SQLITE_STATIC);
|
| ︙ | ︙ | |||
93940 93941 93942 93943 93944 93945 93946 |
|| p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){
/* If the column contains an "AS <name>" phrase, use <name> as the name */
zName = sqlite3DbStrDup(db, zName);
}else{
Expr *pColExpr = p; /* The expression that is the result column name */
Table *pTab; /* Table associated with this expression */
| | > > > | 93913 93914 93915 93916 93917 93918 93919 93920 93921 93922 93923 93924 93925 93926 93927 93928 93929 93930 |
|| p->pRight->u.zToken==0 || p->pRight->u.zToken[0]!=0 );
if( (zName = pEList->a[i].zName)!=0 ){
/* If the column contains an "AS <name>" phrase, use <name> as the name */
zName = sqlite3DbStrDup(db, zName);
}else{
Expr *pColExpr = p; /* The expression that is the result column name */
Table *pTab; /* Table associated with this expression */
while( pColExpr->op==TK_DOT ){
pColExpr = pColExpr->pRight;
assert( pColExpr!=0 );
}
if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
/* For columns use the column name name */
int iCol = pColExpr->iColumn;
pTab = pColExpr->pTab;
if( iCol<0 ) iCol = pTab->iPKey;
zName = sqlite3MPrintf(db, "%s",
iCol>=0 ? pTab->aCol[iCol].zName : "rowid");
|
| ︙ | ︙ | |||
98938 98939 98940 98941 98942 98943 98944 98945 98946 98947 98948 98949 98950 98951 |
if( pIdx->onError==OE_Replace ){
openAll = 1;
break;
}
}
}
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( openAll || aRegIdx[i]>0 ){
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
(char*)pKey, P4_KEYINFO_HANDOFF);
assert( pParse->nTab>iCur+i+1 );
}
}
| > | 98914 98915 98916 98917 98918 98919 98920 98921 98922 98923 98924 98925 98926 98927 98928 |
if( pIdx->onError==OE_Replace ){
openAll = 1;
break;
}
}
}
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
assert( aRegIdx );
if( openAll || aRegIdx[i]>0 ){
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
(char*)pKey, P4_KEYINFO_HANDOFF);
assert( pParse->nTab>iCur+i+1 );
}
}
|
| ︙ | ︙ | |||
99111 99112 99113 99114 99115 99116 99117 99118 99119 99120 99121 99122 99123 99124 |
** all record selected by the WHERE clause have been updated.
*/
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
sqlite3VdbeJumpHere(v, addr);
/* Close all tables */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( openAll || aRegIdx[i]>0 ){
sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
}
}
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
/* Update the sqlite_sequence table by storing the content of the
| > | 99088 99089 99090 99091 99092 99093 99094 99095 99096 99097 99098 99099 99100 99101 99102 |
** all record selected by the WHERE clause have been updated.
*/
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
sqlite3VdbeJumpHere(v, addr);
/* Close all tables */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
assert( aRegIdx );
if( openAll || aRegIdx[i]>0 ){
sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
}
}
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
/* Update the sqlite_sequence table by storing the content of the
|
| ︙ | ︙ | |||
103142 103143 103144 103145 103146 103147 103148 | double r, rS; assert( roundUp==0 || roundUp==1 ); assert( pIdx->nSample>0 ); if( pVal==0 ) return SQLITE_ERROR; n = pIdx->aiRowEst[0]; aSample = pIdx->aSample; | < | 103120 103121 103122 103123 103124 103125 103126 103127 103128 103129 103130 103131 103132 103133 |
double r, rS;
assert( roundUp==0 || roundUp==1 );
assert( pIdx->nSample>0 );
if( pVal==0 ) return SQLITE_ERROR;
n = pIdx->aiRowEst[0];
aSample = pIdx->aSample;
eType = sqlite3_value_type(pVal);
if( eType==SQLITE_INTEGER ){
v = sqlite3_value_int64(pVal);
r = (i64)v;
for(i=0; i<pIdx->nSample; i++){
if( aSample[i].eType==SQLITE_NULL ) continue;
|
| ︙ | ︙ | |||
105562 105563 105564 105565 105566 105567 105568 |
}
}
assert( bestJ>=0 );
assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
WHERETRACE(("*** Optimizer selects table %d for loop %d"
" with cost=%g and nRow=%g\n",
bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
| > | | 105539 105540 105541 105542 105543 105544 105545 105546 105547 105548 105549 105550 105551 105552 105553 105554 |
}
}
assert( bestJ>=0 );
assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
WHERETRACE(("*** Optimizer selects table %d for loop %d"
" with cost=%g and nRow=%g\n",
bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
/* The ALWAYS() that follows was added to hush up clang scan-build */
if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
*ppOrderBy = 0;
}
if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
assert( pWInfo->eDistinct==0 );
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
}
andFlags &= bestPlan.plan.wsFlags;
|
| ︙ | ︙ | |||
109178 109179 109180 109181 109182 109183 109184 109185 109186 109187 109188 109189 109190 109191 109192 |
void *yyp, /* The parser */
int yymajor, /* The major token code number */
sqlite3ParserTOKENTYPE yyminor /* The value for the token */
sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
){
YYMINORTYPE yyminorunion;
int yyact; /* The parser action. */
int yyendofinput; /* True if we are at the end of input */
#ifdef YYERRORSYMBOL
int yyerrorhit = 0; /* True if yymajor has invoked an error */
#endif
yyParser *yypParser; /* The parser */
/* (re)initialize the parser, if necessary */
yypParser = (yyParser*)yyp;
| > > | 109156 109157 109158 109159 109160 109161 109162 109163 109164 109165 109166 109167 109168 109169 109170 109171 109172 |
void *yyp, /* The parser */
int yymajor, /* The major token code number */
sqlite3ParserTOKENTYPE yyminor /* The value for the token */
sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
){
YYMINORTYPE yyminorunion;
int yyact; /* The parser action. */
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
int yyendofinput; /* True if we are at the end of input */
#endif
#ifdef YYERRORSYMBOL
int yyerrorhit = 0; /* True if yymajor has invoked an error */
#endif
yyParser *yypParser; /* The parser */
/* (re)initialize the parser, if necessary */
yypParser = (yyParser*)yyp;
|
| ︙ | ︙ | |||
109201 109202 109203 109204 109205 109206 109207 109208 109209 109210 109211 109212 109213 109214 109215 109216 109217 109218 109219 |
#endif
yypParser->yyidx = 0;
yypParser->yyerrcnt = -1;
yypParser->yystack[0].stateno = 0;
yypParser->yystack[0].major = 0;
}
yyminorunion.yy0 = yyminor;
yyendofinput = (yymajor==0);
sqlite3ParserARG_STORE;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
}
#endif
do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
if( yyact<YYNSTATE ){
| > > < | 109181 109182 109183 109184 109185 109186 109187 109188 109189 109190 109191 109192 109193 109194 109195 109196 109197 109198 109199 109200 109201 109202 109203 109204 109205 109206 109207 109208 |
#endif
yypParser->yyidx = 0;
yypParser->yyerrcnt = -1;
yypParser->yystack[0].stateno = 0;
yypParser->yystack[0].major = 0;
}
yyminorunion.yy0 = yyminor;
#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
yyendofinput = (yymajor==0);
#endif
sqlite3ParserARG_STORE;
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
}
#endif
do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
if( yyact<YYNSTATE ){
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
yypParser->yyerrcnt--;
yymajor = YYNOCODE;
}else if( yyact < YYNSTATE + YYNRULE ){
yy_reduce(yypParser,yyact-YYNSTATE);
}else{
assert( yyact == YY_ERROR_ACTION );
|
| ︙ | ︙ | |||
110605 110606 110607 110608 110609 110610 110611 |
** * Calls to this routine from Y must block until the outer-most
** call by X completes.
**
** * Recursive calls to this routine from thread X return immediately
** without blocking.
*/
SQLITE_API int sqlite3_initialize(void){
| | | 110586 110587 110588 110589 110590 110591 110592 110593 110594 110595 110596 110597 110598 110599 110600 |
** * Calls to this routine from Y must block until the outer-most
** call by X completes.
**
** * Recursive calls to this routine from thread X return immediately
** without blocking.
*/
SQLITE_API int sqlite3_initialize(void){
MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
int rc; /* Result code */
#ifdef SQLITE_OMIT_WSD
rc = sqlite3_wsd_init(4096, 24);
if( rc!=SQLITE_OK ){
return rc;
}
|
| ︙ | ︙ | |||
110639 110640 110641 110642 110643 110644 110645 | /* Initialize the malloc() system and the recursive pInitMutex mutex. ** This operation is protected by the STATIC_MASTER mutex. Note that ** MutexAlloc() is called for a static mutex prior to initializing the ** malloc subsystem - this implies that the allocation of a static ** mutex must not require support from the malloc subsystem. */ | | | 110620 110621 110622 110623 110624 110625 110626 110627 110628 110629 110630 110631 110632 110633 110634 |
/* Initialize the malloc() system and the recursive pInitMutex mutex.
** This operation is protected by the STATIC_MASTER mutex. Note that
** MutexAlloc() is called for a static mutex prior to initializing the
** malloc subsystem - this implies that the allocation of a static
** mutex must not require support from the malloc subsystem.
*/
MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
sqlite3_mutex_enter(pMaster);
sqlite3GlobalConfig.isMutexInit = 1;
if( !sqlite3GlobalConfig.isMallocInit ){
rc = sqlite3MallocInit();
}
if( rc==SQLITE_OK ){
sqlite3GlobalConfig.isMallocInit = 1;
|
| ︙ | ︙ | |||
111713 111714 111715 111716 111717 111718 111719 |
*/
SQLITE_API int sqlite3_overload_function(
sqlite3 *db,
const char *zName,
int nArg
){
int nName = sqlite3Strlen30(zName);
| | | | | | 111694 111695 111696 111697 111698 111699 111700 111701 111702 111703 111704 111705 111706 111707 111708 111709 111710 111711 111712 111713 111714 |
*/
SQLITE_API int sqlite3_overload_function(
sqlite3 *db,
const char *zName,
int nArg
){
int nName = sqlite3Strlen30(zName);
int rc = SQLITE_OK;
sqlite3_mutex_enter(db->mutex);
if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
0, sqlite3InvalidFunction, 0, 0, 0);
}
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#ifndef SQLITE_OMIT_TRACE
/*
** Register a trace function. The pArg from the previously registered trace
|
| ︙ | ︙ | |||
112781 112782 112783 112784 112785 112786 112787 112788 112789 112790 112791 112792 112793 112794 |
opendb_out:
sqlite3_free(zOpen);
if( db ){
assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
sqlite3_mutex_leave(db->mutex);
}
rc = sqlite3_errcode(db);
if( rc==SQLITE_NOMEM ){
sqlite3_close(db);
db = 0;
}else if( rc!=SQLITE_OK ){
db->magic = SQLITE_MAGIC_SICK;
}
*ppDb = db;
| > | 112762 112763 112764 112765 112766 112767 112768 112769 112770 112771 112772 112773 112774 112775 112776 |
opendb_out:
sqlite3_free(zOpen);
if( db ){
assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
sqlite3_mutex_leave(db->mutex);
}
rc = sqlite3_errcode(db);
assert( db!=0 || rc==SQLITE_NOMEM );
if( rc==SQLITE_NOMEM ){
sqlite3_close(db);
db = 0;
}else if( rc!=SQLITE_OK ){
db->magic = SQLITE_MAGIC_SICK;
}
*ppDb = db;
|
| ︙ | ︙ | |||
114509 114510 114511 114512 114513 114514 114515 114516 114517 114518 114519 114520 114521 114522 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) # define TESTONLY(X) X #else # define TESTONLY(X) #endif #endif /* SQLITE_AMALGAMATION */ typedef struct Fts3Table Fts3Table; typedef struct Fts3Cursor Fts3Cursor; typedef struct Fts3Expr Fts3Expr; typedef struct Fts3Phrase Fts3Phrase; typedef struct Fts3PhraseToken Fts3PhraseToken; | > > > > > > > | 114491 114492 114493 114494 114495 114496 114497 114498 114499 114500 114501 114502 114503 114504 114505 114506 114507 114508 114509 114510 114511 | #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) # define TESTONLY(X) X #else # define TESTONLY(X) #endif #endif /* SQLITE_AMALGAMATION */ #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); # define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt() #else # define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB #endif typedef struct Fts3Table Fts3Table; typedef struct Fts3Cursor Fts3Cursor; typedef struct Fts3Expr Fts3Expr; typedef struct Fts3Phrase Fts3Phrase; typedef struct Fts3PhraseToken Fts3PhraseToken; |
| ︙ | ︙ | |||
115010 115011 115012 115013 115014 115015 115016 |
*/
static void fts3GetReverseVarint(
char **pp,
char *pStart,
sqlite3_int64 *pVal
){
sqlite3_int64 iVal;
| | | 114999 115000 115001 115002 115003 115004 115005 115006 115007 115008 115009 115010 115011 115012 115013 |
*/
static void fts3GetReverseVarint(
char **pp,
char *pStart,
sqlite3_int64 *pVal
){
sqlite3_int64 iVal;
char *p;
/* Pointer p now points at the first byte past the varint we are
** interested in. So, unless the doclist is corrupt, the 0x80 bit is
** clear on character p[-1]. */
for(p = (*pp)-2; p>=pStart && *p&0x80; p--);
p++;
*pp = p;
|
| ︙ | ︙ | |||
115411 115412 115413 115414 115415 115416 115417 |
**
** If *pp does not being with a decimal digit SQLITE_ERROR is returned and
** the output value undefined. Otherwise SQLITE_OK is returned.
**
** This function is used when parsing the "prefix=" FTS4 parameter.
*/
static int fts3GobbleInt(const char **pp, int *pnOut){
| | | 115400 115401 115402 115403 115404 115405 115406 115407 115408 115409 115410 115411 115412 115413 115414 |
**
** If *pp does not being with a decimal digit SQLITE_ERROR is returned and
** the output value undefined. Otherwise SQLITE_OK is returned.
**
** This function is used when parsing the "prefix=" FTS4 parameter.
*/
static int fts3GobbleInt(const char **pp, int *pnOut){
const char *p; /* Iterator pointer */
int nInt = 0; /* Output value */
for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
nInt = nInt * 10 + (p[0] - '0');
}
if( p==*pp ) return SQLITE_ERROR;
*pnOut = nInt;
|
| ︙ | ︙ | |||
115910 115911 115912 115913 115914 115915 115916 |
}else{
int rc = sqlite3_reset(pCsr->pStmt);
if( rc==SQLITE_OK ){
/* If no row was found and no error has occured, then the %_content
** table is missing a row that is present in the full-text index.
** The data structures are corrupt.
*/
| | | 115899 115900 115901 115902 115903 115904 115905 115906 115907 115908 115909 115910 115911 115912 115913 |
}else{
int rc = sqlite3_reset(pCsr->pStmt);
if( rc==SQLITE_OK ){
/* If no row was found and no error has occured, then the %_content
** table is missing a row that is present in the full-text index.
** The data structures are corrupt.
*/
rc = FTS_CORRUPT_VTAB;
}
pCsr->isEof = 1;
if( pContext ){
sqlite3_result_error_code(pContext, rc);
}
return rc;
}
|
| ︙ | ︙ | |||
115970 115971 115972 115973 115974 115975 115976 |
** contents, or two zero bytes. Or, if the node is read from the %_segments
** table, then there are always 20 bytes of zeroed padding following the
** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
*/
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
if( zCsr>zEnd ){
| | | > | 115959 115960 115961 115962 115963 115964 115965 115966 115967 115968 115969 115970 115971 115972 115973 115974 115975 115976 115977 115978 115979 115980 115981 115982 115983 115984 115985 115986 115987 115988 115989 115990 115991 115992 115993 115994 115995 115996 115997 115998 115999 116000 116001 116002 116003 116004 |
** contents, or two zero bytes. Or, if the node is read from the %_segments
** table, then there are always 20 bytes of zeroed padding following the
** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
*/
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
if( zCsr>zEnd ){
return FTS_CORRUPT_VTAB;
}
while( zCsr<zEnd && (piFirst || piLast) ){
int cmp; /* memcmp() result */
int nSuffix; /* Size of term suffix */
int nPrefix = 0; /* Size of term prefix */
int nBuffer; /* Total term size */
/* Load the next term on the node into zBuffer. Use realloc() to expand
** the size of zBuffer if required. */
if( !isFirstTerm ){
zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix);
}
isFirstTerm = 0;
zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
rc = FTS_CORRUPT_VTAB;
goto finish_scan;
}
if( nPrefix+nSuffix>nAlloc ){
char *zNew;
nAlloc = (nPrefix+nSuffix) * 2;
zNew = (char *)sqlite3_realloc(zBuffer, nAlloc);
if( !zNew ){
rc = SQLITE_NOMEM;
goto finish_scan;
}
zBuffer = zNew;
}
assert( zBuffer );
memcpy(&zBuffer[nPrefix], zCsr, nSuffix);
nBuffer = nPrefix + nSuffix;
zCsr += nSuffix;
/* Compare the term we are searching for with the term just loaded from
** the interior node. If the specified term is greater than or equal
** to the term from the interior node, then all terms on the sub-tree
|
| ︙ | ︙ | |||
117437 117438 117439 117440 117441 117442 117443 |
** When called, *ppPoslist must point to the byte immediately following the
** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function
** moves *ppPoslist so that it instead points to the first byte of the
** same position list.
*/
static void fts3ReversePoslist(char *pStart, char **ppPoslist){
char *p = &(*ppPoslist)[-2];
| | | 117427 117428 117429 117430 117431 117432 117433 117434 117435 117436 117437 117438 117439 117440 117441 |
** When called, *ppPoslist must point to the byte immediately following the
** end of a position-list. i.e. ( (*ppPoslist)[-1]==POS_END ). This function
** moves *ppPoslist so that it instead points to the first byte of the
** same position list.
*/
static void fts3ReversePoslist(char *pStart, char **ppPoslist){
char *p = &(*ppPoslist)[-2];
char c = 0;
while( p>pStart && (c=*p--)==0 );
while( p>pStart && (*p & 0x80) | c ){
c = *p--;
}
if( p>pStart ){ p = &p[2]; }
while( *p++&0x80 );
|
| ︙ | ︙ | |||
118431 118432 118433 118434 118435 118436 118437 |
pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
a += sqlite3Fts3GetVarint(a, &nDoc);
while( a<pEnd ){
a += sqlite3Fts3GetVarint(a, &nByte);
}
if( nDoc==0 || nByte==0 ){
sqlite3_reset(pStmt);
| | | 118421 118422 118423 118424 118425 118426 118427 118428 118429 118430 118431 118432 118433 118434 118435 |
pEnd = &a[sqlite3_column_bytes(pStmt, 0)];
a += sqlite3Fts3GetVarint(a, &nDoc);
while( a<pEnd ){
a += sqlite3Fts3GetVarint(a, &nByte);
}
if( nDoc==0 || nByte==0 ){
sqlite3_reset(pStmt);
return FTS_CORRUPT_VTAB;
}
pCsr->nDoc = nDoc;
pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
assert( pCsr->nRowAvg>0 );
rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ) return rc;
|
| ︙ | ︙ | |||
118907 118908 118909 118910 118911 118912 118913 |
int nNear = p->nNear;
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
}
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
nToken = pExpr->pRight->pPhrase->nToken;
for(p=pExpr->pLeft; p && res; p=p->pLeft){
| > > > | | | 118897 118898 118899 118900 118901 118902 118903 118904 118905 118906 118907 118908 118909 118910 118911 118912 118913 118914 118915 |
int nNear = p->nNear;
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
}
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
nToken = pExpr->pRight->pPhrase->nToken;
for(p=pExpr->pLeft; p && res; p=p->pLeft){
int nNear;
Fts3Phrase *pPhrase;
assert( p->pParent && p->pParent->pLeft==p );
nNear = p->pParent->nNear;
pPhrase = (
p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
);
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
}
}
sqlite3_free(aTmp);
|
| ︙ | ︙ | |||
119398 119399 119400 119401 119402 119403 119404 119405 119406 119407 119408 119409 119410 119411 |
for(i=0; i<pPhrase->nToken; i++){
fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr);
pPhrase->aToken[i].pSegcsr = 0;
}
}
}
#if !SQLITE_CORE
/*
** Initialize API pointer table, if required.
*/
SQLITE_API int sqlite3_extension_init(
sqlite3 *db,
char **pzErrMsg,
| > > > > > > > > > | 119391 119392 119393 119394 119395 119396 119397 119398 119399 119400 119401 119402 119403 119404 119405 119406 119407 119408 119409 119410 119411 119412 119413 |
for(i=0; i<pPhrase->nToken; i++){
fts3SegReaderCursorFree(pPhrase->aToken[i].pSegcsr);
pPhrase->aToken[i].pSegcsr = 0;
}
}
}
/*
** Return SQLITE_CORRUPT_VTAB.
*/
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
return SQLITE_CORRUPT_VTAB;
}
#endif
#if !SQLITE_CORE
/*
** Initialize API pointer table, if required.
*/
SQLITE_API int sqlite3_extension_init(
sqlite3 *db,
char **pzErrMsg,
|
| ︙ | ︙ | |||
120195 120196 120197 120198 120199 120200 120201 |
memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p);
p->eType = FTSQUERY_PHRASE;
p->pPhrase = (Fts3Phrase *)&p[1];
p->pPhrase->iColumn = pParse->iDefaultCol;
p->pPhrase->nToken = nToken;
zBuf = (char *)&p->pPhrase->aToken[nToken];
| > | | > > > | 120197 120198 120199 120200 120201 120202 120203 120204 120205 120206 120207 120208 120209 120210 120211 120212 120213 120214 120215 120216 |
memset(p, 0, (char *)&(((Fts3Phrase *)&p[1])->aToken[0])-(char *)p);
p->eType = FTSQUERY_PHRASE;
p->pPhrase = (Fts3Phrase *)&p[1];
p->pPhrase->iColumn = pParse->iDefaultCol;
p->pPhrase->nToken = nToken;
zBuf = (char *)&p->pPhrase->aToken[nToken];
if( zTemp ){
memcpy(zBuf, zTemp, nTemp);
sqlite3_free(zTemp);
}else{
assert( nTemp==0 );
}
for(jj=0; jj<p->pPhrase->nToken; jj++){
p->pPhrase->aToken[jj].z = zBuf;
zBuf += p->pPhrase->aToken[jj].n;
}
rc = SQLITE_OK;
}
|
| ︙ | ︙ | |||
122955 122956 122957 122958 122959 122960 122961 |
if( rc==SQLITE_OK ){
if( eStmt==SQL_SELECT_DOCSIZE ){
sqlite3_bind_int64(pStmt, 1, iDocid);
}
rc = sqlite3_step(pStmt);
if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
rc = sqlite3_reset(pStmt);
| | | 122961 122962 122963 122964 122965 122966 122967 122968 122969 122970 122971 122972 122973 122974 122975 |
if( rc==SQLITE_OK ){
if( eStmt==SQL_SELECT_DOCSIZE ){
sqlite3_bind_int64(pStmt, 1, iDocid);
}
rc = sqlite3_step(pStmt);
if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
rc = sqlite3_reset(pStmt);
if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB;
pStmt = 0;
}else{
rc = SQLITE_OK;
}
}
*ppStmt = pStmt;
|
| ︙ | ︙ | |||
123759 123760 123761 123762 123763 123764 123765 |
/* Because of the FTS3_NODE_PADDING bytes of padding, the following is
** safe (no risk of overread) even if the node data is corrupted. */
pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
if( nPrefix<0 || nSuffix<=0
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
){
| | | 123765 123766 123767 123768 123769 123770 123771 123772 123773 123774 123775 123776 123777 123778 123779 |
/* Because of the FTS3_NODE_PADDING bytes of padding, the following is
** safe (no risk of overread) even if the node data is corrupted. */
pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
if( nPrefix<0 || nSuffix<=0
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
){
return FTS_CORRUPT_VTAB;
}
if( nPrefix+nSuffix>pReader->nTermAlloc ){
int nNew = (nPrefix+nSuffix)*2;
char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
if( !zNew ){
return SQLITE_NOMEM;
|
| ︙ | ︙ | |||
123789 123790 123791 123792 123793 123794 123795 |
/* Check that the doclist does not appear to extend past the end of the
** b-tree node. And that the final byte of the doclist is 0x00. If either
** of these statements is untrue, then the data structure is corrupt.
*/
if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
){
| | | 123795 123796 123797 123798 123799 123800 123801 123802 123803 123804 123805 123806 123807 123808 123809 |
/* Check that the doclist does not appear to extend past the end of the
** b-tree node. And that the final byte of the doclist is 0x00. If either
** of these statements is untrue, then the data structure is corrupt.
*/
if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
){
return FTS_CORRUPT_VTAB;
}
return SQLITE_OK;
}
/*
** Set the SegReader to point to the first docid in the doclist associated
** with the current term.
|
| ︙ | ︙ | |||
125743 125744 125745 125746 125747 125748 125749 |
int nArg, /* Size of argument array */
sqlite3_value **apVal, /* Array of arguments */
sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
){
Fts3Table *p = (Fts3Table *)pVtab;
int rc = SQLITE_OK; /* Return Code */
int isRemove = 0; /* True for an UPDATE or DELETE */
| < | 125749 125750 125751 125752 125753 125754 125755 125756 125757 125758 125759 125760 125761 125762 |
int nArg, /* Size of argument array */
sqlite3_value **apVal, /* Array of arguments */
sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
){
Fts3Table *p = (Fts3Table *)pVtab;
int rc = SQLITE_OK; /* Return Code */
int isRemove = 0; /* True for an UPDATE or DELETE */
u32 *aSzIns = 0; /* Sizes of inserted documents */
u32 *aSzDel; /* Sizes of deleted documents */
int nChng = 0; /* Net change in number of documents */
int bInsertDone = 0;
assert( p->pSegments==0 );
|
| ︙ | ︙ | |||
125826 125827 125828 125829 125830 125831 125832 |
}
/* If this is a DELETE or UPDATE operation, remove the old record. */
if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
isRemove = 1;
| < | | > | 125831 125832 125833 125834 125835 125836 125837 125838 125839 125840 125841 125842 125843 125844 125845 125846 125847 125848 125849 125850 125851 125852 125853 125854 125855 125856 125857 |
}
/* If this is a DELETE or UPDATE operation, remove the old record. */
if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
isRemove = 1;
}
/* If this is an INSERT or UPDATE operation, insert the new record. */
if( nArg>1 && rc==SQLITE_OK ){
if( bInsertDone==0 ){
rc = fts3InsertData(p, apVal, pRowid);
if( rc==SQLITE_CONSTRAINT ) rc = FTS_CORRUPT_VTAB;
}
if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
rc = fts3PendingTermsDocid(p, *pRowid);
}
if( rc==SQLITE_OK ){
assert( p->iPrevDocid==*pRowid );
rc = fts3InsertTerms(p, apVal, aSzIns);
}
if( p->bHasDocsize ){
fts3InsertDocsize(&rc, p, aSzIns);
}
nChng++;
}
|
| ︙ | ︙ | |||
126732 126733 126734 126735 126736 126737 126738 |
if( rc!=SQLITE_OK ) return rc;
}
pStmt = *ppStmt;
assert( sqlite3_data_count(pStmt)==1 );
a = sqlite3_column_blob(pStmt, 0);
a += sqlite3Fts3GetVarint(a, &nDoc);
| | | 126737 126738 126739 126740 126741 126742 126743 126744 126745 126746 126747 126748 126749 126750 126751 |
if( rc!=SQLITE_OK ) return rc;
}
pStmt = *ppStmt;
assert( sqlite3_data_count(pStmt)==1 );
a = sqlite3_column_blob(pStmt, 0);
a += sqlite3Fts3GetVarint(a, &nDoc);
if( nDoc==0 ) return FTS_CORRUPT_VTAB;
*pnDoc = (u32)nDoc;
if( paLen ) *paLen = a;
return SQLITE_OK;
}
/*
|
| ︙ | ︙ | |||
127311 127312 127313 127314 127315 127316 127317 |
if( rc==SQLITE_OK ){
char aBuffer[64];
sqlite3_snprintf(sizeof(aBuffer), aBuffer,
"%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart
);
rc = fts3StringAppend(&res, aBuffer, -1);
}else if( rc==SQLITE_DONE ){
| | | 127316 127317 127318 127319 127320 127321 127322 127323 127324 127325 127326 127327 127328 127329 127330 |
if( rc==SQLITE_OK ){
char aBuffer[64];
sqlite3_snprintf(sizeof(aBuffer), aBuffer,
"%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart
);
rc = fts3StringAppend(&res, aBuffer, -1);
}else if( rc==SQLITE_DONE ){
rc = FTS_CORRUPT_VTAB;
}
}
}
if( rc==SQLITE_DONE ){
rc = SQLITE_OK;
}
|
| ︙ | ︙ | |||
128652 128653 128654 128655 128656 128657 128658 |
if( argc>0 ){
pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
pCsr->nConstraint = argc;
if( !pCsr->aConstraint ){
rc = SQLITE_NOMEM;
}else{
memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
| | > | 128657 128658 128659 128660 128661 128662 128663 128664 128665 128666 128667 128668 128669 128670 128671 128672 |
if( argc>0 ){
pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
pCsr->nConstraint = argc;
if( !pCsr->aConstraint ){
rc = SQLITE_NOMEM;
}else{
memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
assert( (idxStr==0 && argc==0)
|| (idxStr && (int)strlen(idxStr)==argc*2) );
for(ii=0; ii<argc; ii++){
RtreeConstraint *p = &pCsr->aConstraint[ii];
p->op = idxStr[ii*2];
p->iCoord = idxStr[ii*2+1]-'a';
if( p->op==RTREE_MATCH ){
/* A MATCH operator. The right-hand-side must be a blob that
** can be cast into an RtreeMatchArg object. One created using
|
| ︙ | ︙ | |||
128953 128954 128955 128956 128957 128958 128959 128960 128961 128962 128963 128964 128965 128966 128967 |
for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
int iCell;
sqlite3_int64 iBest = 0;
float fMinGrowth = 0.0;
float fMinArea = 0.0;
float fMinOverlap = 0.0;
int nCell = NCELL(pNode);
RtreeCell cell;
RtreeNode *pChild;
RtreeCell *aCell = 0;
| > > > | 128959 128960 128961 128962 128963 128964 128965 128966 128967 128968 128969 128970 128971 128972 128973 128974 128975 128976 |
for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
int iCell;
sqlite3_int64 iBest = 0;
float fMinGrowth = 0.0;
float fMinArea = 0.0;
#if VARIANT_RSTARTREE_CHOOSESUBTREE
float fMinOverlap = 0.0;
float overlap;
#endif
int nCell = NCELL(pNode);
RtreeCell cell;
RtreeNode *pChild;
RtreeCell *aCell = 0;
|
| ︙ | ︙ | |||
128985 128986 128987 128988 128989 128990 128991 |
** is inserted into it. Resolve ties by choosing the entry with
** the smallest area.
*/
for(iCell=0; iCell<nCell; iCell++){
int bBest = 0;
float growth;
float area;
| < > > > < | 128994 128995 128996 128997 128998 128999 129000 129001 129002 129003 129004 129005 129006 129007 129008 129009 129010 129011 129012 129013 129014 129015 129016 129017 129018 129019 129020 129021 129022 129023 129024 129025 129026 129027 129028 129029 129030 129031 |
** is inserted into it. Resolve ties by choosing the entry with
** the smallest area.
*/
for(iCell=0; iCell<nCell; iCell++){
int bBest = 0;
float growth;
float area;
nodeGetCell(pRtree, pNode, iCell, &cell);
growth = cellGrowth(pRtree, &cell, pCell);
area = cellArea(pRtree, &cell);
#if VARIANT_RSTARTREE_CHOOSESUBTREE
if( ii==(pRtree->iDepth-1) ){
overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
}else{
overlap = 0.0;
}
if( (iCell==0)
|| (overlap<fMinOverlap)
|| (overlap==fMinOverlap && growth<fMinGrowth)
|| (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
){
bBest = 1;
fMinOverlap = overlap;
}
#else
if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){
bBest = 1;
}
#endif
if( bBest ){
fMinGrowth = growth;
fMinArea = area;
iBest = cell.iRowid;
}
}
sqlite3_free(aCell);
|
| ︙ | ︙ |
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.7.9" #define SQLITE_VERSION_NUMBER 3007009 | | | 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.7.9" #define SQLITE_VERSION_NUMBER 3007009 #define SQLITE_SOURCE_ID "2011-10-15 00:16:30 39408702a989f907261c298bf0947f3e68bd10fe" /* ** 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 |
| ︙ | ︙ | |||
2800 2801 2802 2803 2804 2805 2806 | ** first zero terminator. ^If nByte is non-negative, then it is the maximum ** number of bytes read from zSql. ^When nByte is non-negative, the ** zSql string ends at either the first '\000' or '\u0000' character or ** the nByte-th byte, whichever comes first. If the caller knows ** that the supplied string is nul-terminated, then there is a small ** performance advantage to be gained by passing an nByte parameter that ** is equal to the number of bytes in the input string <i>including</i> | | > | 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 | ** first zero terminator. ^If nByte is non-negative, then it is the maximum ** number of bytes read from zSql. ^When nByte is non-negative, the ** zSql string ends at either the first '\000' or '\u0000' character or ** the nByte-th byte, whichever comes first. If the caller knows ** that the supplied string is nul-terminated, then there is a small ** performance advantage to be gained by passing an nByte parameter that ** is equal to the number of bytes in the input string <i>including</i> ** the nul-terminator bytes as this saves SQLite from having to ** make a copy of the input string. ** ** ^If pzTail is not NULL then *pzTail is made to point to the first byte ** past the end of the first SQL statement in zSql. These routines only ** compile the first statement in zSql, so *pzTail is left pointing to ** what remains uncompiled. ** ** ^*ppStmt is left pointing to a compiled [prepared statement] that can be |
| ︙ | ︙ | |||
3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 | ** ^The third argument is the value to bind to the parameter. ** ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of <u>bytes</u> in the value, not the number of characters.)^ ** ^If the fourth parameter is negative, the length of the string is ** the number of bytes up to the first zero terminator. ** ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or ** string after SQLite has finished with it. ^The destructor is called ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(), ** sqlite3_bind_text(), or sqlite3_bind_text16() fails. ** ^If the fifth argument is | > > > > > > > | 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 | ** ^The third argument is the value to bind to the parameter. ** ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of <u>bytes</u> in the value, not the number of characters.)^ ** ^If the fourth parameter is negative, the length of the string is ** the number of bytes up to the first zero terminator. ** If a non-negative fourth parameter is provided to sqlite3_bind_text() ** or sqlite3_bind_text16() then that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL ** terminated. If any NUL characters occur at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. ** ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or ** string after SQLite has finished with it. ^The destructor is called ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(), ** sqlite3_bind_text(), or sqlite3_bind_text16() fails. ** ^If the fifth argument is |
| ︙ | ︙ | |||
4039 4040 4041 4042 4043 4044 4045 | ** the 2nd parameter of the sqlite3_result_text* interfaces. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is negative, then SQLite takes result text from the 2nd parameter ** through the first zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined | | > > > > > | 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 | ** the 2nd parameter of the sqlite3_result_text* interfaces. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is negative, then SQLite takes result text from the 2nd parameter ** through the first zero character. ** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it ** must be the byte offset into the string where the NUL terminator would ** appear if the string where NUL terminated. If any NUL characters occur ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. ** ^If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or BLOB result when it has ** finished using that result. ** ^If the 4th parameter to the sqlite3_result_text* interfaces or to ** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite ** assumes that the text or BLOB result is in constant space and does not |
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
801 802 803 804 805 806 807 808 809 |
/*
** WEBPAGE: test_env
*/
void page_test_env(void){
char c;
int i;
char zCap[30];
login_check_credentials();
| > | > > > > > > > > > > > | | 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 |
/*
** WEBPAGE: test_env
*/
void page_test_env(void){
char c;
int i;
int showAll;
char zCap[30];
login_check_credentials();
if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){
login_needed();
return;
}
style_header("Environment Test");
showAll = atoi(PD("showall","0"));
if( !showAll ){
style_submenu_element("Show Cookies", "Show Cookies",
"%s/test_env?showall=1", g.zTop);
}else{
style_submenu_element("Hide Cookies", "Hide Cookies",
"%s/test_env", g.zTop);
}
#if !defined(_WIN32)
@ uid=%d(getuid()), gid=%d(getgid())<br />
#endif
@ g.zBaseURL = %h(g.zBaseURL)<br />
@ g.zTop = %h(g.zTop)<br />
for(i=0, c='a'; c<='z'; c++){
if( login_has_capability(&c, 1) ) zCap[i++] = c;
}
zCap[i] = 0;
@ g.userUid = %d(g.userUid)<br />
@ g.zLogin = %h(g.zLogin)<br />
@ capabilities = %s(zCap)<br />
@ <hr>
cgi_print_all(atoi(PD("showall","0")));
if( g.perm.Setup ){
const char *zRedir = P("redirect");
if( zRedir ) cgi_redirect(zRedir);
}
style_footer();
}
|
Changes to www/fossil-v-git.wiki.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 |
<h2>2.0 Executive Summary:</h2>
<blockquote><center><table border=1 cellpadding=5>
<tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
<tr><td>File versioning only</td>
<td>Versioning, Tickets, Wiki, and Blog/News</td></tr>
<tr><td>Sharding</td><td>Replicating</td></tr>
| | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<h2>2.0 Executive Summary:</h2>
<blockquote><center><table border=1 cellpadding=5>
<tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
<tr><td>File versioning only</td>
<td>Versioning, Tickets, Wiki, and Blog/News</td></tr>
<tr><td>Sharding</td><td>Replicating</td></tr>
<tr><td>Developer branches</td><td>Feature branches</td></tr>
<tr><td>Complex</td><td>Intuitive</td></tr>
<tr><td>Separate web tools</td><td>Integrated Web interface</td></tr>
<tr><td>Lots of little tools</td><td>Single executable</td></tr>
<tr><td>Pile-of-files repository</td><td>Single file repository</td></tr>
<tr><td>Uses "<tt>rebase</tt>"</td><td>Immutable</td></tr>
<tr><td>GPL</td><td>BSD</td></tr>
</table></center></blockquote>
|
| ︙ | ︙ | |||
77 78 79 80 81 82 83 | developers are operating directly on the master branch, or at most a small number of well defined branches. The [concepts.wiki#workflow | autosync] mode of Fossil makes it easy for multiple developers to work on a single branch and maintain linear development on that branch and avoid needless forking and merging. | | | | > > > > > > > > > | > > < > > | > > > > > | < < < < < < < < < < < < > > < | < < > > > > > > > | 77 78 79 80 81 82 83 84 85 86 87 88 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 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | developers are operating directly on the master branch, or at most a small number of well defined branches. The [concepts.wiki#workflow | autosync] mode of Fossil makes it easy for multiple developers to work on a single branch and maintain linear development on that branch and avoid needless forking and merging. <h3>3.3 Branches</h3> Git (and especially GitHub) encourages a workflow where each developer has his or her own branch or branches. Developers then send "pull requests" to have their changes be merged into "official" branches by integrators. For example, the Linux kernel team has a hierarchy of integrators with Linus Torvalds at the root. Individual developers each have their own private branches of the source tree into which they make their own changes. They then encourage first-tier integrators to pull those changes. The first-tier integrators merge together changes from multiple contributors then try to get second-tier integrators to pull their branches. The changes merge up the the hierarchy until (hopefully) they are pulled into "Linus's branch", at which time they become part of the "official" Linux. In Git, each branch is "owned" by the person who creates it and works on it. The owner might pull changes from others, but the owner is always in control of the branch. Branches are developer-centric. Fossil, on the other hand, encourages a workflow where branches are associated with features or releases, not individual developers. All developers share all branches in common, and two or more developers can and often do intersperse commits onto the same branch. Branches do not belong to individuals. All branches are read/write accessible to all developers at all times. There is no need for integrators to merge together changes from various independent developers. Instead, all of the developers work together cooperatively and the changes stay integrated naturally. So to a first approximation, branches in Git are developer-centric whereas branches in Fossil are feature-centric. The Git approach scales much better for large projects like the Linux kernel with thousands of contributors who in many cases don't even know each others names. The integrators serve a gatekeeper role to help keep undesirable code out of the official Linux source tree. On the other hand, not many projects are as big or as loosely organized as the Linux kernel. Most project, have a small team of developers who all know each other well and trust each other, and who enjoy working together collaboratively without the overhead and hierarchy of integrators. <h3>3.4 Complexity</h3> Git is a complex system. It can be tricky to use and requires a fair amount of knowledge and experience to master. Fossil strives to be a much simpler system that can be learned and mastered much more quickly. Fossil strives to have fewer "gotchas" and quirks that can trip up a |
| ︙ | ︙ |