Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | merge trunk again... (previous merge was not from latest trunk from fossil-scm.org) |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | mgagnon_fix |
| Files: | files | file ages | folders |
| SHA1: |
7a57ab6465798ebed7915f879c1e5054 |
| User & Date: | mgagnon 2012-06-11 17:33:09.182 |
Context
|
2012-06-11
| ||
| 17:33 | merge trunk again... (previous merge was not from latest trunk from fossil-scm.org) ... (Closed-Leaf check-in: 7a57ab6465 user: mgagnon tags: mgagnon_fix) | |
| 17:23 | Merge in Trunk... ... (check-in: c109e66db5 user: mgagnon tags: mgagnon_fix) | |
| 11:39 | Minor pedantic wording change to accommodate a recent code change in how _FOSSIL_ stores the path to the repo file. ... (check-in: 480367cecf user: stephan tags: trunk) | |
Changes
Changes to autosetup/local.tcl.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 |
}
}
}
proc parse-tclconfig-sh-file {filename} {
foreach line [split [readfile $filename] \n] {
if {[regexp {^(TCL_[^=]*)=(.*)$} $line -> name value]} {
set tclconfig($name) [string trim $value ']
}
}
return [array get tclconfig]
}
| > | 18 19 20 21 22 23 24 25 26 27 28 29 30 |
}
}
}
proc parse-tclconfig-sh-file {filename} {
foreach line [split [readfile $filename] \n] {
if {[regexp {^(TCL_[^=]*)=(.*)$} $line -> name value]} {
set value [regsub -all {\$\{.*\}} $value ""]
set tclconfig($name) [string trim $value ']
}
}
return [array get tclconfig]
}
|
Changes to src/add.c.
| ︙ | ︙ | |||
194 195 196 197 198 199 200 201 202 | ** the "--dotfiles" option to the command-line. ** ** The --ignore option is a comma-separate list of glob patterns for files ** to be excluded. Example: '*.o,*.obj,*.exe' If the --ignore option ** does not appear on the command line then the "ignore-glob" setting is ** used. ** ** Options: ** | > > > > > | | | | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
** the "--dotfiles" option to the command-line.
**
** The --ignore option is a comma-separate list of glob patterns for files
** to be excluded. Example: '*.o,*.obj,*.exe' If the --ignore option
** does not appear on the command line then the "ignore-glob" setting is
** used.
**
** The --case-sensitive option determines whether or not filenames should
** be treated case sensitive or not. If the option is not given, the default
** depends on the global setting, or the operating system default, if not set.
**
** Options:
**
** --case-sensitive <BOOL> override case-sensitive setting
** --dotfiles include files beginning with a dot (".")
** --ignore <CSG> ignore files matching patterns from the
** comma separated list of glob patterns.
**
** See also: addremove, rm
*/
void add_cmd(void){
int i; /* Loop counter */
int vid; /* Currently checked out version */
int nRoot; /* Full path characters in g.zLocalRoot */
|
| ︙ | ︙ | |||
245 246 247 248 249 250 251 |
file_canonical_name(g.argv[i], &fullName, 0);
zName = blob_str(&fullName);
isDir = file_wd_isdir(zName);
if( isDir==1 ){
vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore);
}else if( isDir==0 ){
| | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
file_canonical_name(g.argv[i], &fullName, 0);
zName = blob_str(&fullName);
isDir = file_wd_isdir(zName);
if( isDir==1 ){
vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore);
}else if( isDir==0 ){
fossil_warning("not found: %s", zName);
}else if( file_access(zName, R_OK) ){
fossil_fatal("cannot open %s", zName);
}else{
char *zTreeName = &zName[nRoot];
db_multi_exec(
"INSERT OR IGNORE INTO sfile(x) VALUES(%Q)",
zTreeName
|
| ︙ | ︙ | |||
371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
** "" (empty string) if filenames are case sensitive
**
** "COLLATE nocase" if filenames are not case sensitive.
*/
const char *filename_collation(void){
return filenames_are_case_sensitive() ? "" : "COLLATE nocase";
}
/*
** COMMAND: addremove
**
** Usage: %fossil addremove ?OPTIONS?
**
** Do all necessary "add" and "rm" commands to synchronize the repository
| > > > > > > > > > > > > | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 |
** "" (empty string) if filenames are case sensitive
**
** "COLLATE nocase" if filenames are not case sensitive.
*/
const char *filename_collation(void){
return filenames_are_case_sensitive() ? "" : "COLLATE nocase";
}
/*
** Do a strncmp() operation which is either case-sensitive or not
** depending on the setting of filenames_are_case_sensitive().
*/
int filenames_strncmp(const char *zA, const char *zB, int nByte){
if( filenames_are_case_sensitive() ){
return fossil_strncmp(zA,zB,nByte);
}else{
return fossil_strnicmp(zA,zB,nByte);
}
}
/*
** COMMAND: addremove
**
** Usage: %fossil addremove ?OPTIONS?
**
** Do all necessary "add" and "rm" commands to synchronize the repository
|
| ︙ | ︙ | |||
394 395 396 397 398 399 400 | ** ** The command does not "commit". You must run the "commit" separately ** as a separate step. ** ** Files and directories whose names begin with "." are ignored unless ** the --dotfiles option is used. ** | | > > | | | | | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
**
** The command does not "commit". You must run the "commit" separately
** as a separate step.
**
** Files and directories whose names begin with "." are ignored unless
** the --dotfiles option is used.
**
** The --ignore option overrides the "ignore-glob" setting, as does the
** --case-sensitive option with the "case-sensitive" setting. See the
** documentation on the "settings" command for further information.
**
** The --test option shows what would happen without actually doing anything.
**
** This command can be used to track third party software.
**
** Options:
** --case-sensitive <BOOL> override case-sensitive setting
** --dotfiles include files beginning with a dot (".")
** --ignore <CSG> ignore files matching patterns from the
** comma separated list of glob patterns.
** --test If given, display instead of run actions
**
** See also: add, rm
*/
void addremove_cmd(void){
Blob path;
const char *zIgnoreFlag = find_option("ignore",0,1);
int allFlag = find_option("dotfiles",0,0)!=0;
|
| ︙ | ︙ |
Changes to src/allrepo.c.
| ︙ | ︙ | |||
61 62 63 64 65 66 67 | ** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%. ** ** Available operations are: ** ** ignore Arguments are repositories that should be ignored ** by subsequent list, pull, push, rebuild, and sync. ** | | > > > > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | ** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%. ** ** Available operations are: ** ** ignore Arguments are repositories that should be ignored ** by subsequent list, pull, push, rebuild, and sync. ** ** list | ls Display the location of all repositories. ** The --ckout option causes all local checkouts to be ** list instead. ** ** changes Shows all local checkouts that have uncommitted changes ** ** pull Run a "pull" operation on all repositories ** ** push Run a "push" on all repositories ** ** rebuild Rebuild on all repositories ** |
| ︙ | ︙ | |||
83 84 85 86 87 88 89 |
void all_cmd(void){
int n;
Stmt q;
const char *zCmd;
char *zSyscmd;
char *zFossil;
char *zQFilename;
| > | > > > > > > > > | > > > > > > > | | > > > > > > | > > > > > > > > | | | | | > | > > > | | | > > > > | | > | < > | < < < < < < < < < | | < < < > | > > | | | > > > > > | < < | 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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
void all_cmd(void){
int n;
Stmt q;
const char *zCmd;
char *zSyscmd;
char *zFossil;
char *zQFilename;
int useCheckouts = 0;
int quiet = 0;
int testRun = 0;
int stopOnError = find_option("dontstop",0,0)==0;
int rc;
Bag outOfDate;
/* The undocumented --test option causes no changes to occur to any
** repository, but instead show what would have happened. Intended for
** test and debugging use.
*/
testRun = find_option("test",0,0)!=0;
if( g.argc<3 ){
usage("changes|list|ls|pull|push|rebuild|sync");
}
n = strlen(g.argv[2]);
db_open_config(1);
zCmd = g.argv[2];
if( strncmp(zCmd, "list", n)==0 || strncmp(zCmd,"ls",n)==0 ){
zCmd = "list";
useCheckouts = find_option("ckout","c",0)!=0;
}else if( strncmp(zCmd, "push", n)==0 ){
zCmd = "push -autourl -R";
}else if( strncmp(zCmd, "pull", n)==0 ){
zCmd = "pull -autourl -R";
}else if( strncmp(zCmd, "rebuild", n)==0 ){
zCmd = "rebuild";
}else if( strncmp(zCmd, "sync", n)==0 ){
zCmd = "sync -autourl -R";
}else if( strncmp(zCmd, "test-integrity", n)==0 ){
zCmd = "test-integrity";
}else if( strncmp(zCmd, "changes", n)==0 ){
zCmd = "changes --quiet --header --chdir";
useCheckouts = 1;
stopOnError = 0;
quiet = 1;
}else if( strncmp(zCmd, "ignore", n)==0 ){
int j;
verify_all_options();
db_begin_transaction();
for(j=3; j<g.argc; j++){
char *zSql = mprintf("DELETE FROM global_config"
" WHERE name GLOB 'repo:%q'", g.argv[j]);
if( testRun ){
fossil_print("%s\n", zSql);
}else{
db_multi_exec("%s", zSql);
}
fossil_free(zSql);
}
db_end_transaction(0);
return;
}else{
fossil_fatal("\"all\" subcommand should be one of: "
"changes ignore list ls push pull rebuild sync");
}
verify_all_options();
zFossil = quoteFilename(fossil_nameofexe());
if( useCheckouts ){
db_prepare(&q,
"SELECT substr(name, 7) COLLATE nocase, max(rowid)"
" FROM global_config"
" WHERE substr(name, 1, 6)=='ckout:'"
" GROUP BY 1 ORDER BY 1"
);
}else{
db_prepare(&q,
"SELECT substr(name, 6) COLLATE nocase, max(rowid)"
" FROM global_config"
" WHERE substr(name, 1, 5)=='repo:'"
" GROUP BY 1 ORDER BY 1"
);
}
bag_init(&outOfDate);
while( db_step(&q)==SQLITE_ROW ){
const char *zFilename = db_column_text(&q, 0);
int rowid = db_column_int(&q, 1);
if( file_access(zFilename, 0) || !file_is_canonical(zFilename) ){
bag_insert(&outOfDate, rowid);
continue;
}
if( useCheckouts && file_isdir(zFilename)!=1 ){
bag_insert(&outOfDate, rowid);
continue;
}
if( zCmd[0]=='l' ){
fossil_print("%s\n", zFilename);
continue;
}
zQFilename = quoteFilename(zFilename);
zSyscmd = mprintf("%s %s %s", zFossil, zCmd, zQFilename);
if( !quiet || testRun ){
fossil_print("%s\n", zSyscmd);
fflush(stdout);
}
rc = testRun ? 0 : fossil_system(zSyscmd);
free(zSyscmd);
free(zQFilename);
if( stopOnError && rc ){
break;
}
}
db_finalize(&q);
/* If any repositories whose names appear in the ~/.fossil file could not
** be found, remove those names from the ~/.fossil file.
*/
if( bag_count(&outOfDate)>0 ){
Blob sql;
char *zSep = "(";
int rowid;
blob_zero(&sql);
blob_appendf(&sql, "DELETE FROM global_config WHERE rowid IN ");
for(rowid=bag_first(&outOfDate); rowid>0; rowid=bag_next(&outOfDate,rowid)){
blob_appendf(&sql, "%s%d", zSep, rowid);
zSep = ",";
}
blob_appendf(&sql, ")");
if( testRun ){
fossil_print("%s\n", blob_str(&sql));
}else{
db_multi_exec(blob_str(&sql));
}
blob_reset(&sql);
}
}
/*
* vim:ts=2:sts=2:et:sw=2:ft=c
*/
|
Changes to src/attach.c.
| ︙ | ︙ | |||
73 74 75 76 77 78 79 |
for(i=0; zFilename[i]; i++){
if( zFilename[i]=='/' && zFilename[i+1]!=0 ){
zFilename = &zFilename[i+1];
i = -1;
}
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
| | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
for(i=0; zFilename[i]; i++){
if( zFilename[i]=='/' && zFilename[i+1]!=0 ){
zFilename = &zFilename[i+1];
i = -1;
}
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
zUrlTail = mprintf("tkt=%s&file=%t", zTarget, zFilename);
}else{
zUrlTail = mprintf("page=%t&file=%t", zTarget, zFilename);
}
@
@ <p><a href="/attachview?%s(zUrlTail)">%h(zFilename)</a>
@ [<a href="/attachdownload/%t(zFilename)?%s(zUrlTail)">download</a>]<br />
if( zComment ) while( fossil_isspace(zComment[0]) ) zComment++;
if( zComment && zComment[0] ){
@ %w(zComment)<br />
|
| ︙ | ︙ | |||
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
Blob manifest;
Blob cksum;
char *zUUID;
const char *zComment;
char *zDate;
int rid;
int i, n;
db_begin_transaction();
blob_init(&content, aContent, szContent);
rid = content_put(&content);
zUUID = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
blob_zero(&manifest);
for(i=n=0; zName[i]; i++){
if( zName[i]=='/' || zName[i]=='\\' ) n = i;
}
zName += n;
if( zName[0]==0 ) zName = "unknown";
| > > > > > > > > > | > | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
Blob manifest;
Blob cksum;
char *zUUID;
const char *zComment;
char *zDate;
int rid;
int i, n;
int addCompress = 0;
Manifest *pManifest;
db_begin_transaction();
blob_init(&content, aContent, szContent);
pManifest = manifest_parse(&content, 0);
manifest_destroy(pManifest);
blob_init(&content, aContent, szContent);
if( pManifest ){
blob_compress(&content, &content);
addCompress = 1;
}
rid = content_put(&content);
zUUID = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
blob_zero(&manifest);
for(i=n=0; zName[i]; i++){
if( zName[i]=='/' || zName[i]=='\\' ) n = i;
}
zName += n;
if( zName[0]==0 ) zName = "unknown";
blob_appendf(&manifest, "A %F%s %F %s\n",
zName, addCompress ? ".gz" : "", zTarget, zUUID);
zComment = PD("comment", "");
while( fossil_isspace(zComment[0]) ) zComment++;
n = strlen(zComment);
while( n>0 && fossil_isspace(zComment[n-1]) ){ n--; }
if( n>0 ){
blob_appendf(&manifest, "C %F\n", zComment);
}
|
| ︙ | ︙ |
Changes to src/branch.c.
| ︙ | ︙ | |||
18 19 20 21 22 23 24 | ** This file contains code used to create new branches within a repository. */ #include "config.h" #include "branch.h" #include <assert.h> /* | | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
** This file contains code used to create new branches within a repository.
*/
#include "config.h"
#include "branch.h"
#include <assert.h>
/*
** fossil branch new NAME BASIS ?OPTIONS?
** argv0 argv1 argv2 argv3 argv4
*/
void branch_new(void){
int rootid; /* RID of the root check-in - what we branch off of */
int brid; /* RID of the branch check-in */
int noSign; /* True if the branch is unsigned */
int i; /* Loop counter */
char *zUuid; /* Artifact ID of origin */
|
| ︙ | ︙ | |||
46 47 48 49 50 51 52 |
noSign = find_option("nosign","",0)!=0;
zColor = find_option("bgcolor","c",1);
isPrivate = find_option("private",0,0)!=0;
zDateOvrd = find_option("date-override",0,1);
zUserOvrd = find_option("user-override",0,1);
verify_all_options();
if( g.argc<5 ){
| | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
noSign = find_option("nosign","",0)!=0;
zColor = find_option("bgcolor","c",1);
isPrivate = find_option("private",0,0)!=0;
zDateOvrd = find_option("date-override",0,1);
zUserOvrd = find_option("user-override",0,1);
verify_all_options();
if( g.argc<5 ){
usage("new BRANCH-NAME BASIS ?OPTIONS?");
}
db_find_and_open_repository(0, 0);
noSign = db_get_int("omitsign", 0)|noSign;
/* fossil branch new name */
zBranch = g.argv[3];
if( zBranch==0 || zBranch[0]==0 ){
|
| ︙ | ︙ | |||
224 225 226 227 228 229 230 | ** COMMAND: branch ** ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS? ** ** Run various subcommands to manage branches of the open repository or ** of the repository identified by the -R or --repository option. ** | | | | > > > > | | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | ** COMMAND: branch ** ** Usage: %fossil branch SUBCOMMAND ... ?OPTIONS? ** ** Run various subcommands to manage branches of the open repository or ** of the repository identified by the -R or --repository option. ** ** %fossil branch new BRANCH-NAME BASIS ?OPTIONS? ** ** Create a new branch BRANCH-NAME off of check-in BASIS. ** Supported options for this subcommand include: ** --private branch is private (i.e., remains local) ** --bgcolor COLOR use COLOR instead of automatic background ** --nosign do not sign contents on this branch ** --date-override DATE DATE to use instead of 'now' ** --user-override USER USER to use instead of the current default ** ** %fossil branch list ?--all | --closed? ** %fossil branch ls ?--all | --closed? ** ** List all branches. Use --all or --closed to list all branches ** or closed branches. The default is to show only open branches. ** ** Options: ** -R|--repository FILE Run commands on repository FILE */ |
| ︙ | ︙ | |||
315 316 317 318 319 320 321 |
style_submenu_element("Color-Test", "Color-Test", "brlist?colortest");
}else{
style_submenu_element("All", "All", "brlist?all");
}
login_anonymous_available();
style_sidebox_begin("Nomenclature:", "33%");
@ <ol>
| | | | | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
style_submenu_element("Color-Test", "Color-Test", "brlist?colortest");
}else{
style_submenu_element("All", "All", "brlist?all");
}
login_anonymous_available();
style_sidebox_begin("Nomenclature:", "33%");
@ <ol>
@ <li> An <div class="sideboxDescribed">%z(href("brlist"))
@ open branch</a></div> is a branch that has one or
@ more %z(href("leaves"))open leaves.</a>
@ The presence of open leaves presumably means
@ that the branch is still being extended with new check-ins.</li>
@ <li> A <div class="sideboxDescribed">%z(href("brlist?closed"))
@ closed branch</a></div> is a branch with only
@ <div class="sideboxDescribed">%z(href("leaves?closed"))
@ closed leaves</a></div>.
@ Closed branches are fixed and do not change (unless they are first
@ reopened)</li>
@ </ol>
style_sidebox_end();
branch_prepare_list_query(&q, showAll?1:(showClosed?-1:0));
|
| ︙ | ︙ | |||
350 351 352 353 354 355 356 |
@ <ul>
cnt++;
}
if( colorTest ){
const char *zColor = hash_color(zBr);
@ <li><span style="background-color: %s(zColor)">
@ %h(zBr) → %s(zColor)</span></li>
| < < | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
@ <ul>
cnt++;
}
if( colorTest ){
const char *zColor = hash_color(zBr);
@ <li><span style="background-color: %s(zColor)">
@ %h(zBr) → %s(zColor)</span></li>
}else{
@ <li>%z(href("%R/timeline?r=%T",zBr))%h(zBr)</a></li>
}
}
if( cnt ){
@ </ul>
}
db_finalize(&q);
@ <script type="text/JavaScript">
|
| ︙ | ︙ | |||
376 377 378 379 380 381 382 |
/*
** This routine is called while for each check-in that is rendered by
** the timeline of a "brlist" page. Add some additional hyperlinks
** to the end of the line.
*/
static void brtimeline_extra(int rid){
Stmt q;
| | | | 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 |
/*
** This routine is called while for each check-in that is rendered by
** the timeline of a "brlist" page. Add some additional hyperlinks
** to the end of the line.
*/
static void brtimeline_extra(int rid){
Stmt q;
if( !g.perm.Hyperlink ) return;
db_prepare(&q,
"SELECT substr(tagname,5) FROM tagxref, tag"
" WHERE tagxref.rid=%d"
" AND tagxref.tagid=tag.tagid"
" AND tagxref.tagtype>0"
" AND tag.tagname GLOB 'sym-*'",
rid
);
while( db_step(&q)==SQLITE_ROW ){
const char *zTagName = db_column_text(&q, 0);
@ %z(href("%R/timeline?r=%T",zTagName))[timeline]</a>
}
db_finalize(&q);
}
/*
** WEBPAGE: brtimeline
**
|
| ︙ | ︙ |
Changes to src/browse.c.
| ︙ | ︙ | |||
75 76 77 78 79 80 81 |
*/
void hyperlinked_path(const char *zPath, Blob *pOut, const char *zCI){
int i, j;
char *zSep = "";
for(i=0; zPath[i]; i=j){
for(j=i; zPath[j] && zPath[j]!='/'; j++){}
| | > | | > | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
*/
void hyperlinked_path(const char *zPath, Blob *pOut, const char *zCI){
int i, j;
char *zSep = "";
for(i=0; zPath[i]; i=j){
for(j=i; zPath[j] && zPath[j]!='/'; j++){}
if( zPath[j] && g.perm.Hyperlink ){
if( zCI ){
char *zLink = href("%R/dir?ci=%S&name=%#T", zCI, j, zPath);
blob_appendf(pOut, "%s%z%#h</a>",
zSep, zLink, j-i, &zPath[i]);
}else{
char *zLink = href("%R/dir?name=%#T", j, zPath);
blob_appendf(pOut, "%s%z%#h</a>",
zSep, zLink, j-i, &zPath[i]);
}
}else{
blob_appendf(pOut, "%s%#h", zSep, j-i, &zPath[i]);
}
zSep = "/";
while( zPath[j]=='/' ){ j++; }
}
|
| ︙ | ︙ | |||
116 117 118 119 120 121 122 | int rid = 0; char *zUuid = 0; Blob dirname; Manifest *pM = 0; const char *zSubdirLink; login_check_credentials(); | | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
int rid = 0;
char *zUuid = 0;
Blob dirname;
Manifest *pM = 0;
const char *zSubdirLink;
login_check_credentials();
if( !g.perm.Hyperlink ){ login_needed(); return; }
while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }
style_header("File List");
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
/* If the name= parameter is an empty string, make it a NULL pointer */
if( zD && strlen(zD)==0 ){ zD = 0; }
|
| ︙ | ︙ | |||
153 154 155 156 157 158 159 |
blob_append(&dirname, "in the top-level directory", -1);
zPrefix = "";
}
if( zCI ){
char zShort[20];
memcpy(zShort, zUuid, 10);
zShort[10] = 0;
| | | | | | | | | < | | | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
blob_append(&dirname, "in the top-level directory", -1);
zPrefix = "";
}
if( zCI ){
char zShort[20];
memcpy(zShort, zUuid, 10);
zShort[10] = 0;
@ <h2>Files of check-in [%z(href("vinfo?name=%T",zUuid))%s(zShort)</a>]
@ %s(blob_str(&dirname))</h2>
zSubdirLink = mprintf("%R/dir?ci=%S&name=%T", zUuid, zPrefix);
if( zD ){
style_submenu_element("Top", "Top", "%R/dir?ci=%S", zUuid);
style_submenu_element("All", "All", "%R/dir?name=%t", zD);
}else{
style_submenu_element("All", "All", "%R/dir");
}
}else{
int hasTrunk;
@ <h2>The union of all files from all check-ins
@ %s(blob_str(&dirname))</h2>
hasTrunk = db_exists(
"SELECT 1 FROM tagxref WHERE tagid=%d AND value='trunk'",
TAG_BRANCH);
zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
if( zD ){
style_submenu_element("Top", "Top", "%R/dir");
style_submenu_element("Tip", "Tip", "%R/dir?name=%t&ci=tip", zD);
if( hasTrunk ){
style_submenu_element("Trunk", "Trunk", "%R/dir?name=%t&ci=trunk",
zD);
}
}else{
style_submenu_element("Tip", "Tip", "%R/dir?ci=tip");
if( hasTrunk ){
style_submenu_element("Trunk", "Trunk", "%R/dir?ci=trunk");
}
}
}
/* Compute the temporary table "localfiles" containing the names
** of all files and subdirectories in the zD[] directory.
**
|
| ︙ | ︙ | |||
210 211 212 213 214 215 216 |
db_prepare(&ins,
"INSERT OR IGNORE INTO localfiles VALUES(pathelement(:x,0), :u)"
);
manifest_file_rewind(pM);
while( (pFile = manifest_file_next(pM,0))!=0 ){
if( nD>0
| > | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 |
db_prepare(&ins,
"INSERT OR IGNORE INTO localfiles VALUES(pathelement(:x,0), :u)"
);
manifest_file_rewind(pM);
while( (pFile = manifest_file_next(pM,0))!=0 ){
if( nD>0
&& (filenames_strncmp(pFile->zName, zD, nD-1)!=0
|| pFile->zName[nD-1]!='/')
){
continue;
}
if( pPrev
&& filenames_strncmp(&pFile->zName[nD],&pPrev->zName[nD],nPrev)==0
&& (pFile->zName[nD+nPrev]==0 || pFile->zName[nD+nPrev]=='/')
){
continue;
}
db_bind_text(&ins, ":x", &pFile->zName[nD]);
db_bind_text(&ins, ":u", pFile->zUuid);
db_step(&ins);
|
| ︙ | ︙ | |||
275 276 277 278 279 280 281 |
@ </ul></td><td class="browser"><ul class="browser">
i = 0;
}
i++;
zFN = db_column_text(&q, 0);
if( zFN[0]=='/' ){
zFN++;
| | | | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
@ </ul></td><td class="browser"><ul class="browser">
i = 0;
}
i++;
zFN = db_column_text(&q, 0);
if( zFN[0]=='/' ){
zFN++;
@ <li>%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li>
}else if( zCI ){
const char *zUuid = db_column_text(&q, 1);
@ <li>%z(href("%R/artifact/%s",zUuid))%h(zFN)</a></li>
}else{
@ <li>%z(href("%R/finfo?name=%T%T",zPrefix,zFN))%h(zFN)
@ </a></li>
}
}
db_finalize(&q);
manifest_destroy(pM);
@ </ul></td></tr></table>
style_footer();
}
/*
* vim:ts=2:sts=2:et:sw=2:ft=c
*/
|
Changes to src/checkin.c.
| ︙ | ︙ | |||
93 94 95 96 97 98 99 |
}else if( isRenamed ){
blob_appendf(report, "RENAMED %s\n", zDisplayName);
}
free(zFullName);
}
blob_reset(&rewrittenPathname);
db_finalize(&q);
| | | > > > > > | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
}else if( isRenamed ){
blob_appendf(report, "RENAMED %s\n", zDisplayName);
}
free(zFullName);
}
blob_reset(&rewrittenPathname);
db_finalize(&q);
db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
" WHERE id<=0");
while( db_step(&q)==SQLITE_ROW ){
const char *zLabel = "MERGED_WITH";
switch( db_column_int(&q, 1) ){
case -1: zLabel = "CHERRYPICK "; break;
case -2: zLabel = "BACKOUT "; break;
}
blob_append(report, zPrefix, nPrefix);
blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
}
db_finalize(&q);
if( nErr ){
fossil_fatal("aborting due to prior errors");
}
}
|
| ︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
**
** Options:
** --abs-paths Display absolute pathnames.
** --rel-paths Display pathnames relative to the current working
** directory.
** --sha1sum Verify file status using SHA1 hashing rather
** than relying on file mtimes.
**
** See also: extra, ls, status
*/
void changes_cmd(void){
Blob report;
int vid;
int useSha1sum = find_option("sha1sum", 0, 0)!=0;
int cwdRelative = 0;
db_must_be_within_tree();
cwdRelative = determine_cwd_relative_option();
blob_zero(&report);
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 0, useSha1sum);
status_report(&report, "", 0, cwdRelative);
blob_write_to_file(&report, "-");
}
/*
** COMMAND: status
**
** Usage: %fossil status ?OPTIONS?
| > > > > > > > > > > > | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
**
** Options:
** --abs-paths Display absolute pathnames.
** --rel-paths Display pathnames relative to the current working
** directory.
** --sha1sum Verify file status using SHA1 hashing rather
** than relying on file mtimes.
** --header Identify the repository if there are changes
** -v Say "no changes" if there are none
**
** See also: extra, ls, status
*/
void changes_cmd(void){
Blob report;
int vid;
int useSha1sum = find_option("sha1sum", 0, 0)!=0;
int showHdr = find_option("header",0,0)!=0;
int verbose = find_option("verbose","v",0)!=0;
int cwdRelative = 0;
db_must_be_within_tree();
cwdRelative = determine_cwd_relative_option();
blob_zero(&report);
vid = db_lget_int("checkout", 0);
vfile_check_signature(vid, 0, useSha1sum);
status_report(&report, "", 0, cwdRelative);
if( verbose && blob_size(&report)==0 ){
blob_append(&report, " (none)\n", -1);
}
if( showHdr && blob_size(&report)>0 ){
fossil_print("Changes for %s at %s:\n", db_get("project-name","???"),
g.zLocalRoot);
}
blob_write_to_file(&report, "-");
}
/*
** COMMAND: status
**
** Usage: %fossil status ?OPTIONS?
|
| ︙ | ︙ | |||
736 737 738 739 740 741 742 |
blob_appendf(pOut, "F %F\n", pFile->zName);
pFile = manifest_file_next(pBaseline, 0);
nFBcard++;
}
blob_appendf(pOut, "P %s", zParentUuid);
if( verifyDate ) checkin_verify_younger(vid, zParentUuid, zDate);
free(zParentUuid);
| | < | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 |
blob_appendf(pOut, "F %F\n", pFile->zName);
pFile = manifest_file_next(pBaseline, 0);
nFBcard++;
}
blob_appendf(pOut, "P %s", zParentUuid);
if( verifyDate ) checkin_verify_younger(vid, zParentUuid, zDate);
free(zParentUuid);
db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=0");
while( db_step(&q2)==SQLITE_ROW ){
char *zMergeUuid;
int mid = db_column_int(&q2, 0);
if( !g.markPrivate && content_is_private(mid) ) continue;
zMergeUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
if( zMergeUuid ){
blob_appendf(pOut, " %s", zMergeUuid);
|
| ︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 | ** ** After the following function call has returned, the Global.aCommitFile[] ** array is allocated to contain the "id" field from the vfile table ** for each file to be committed. Or, if aCommitFile is NULL, all files ** should be committed. */ select_commit_files(); | | | 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 |
**
** After the following function call has returned, the Global.aCommitFile[]
** array is allocated to contain the "id" field from the vfile table
** for each file to be committed. Or, if aCommitFile is NULL, all files
** should be committed.
*/
select_commit_files();
isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
if( g.aCommitFile && isAMerge ){
fossil_fatal("cannot do a partial commit of a merge");
}
user_select();
/*
** Check that the user exists.
|
| ︙ | ︙ | |||
1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 |
blob_append(&comment, zComment, -1);
}else if( zComFile ){
blob_zero(&comment);
blob_read_from_file(&comment, zComFile);
}else{
char *zInit = db_text(0, "SELECT value FROM vvar WHERE name='ci-comment'");
prepare_commit_comment(&comment, zInit, zBranch, vid, zUserOvrd);
free(zInit);
}
if( blob_size(&comment)==0 ){
Blob ans;
blob_zero(&ans);
prompt_user("empty check-in comment. continue (y/N)? ", &ans);
if( blob_str(&ans)[0]!='y' ){
| > > > > > > | 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 |
blob_append(&comment, zComment, -1);
}else if( zComFile ){
blob_zero(&comment);
blob_read_from_file(&comment, zComFile);
}else{
char *zInit = db_text(0, "SELECT value FROM vvar WHERE name='ci-comment'");
prepare_commit_comment(&comment, zInit, zBranch, vid, zUserOvrd);
if( zInit && zInit[0] && fossil_strcmp(zInit, blob_str(&comment))==0 ){
Blob ans;
blob_zero(&ans);
prompt_user("unchanged check-in comment. continue (y/N)? ", &ans);
if( blob_str(&ans)[0]!='y' ) fossil_exit(1);;
}
free(zInit);
}
if( blob_size(&comment)==0 ){
Blob ans;
blob_zero(&ans);
prompt_user("empty check-in comment. continue (y/N)? ", &ans);
if( blob_str(&ans)[0]!='y' ){
|
| ︙ | ︙ | |||
1267 1268 1269 1270 1271 1272 1273 |
blob_reset(&muuid);
}
/* Update the vfile and vmerge tables */
db_multi_exec(
"DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
| | | 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 |
blob_reset(&muuid);
}
/* Update the vfile and vmerge tables */
db_multi_exec(
"DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
"DELETE FROM vmerge;"
"UPDATE vfile SET vid=%d;"
"UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
" WHERE file_is_selected(id);"
, vid, nvid
);
db_lset_int("checkout", nvid);
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
*/
void close_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
db_must_be_within_tree();
if( !forceFlag && unsaved_changes()==1 ){
fossil_fatal("there are unsaved changes in the current checkout");
}
unlink_local_database(1);
db_close(1);
unlink_local_database(0);
}
/*
* vim:ts=2:sts=2:et:sw=2:ft=c
| > > > | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 |
*/
void close_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
db_must_be_within_tree();
if( !forceFlag && unsaved_changes()==1 ){
fossil_fatal("there are unsaved changes in the current checkout");
}
if( db_is_writeable("repository") ){
db_multi_exec("DELETE FROM config WHERE name='ckout:%q'", g.zLocalRoot);
}
unlink_local_database(1);
db_close(1);
unlink_local_database(0);
}
/*
* vim:ts=2:sts=2:et:sw=2:ft=c
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
int nPrepare; /* Number of calls to sqlite3_prepare() */
int nDeleteOnFail; /* Number of entries in azDeleteOnFail[] */
struct sCommitHook {
int (*xHook)(void); /* Functions to call at db_end_transaction() */
int sequence; /* Call functions in sequence order */
} aHook[5];
char *azDeleteOnFail[3]; /* Files to delete on a failure */
} db = {0, 0, 0, 0, 0, 0, };
/*
** Arrange for the given file to be deleted on a failure.
*/
void db_delete_on_failure(const char *zFilename){
assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
| > > > | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
int nPrepare; /* Number of calls to sqlite3_prepare() */
int nDeleteOnFail; /* Number of entries in azDeleteOnFail[] */
struct sCommitHook {
int (*xHook)(void); /* Functions to call at db_end_transaction() */
int sequence; /* Call functions in sequence order */
} aHook[5];
char *azDeleteOnFail[3]; /* Files to delete on a failure */
char *azBeforeCommit[5]; /* Commands to run prior to COMMIT */
int nBeforeCommit; /* Number of entries in azBeforeCommit */
int nPriorChanges; /* sqlite3_total_changes() at transaction start */
} db = {0, 0, 0, 0, 0, 0, };
/*
** Arrange for the given file to be deleted on a failure.
*/
void db_delete_on_failure(const char *zFilename){
assert( db.nDeleteOnFail<count(db.azDeleteOnFail) );
|
| ︙ | ︙ | |||
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
/*
** Begin and end a nested transaction
*/
void db_begin_transaction(void){
if( db.nBegin==0 ){
db_multi_exec("BEGIN");
sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
}
db.nBegin++;
}
void db_end_transaction(int rollbackFlag){
if( g.db==0 ) return;
if( db.nBegin<=0 ) return;
if( rollbackFlag ) db.doRollback = 1;
db.nBegin--;
if( db.nBegin==0 ){
int i;
| > > > > > > > | > | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
/*
** Begin and end a nested transaction
*/
void db_begin_transaction(void){
if( db.nBegin==0 ){
db_multi_exec("BEGIN");
sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
db.nPriorChanges = sqlite3_total_changes(g.db);
}
db.nBegin++;
}
void db_end_transaction(int rollbackFlag){
if( g.db==0 ) return;
if( db.nBegin<=0 ) return;
if( rollbackFlag ) db.doRollback = 1;
db.nBegin--;
if( db.nBegin==0 ){
int i;
if( db.doRollback==0 && db.nPriorChanges<sqlite3_total_changes(g.db) ){
while( db.nBeforeCommit ){
db.nBeforeCommit--;
sqlite3_exec(g.db, db.azBeforeCommit[db.nBeforeCommit], 0, 0, 0);
sqlite3_free(db.azBeforeCommit[db.nBeforeCommit]);
}
leaf_do_pending_checks();
}
for(i=0; db.doRollback==0 && i<db.nCommitHook; i++){
db.doRollback |= db.aHook[i].xHook();
}
while( db.pAllStmt ){
db_finalize(db.pAllStmt);
}
db_multi_exec(db.doRollback ? "ROLLBACK" : "COMMIT");
|
| ︙ | ︙ | |||
485 486 487 488 489 490 491 492 493 494 495 496 497 498 |
rc = sqlite3_exec(g.db, blob_buffer(&sql), 0, 0, &zErr);
if( rc!=SQLITE_OK ){
db_err("%s\n%s", zErr, blob_buffer(&sql));
}
blob_reset(&sql);
return rc;
}
/*
** Execute a query and return a single integer value.
*/
i64 db_int64(i64 iDflt, const char *zSql, ...){
va_list ap;
Stmt s;
| > > > > > > > > > > > > > > | 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 |
rc = sqlite3_exec(g.db, blob_buffer(&sql), 0, 0, &zErr);
if( rc!=SQLITE_OK ){
db_err("%s\n%s", zErr, blob_buffer(&sql));
}
blob_reset(&sql);
return rc;
}
/*
** Optionally make the following changes to the database if feasible and
** convenient. Do not start a transaction for these changes, but only
** make these changes if other changes are also being made.
*/
void db_optional_sql(const char *zDb, const char *zSql, ...){
if( db_is_writeable(zDb) && db.nBeforeCommit < count(db.azBeforeCommit) ){
va_list ap;
va_start(ap, zSql);
db.azBeforeCommit[db.nBeforeCommit++] = sqlite3_vmprintf(zSql, ap);
va_end(ap);
}
}
/*
** Execute a query and return a single integer value.
*/
i64 db_int64(i64 iDflt, const char *zSql, ...){
va_list ap;
Stmt s;
|
| ︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 |
** Return TRUE if the schema is out-of-date
*/
int db_schema_is_outofdate(void){
return db_exists("SELECT 1 FROM config"
" WHERE name='aux-schema'"
" AND value<>'%s'", AUX_SCHEMA);
}
/*
** Verify that the repository schema is correct. If it is not correct,
** issue a fatal error and die.
*/
void db_verify_schema(void){
if( db_schema_is_outofdate() ){
| > > > > > > > | 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 |
** Return TRUE if the schema is out-of-date
*/
int db_schema_is_outofdate(void){
return db_exists("SELECT 1 FROM config"
" WHERE name='aux-schema'"
" AND value<>'%s'", AUX_SCHEMA);
}
/*
** Return true if the database is writeable
*/
int db_is_writeable(const char *zName){
return !sqlite3_db_readonly(g.db, db_name(zName));
}
/*
** Verify that the repository schema is correct. If it is not correct,
** issue a fatal error and die.
*/
void db_verify_schema(void){
if( db_schema_is_outofdate() ){
|
| ︙ | ︙ | |||
1059 1060 1061 1062 1063 1064 1065 |
/*
** Open the local database. If unable, exit with an error.
*/
void db_must_be_within_tree(void){
if( db_open_local()==0 ){
| | | 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 |
/*
** Open the local database. If unable, exit with an error.
*/
void db_must_be_within_tree(void){
if( db_open_local()==0 ){
fossil_fatal("current directory is not within an open checkout");
}
db_open_repository(0);
db_verify_schema();
}
/*
** Close the database connection.
|
| ︙ | ︙ | |||
1721 1722 1723 1724 1725 1726 1727 1728 |
Blob localRoot;
file_canonical_name(g.zLocalRoot, &localRoot, 1);
db_multi_exec(
"REPLACE INTO global_config(name, value)"
"VALUES('ckout:%q','%q');",
blob_str(&localRoot), blob_str(&full)
);
blob_reset(&localRoot);
| > > > > > > | | > | 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 |
Blob localRoot;
file_canonical_name(g.zLocalRoot, &localRoot, 1);
db_multi_exec(
"REPLACE INTO global_config(name, value)"
"VALUES('ckout:%q','%q');",
blob_str(&localRoot), blob_str(&full)
);
db_swap_connections();
db_optional_sql("repository",
"REPLACE INTO config(name,value,mtime)"
"VALUES('ckout:%q',1,now())",
blob_str(&localRoot)
);
blob_reset(&localRoot);
}else{
db_swap_connections();
}
blob_reset(&full);
}
/*
** COMMAND: open
**
** Usage: %fossil open FILENAME ?VERSION? ?OPTIONS?
|
| ︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 |
usage("REPOSITORY-FILENAME ?VERSION?");
}
if( !allowNested && db_open_local() ){
fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
}
file_canonical_name(g.argv[2], &path, 0);
db_open_repository(blob_str(&path));
| > > > > > | | | 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 |
usage("REPOSITORY-FILENAME ?VERSION?");
}
if( !allowNested && db_open_local() ){
fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
}
file_canonical_name(g.argv[2], &path, 0);
db_open_repository(blob_str(&path));
#if defined(_WIN32)
# define LOCALDB_NAME "./_FOSSIL_"
#else
# define LOCALDB_NAME "./.fslckout"
#endif
db_init_database(LOCALDB_NAME, zLocalSchema, (char*)0);
db_delete_on_failure(LOCALDB_NAME);
db_open_local();
db_lset("repository", g.argv[2]);
db_record_repository_filename(blob_str(&path));
vid = db_int(0, "SELECT pid FROM plink y"
" WHERE NOT EXISTS(SELECT 1 FROM plink x WHERE x.cid=y.pid)");
if( vid==0 ){
db_lset_int("checkout", 1);
|
| ︙ | ︙ | |||
1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 |
char const *def; /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
{ "access-log", 0, 0, 0, "off" },
{ "allow-symlinks",0, 0, 1, "off" },
{ "auto-captcha", "autocaptcha", 0, 0, "on" },
{ "auto-shun", 0, 0, 0, "on" },
{ "autosync", 0, 0, 0, "on" },
{ "binary-glob", 0, 32, 1, "" },
{ "clearsign", 0, 0, 0, "off" },
{ "case-sensitive",0, 0, 0, "on" },
{ "crnl-glob", 0, 16, 1, "" },
{ "default-perms", 0, 16, 0, "u" },
| > | 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 |
char const *def; /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
{ "access-log", 0, 0, 0, "off" },
{ "allow-symlinks",0, 0, 1, "off" },
{ "auto-captcha", "autocaptcha", 0, 0, "on" },
{ "auto-hyperlink",0, 0, 0, "on", },
{ "auto-shun", 0, 0, 0, "on" },
{ "autosync", 0, 0, 0, "on" },
{ "binary-glob", 0, 32, 1, "" },
{ "clearsign", 0, 0, 0, "off" },
{ "case-sensitive",0, 0, 0, "on" },
{ "crnl-glob", 0, 16, 1, "" },
{ "default-perms", 0, 16, 0, "u" },
|
| ︙ | ︙ | |||
1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 | ** (existing links in repository created on Unix become ** plain-text files with link destination path inside). ** Default: off ** ** auto-captcha If enabled, the Login page provides a button to ** fill in the captcha password. Default: on ** ** auto-shun If enabled, automatically pull the shunning list ** from a server to which the client autosyncs. ** Default: on ** ** autosync If enabled, automatically pull prior to commit ** or update and automatically push after commit or ** tag or branch creation. If the value is "pullonly" | > > > > > | 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 | ** (existing links in repository created on Unix become ** plain-text files with link destination path inside). ** Default: off ** ** auto-captcha If enabled, the Login page provides a button to ** fill in the captcha password. Default: on ** ** auto-hyperlink Use javascript to enable hyperlinks on web pages ** for all users (regardless of the "h" privilege) if the ** User-Agent string in the HTTP header look like it came ** from real person, not a spider or bot. Default: on ** ** auto-shun If enabled, automatically pull the shunning list ** from a server to which the client autosyncs. ** Default: on ** ** autosync If enabled, automatically pull prior to commit ** or update and automatically push after commit or ** tag or branch creation. If the value is "pullonly" |
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
885 886 887 888 889 890 891 892 893 894 895 896 897 898 |
memset(&s, 0, sizeof(s));
s.zLine = fossil_malloc( 10*width + 200 );
if( s.zLine==0 ) return;
s.width = width;
s.escHtml = escHtml;
s.iStart = -1;
s.iEnd = -1;
A = p->aFrom;
B = p->aTo;
R = p->aEdit;
mxr = p->nEdit;
while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
for(r=0; r<mxr; r += 3*nr){
| > | 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 |
memset(&s, 0, sizeof(s));
s.zLine = fossil_malloc( 10*width + 200 );
if( s.zLine==0 ) return;
s.width = width;
s.escHtml = escHtml;
s.iStart = -1;
s.iStart2 = 0;
s.iEnd = -1;
A = p->aFrom;
B = p->aTo;
R = p->aEdit;
mxr = p->nEdit;
while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
for(r=0; r<mxr; r += 3*nr){
|
| ︙ | ︙ | |||
1775 1776 1777 1778 1779 1780 1781 |
while( db_step(&q)==SQLITE_ROW ){
int pid = db_column_int(&q, 0);
const char *zUuid = db_column_text(&q, 1);
const char *zDate = db_column_text(&q, 2);
const char *zUser = db_column_text(&q, 3);
if( webLabel ){
zLabel = mprintf(
| | | | 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 |
while( db_step(&q)==SQLITE_ROW ){
int pid = db_column_int(&q, 0);
const char *zUuid = db_column_text(&q, 1);
const char *zDate = db_column_text(&q, 2);
const char *zUser = db_column_text(&q, 3);
if( webLabel ){
zLabel = mprintf(
"<a href='%R/info/%s' target='infowindow'>%.10s</a> %s %13.13s",
zUuid, zUuid, zDate, zUser
);
}else{
zLabel = mprintf("%.10s %s %13.13s", zUuid, zDate, zUser);
}
p->nVers++;
p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
p->azVers[p->nVers-1] = zLabel;
|
| ︙ | ︙ | |||
1818 1819 1820 1821 1822 1823 1824 |
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
iLimit = atoi(PD("limit","-1"));
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
fossil_redirect_home();
}
style_header("File Annotation");
if( P("filevers") ) annFlags |= ANN_FILE_VERS;
| | | 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 |
if( mid==0 || fnid==0 ){ fossil_redirect_home(); }
iLimit = atoi(PD("limit","-1"));
if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){
fossil_redirect_home();
}
style_header("File Annotation");
if( P("filevers") ) annFlags |= ANN_FILE_VERS;
annotate_file(&ann, fnid, mid, g.perm.Hyperlink, iLimit, annFlags);
if( P("log") ){
int i;
@ <h2>Versions analyzed:</h2>
@ <ol>
for(i=0; i<ann.nVers; i++){
@ <li><tt>%s(ann.azVers[i])</tt></li>
}
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
539 540 541 542 543 544 545 |
diff_all_two_versions(zFrom, zTo, zDiffCmd, diffFlags);
}
}
}
/*
** WEBPAGE: vpatch
| | | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 |
diff_all_two_versions(zFrom, zTo, zDiffCmd, diffFlags);
}
}
}
/*
** WEBPAGE: vpatch
** URL vpatch?from=UUID&to=UUID
*/
void vpatch_page(void){
const char *zFrom = P("from");
const char *zTo = P("to");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( zFrom==0 || zTo==0 ) fossil_redirect_home();
|
| ︙ | ︙ |
Changes to src/event.c.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 |
#include "event.h"
/*
** Output a hyperlink to an event given its tagid.
*/
void hyperlink_to_event_tagid(int tagid){
char *zEventId;
| < < | < < < < < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#include "event.h"
/*
** Output a hyperlink to an event given its tagid.
*/
void hyperlink_to_event_tagid(int tagid){
char *zEventId;
zEventId = db_text(0, "SELECT substr(tagname, 7) FROM tag WHERE tagid=%d",
tagid);
@ [%z(href("%R/event/%s",zEventId))%S(zEventId)</a>]
free(zEventId);
}
/*
** WEBPAGE: event
** URL: /event
** PARAMETERS:
|
| ︙ | ︙ | |||
128 129 130 131 132 133 134 |
if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
style_submenu_element("Edit", "Edit", "%s/eventedit?name=%s",
g.zTop, zEventId);
}
zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate);
style_submenu_element("Context", "Context", "%s/timeline?c=%T",
g.zTop, zETime);
| | | | | | | | | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
if( g.perm.WrWiki && g.perm.Write && nextRid==0 ){
style_submenu_element("Edit", "Edit", "%s/eventedit?name=%s",
g.zTop, zEventId);
}
zETime = db_text(0, "SELECT datetime(%.17g)", pEvent->rEventDate);
style_submenu_element("Context", "Context", "%s/timeline?c=%T",
g.zTop, zETime);
if( g.perm.Hyperlink ){
if( showDetail ){
style_submenu_element("Plain", "Plain", "%s/event?name=%s&aid=%s",
g.zTop, zEventId, zUuid);
if( nextRid ){
char *zNext;
zNext = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nextRid);
style_submenu_element("Next", "Next",
"%s/event?name=%s&aid=%s&detail=1",
g.zTop, zEventId, zNext);
free(zNext);
}
if( prevRid ){
char *zPrev;
zPrev = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", prevRid);
style_submenu_element("Prev", "Prev",
"%s/event?name=%s&aid=%s&detail=1",
g.zTop, zEventId, zPrev);
free(zPrev);
}
}else{
style_submenu_element("Detail", "Detail",
"%s/event?name=%s&aid=%s&detail=1",
g.zTop, zEventId, zUuid);
}
}
if( showDetail && g.perm.Hyperlink ){
int i;
const char *zClr = 0;
Blob comment;
zATime = db_text(0, "SELECT datetime(%.17g)", pEvent->rDate);
@ <p>Event [%z(href("%R/artifact/%s",zUuid))%S(zUuid)</a>] at
@ [%z(href("%R/timeline?c=%T",zETime))%s(zETime)</a>]
@ entered by user <b>%h(pEvent->zUser)</b> on
@ [%z(href("%R/timeline?c=%T",zATime))%s(zATime)</a>]:</p>
@ <blockquote>
for(i=0; i<pEvent->nTag; i++){
if( fossil_strcmp(pEvent->aTag[i].zName,"+bgcolor")==0 ){
zClr = pEvent->aTag[i].zValue;
}
}
if( zClr && zClr[0]==0 ) zClr = 0;
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
303 304 305 306 307 308 309 |
@ <tr><td>
@ <div class="divider">%s(zPrevDate)</div>
@ </td></tr>
}
memcpy(zTime, &zDate[11], 5);
zTime[5] = 0;
@ <tr><td class="timelineTime">
| | < < < < < | | | | | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
@ <tr><td>
@ <div class="divider">%s(zPrevDate)</div>
@ </td></tr>
}
memcpy(zTime, &zDate[11], 5);
zTime[5] = 0;
@ <tr><td class="timelineTime">
@ %z(href("%R/timeline?c=%t",zDate))%s(zTime)</a></td>
@ <td class="timelineGraph"><div id="m%d(gidx)"></div></td>
if( zBgClr && zBgClr[0] ){
@ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
}else{
@ <td class="timelineTableCell">
}
sqlite3_snprintf(sizeof(zShort), zShort, "%.10s", zUuid);
sqlite3_snprintf(sizeof(zShortCkin), zShortCkin, "%.10s", zCkin);
if( zUuid ){
@ %z(href("%R/artifact/%s",zUuid))[%S(zUuid)]</a> part of check-in
}else{
@ <b>Deleted</b> by check-in
}
hyperlink_to_uuid(zShortCkin);
@ %h(zCom) (user:
hyperlink_to_user(zUser, zDate, "");
@ branch: %h(zBr))
if( g.perm.Hyperlink && zUuid ){
const char *z = zFilename;
if( fpid ){
@ %z(href("%R/fdiff?v1=%s&v2=%s",zPUuid,zUuid))[diff]</a>
}
@ %z(href("%R/annotate?checkin=%S&filename=%h",zCkin,z))
@ [annotate]</a>
}
@ </td></tr>
}
db_finalize(&q);
if( pGraph ){
graph_finish(pGraph, 0);
|
| ︙ | ︙ |
Changes to src/glob.c.
| ︙ | ︙ | |||
108 109 110 111 112 113 114 |
if( zPatternList==0 || zPatternList[0]==0 ) return 0;
nList = strlen(zPatternList);
p = fossil_malloc( sizeof(*p) + nList+1 );
memset(p, 0, sizeof(*p));
z = (char*)&p[1];
memcpy(z, zPatternList, nList+1);
while( z[0] ){
| | > > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
if( zPatternList==0 || zPatternList[0]==0 ) return 0;
nList = strlen(zPatternList);
p = fossil_malloc( sizeof(*p) + nList+1 );
memset(p, 0, sizeof(*p));
z = (char*)&p[1];
memcpy(z, zPatternList, nList+1);
while( z[0] ){
while( z[0]==',' || z[0]==' ' || z[0]=='\n' || z[0]=='\r' ){
z++; /* Skip leading spaces and newlines */
}
if( z[0]=='\'' || z[0]=='"' ){
delimiter = z[0];
z++;
}else{
delimiter = ',';
}
if( z[0]==0 ) break;
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
if( zComment ){
fossil_print("comment: ");
comment_print(zComment, 14, 79);
free(zComment);
}
}
/*
** COMMAND: info
**
** Usage: %fossil info ?VERSION | REPOSITORY_FILENAME? ?OPTIONS?
**
** With no arguments, provide information about the current tree.
** If an argument is specified, provide information about the object
** in the respository of the current tree that the argument refers
** to. Or if the argument is the name of a repository, show
** information about that repository.
**
** Use the "finfo" command to get information about a specific
** file in a checkout.
**
** Options:
**
** -R|--repository FILE Extract info from repository FILE
**
** See also: annotate, artifact, finfo, timeline
*/
void info_cmd(void){
i64 fsize;
if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){
db_open_config(0);
db_record_repository_filename(g.argv[2]);
db_open_repository(g.argv[2]);
fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
fossil_print("project-code: %s\n", db_get("project-code", "<none>"));
return;
}
db_find_and_open_repository(0,0);
if( g.argc==2 ){
int vid;
/* 012345678901234 */
db_record_repository_filename(0);
fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
if( g.localOpen ){
fossil_print("repository: %s\n", db_repository_filename());
fossil_print("local-root: %s\n", g.zLocalRoot);
}
#if defined(_WIN32)
if( g.zHome ){
fossil_print("user-home: %s\n", g.zHome);
}
#endif
fossil_print("project-code: %s\n", db_get("project-code", ""));
vid = g.localOpen ? db_lget_int("checkout", 0) : 0;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
if( zComment ){
fossil_print("comment: ");
comment_print(zComment, 14, 79);
free(zComment);
}
}
/*
** Print information about the URLs used to access a repository and
** checkouts in a repository.
*/
static void extraRepoInfo(void){
Stmt s;
db_prepare(&s, "SELECT substr(name,7), date(mtime,'unixepoch')"
" FROM config"
" WHERE name GLOB 'ckout:*' ORDER BY name");
while( db_step(&s)==SQLITE_ROW ){
const char *zName;
const char *zCkout = db_column_text(&s, 0);
if( g.localOpen ){
if( fossil_strcmp(zCkout, g.zLocalRoot)==0 ) continue;
zName = "alt-root:";
}else{
zName = "check-out:";
}
fossil_print("%-11s %-54s %s\n", zName, zCkout,
db_column_text(&s, 1));
}
db_finalize(&s);
db_prepare(&s, "SELECT substr(name,9), date(mtime,'unixepoch')"
" FROM config"
" WHERE name GLOB 'baseurl:*' ORDER BY name");
while( db_step(&s)==SQLITE_ROW ){
fossil_print("access-url: %-54s %s\n", db_column_text(&s, 0),
db_column_text(&s, 1));
}
db_finalize(&s);
}
/*
** COMMAND: info
**
** Usage: %fossil info ?VERSION | REPOSITORY_FILENAME? ?OPTIONS?
**
** With no arguments, provide information about the current tree.
** If an argument is specified, provide information about the object
** in the respository of the current tree that the argument refers
** to. Or if the argument is the name of a repository, show
** information about that repository.
**
** Use the "finfo" command to get information about a specific
** file in a checkout.
**
** Options:
**
** -R|--repository FILE Extract info from repository FILE
** -l|--detail Show extra information
**
** See also: annotate, artifact, finfo, timeline
*/
void info_cmd(void){
i64 fsize;
int bDetail = find_option("detail","l",0)!=0;
if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){
db_open_config(0);
db_record_repository_filename(g.argv[2]);
db_open_repository(g.argv[2]);
fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
fossil_print("project-code: %s\n", db_get("project-code", "<none>"));
extraRepoInfo();
return;
}
db_find_and_open_repository(0,0);
if( g.argc==2 ){
int vid;
/* 012345678901234 */
db_record_repository_filename(0);
fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>"));
if( g.localOpen ){
fossil_print("repository: %s\n", db_repository_filename());
fossil_print("local-root: %s\n", g.zLocalRoot);
}
if( bDetail ) extraRepoInfo();
#if defined(_WIN32)
if( g.zHome ){
fossil_print("user-home: %s\n", g.zHome);
}
#endif
fossil_print("project-code: %s\n", db_get("project-code", ""));
vid = g.localOpen ? db_lget_int("checkout", 0) : 0;
|
| ︙ | ︙ | |||
225 226 227 228 229 230 231 |
hyperlink_to_uuid(zOrigUuid);
}else{
@ propagates to descendants
}
#if 0
if( zValue && fossil_strcmp(zTagname,"branch")==0 ){
@
| | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
hyperlink_to_uuid(zOrigUuid);
}else{
@ propagates to descendants
}
#if 0
if( zValue && fossil_strcmp(zTagname,"branch")==0 ){
@
@ %z(href("%R/timeline?r=%T",zValue))branch timeline</a>
}
#endif
}
if( zSrcUuid && zSrcUuid[0] ){
if( tagtype==0 ){
@ by
}else{
|
| ︙ | ︙ | |||
297 298 299 300 301 302 303 |
const char *zName, /* Name of the file that has changed */
const char *zOld, /* blob.uuid before change. NULL for added files */
const char *zNew, /* blob.uuid after change. NULL for deletes */
const char *zOldName, /* Prior name. NULL if no name change. */
int diffFlags, /* Flags for text_diff(). Zero to omit diffs */
int mperm /* executable or symlink permission for zNew */
){
| | | | | | | | | | | | | | 333 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 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
const char *zName, /* Name of the file that has changed */
const char *zOld, /* blob.uuid before change. NULL for added files */
const char *zNew, /* blob.uuid after change. NULL for deletes */
const char *zOldName, /* Prior name. NULL if no name change. */
int diffFlags, /* Flags for text_diff(). Zero to omit diffs */
int mperm /* executable or symlink permission for zNew */
){
if( !g.perm.Hyperlink ){
if( zNew==0 ){
@ <p>Deleted %h(zName)</p>
}else if( zOld==0 ){
@ <p>Added %h(zName)</p>
}else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
@ <p>Name change from %h(zOldName) to %h(zName)
}else if( fossil_strcmp(zNew, zOld)==0 ){
@ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared")
@ for %h(zName)</p>
}else{
@ <p>Changes to %h(zName)</p>
}
if( diffFlags ){
@ <pre style="white-space:pre;">
append_diff(zOld, zNew, diffFlags);
@ </pre>
}
}else{
if( zOld && zNew ){
if( fossil_strcmp(zOld, zNew)!=0 ){
@ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@ from %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a>
@ to %z(href("%R/artifact/%s",zNew))[%S(zNew)].</a>
}else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
@ <p>Name change from
@ from %z(href("%R/finfo?name=%T",zOldName))%h(zOldName)</a>
@ to %z(href("%R/finfo?name=%T",zName))%h(zName)</a>.
}else{
@ <p>Execute permission %s(( mperm==PERM_EXE )?"set":"cleared") for
@ %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
}
}else if( zOld ){
@ <p>Deleted %z(href("%s/finfo?name=%T",g.zTop,zName))%h(zName)</a>
@ version %z(href("%R/artifact/%s",zOld))[%S(zOld)]</a>
}else{
@ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
}
if( diffFlags ){
@ <pre style="white-space:pre;">
append_diff(zOld, zNew, diffFlags);
@ </pre>
}else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
@
@ %z(href("%R/fdiff?v1=%S&v2=%S",zOld,zNew))[diff]</a>
}
@ </p>
}
}
/*
** Construct an appropriate diffFlag for text_diff() based on query
|
| ︙ | ︙ | |||
499 500 501 502 503 504 505 |
const char *zDate = db_column_text(&q, 2);
if( zUser==0 || zUser[0]==0 ) zUser = "unknown";
@ <tr><th>Received From:</th>
@ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
}
db_finalize(&q);
}
| | | | | | | | | | | | | | | | | | | | | | | | | | 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 |
const char *zDate = db_column_text(&q, 2);
if( zUser==0 || zUser[0]==0 ) zUser = "unknown";
@ <tr><th>Received From:</th>
@ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
}
db_finalize(&q);
}
if( g.perm.Hyperlink ){
const char *zProjName = db_get("project-name", "unnamed");
@ <tr><th>Timelines:</th><td>
@ %z(href("%R/timeline?f=%S",zUuid))family</a>
if( zParent ){
@ | %z(href("%R/timeline?p=%S",zUuid))ancestors</a>
}
if( !isLeaf ){
@ | %z(href("%R/timeline?d=%S",zUuid))descendants</a>
}
if( zParent && !isLeaf ){
@ | %z(href("%R/timeline?dp=%S",zUuid))both</a>
}
db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
" WHERE rid=%d AND tagtype>0 "
" AND tag.tagid=tagxref.tagid "
" AND +tag.tagname GLOB 'sym-*'", rid);
while( db_step(&q)==SQLITE_ROW ){
const char *zTagName = db_column_text(&q, 0);
@ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
}
db_finalize(&q);
@ </td></tr>
@ <tr><th>Other Links:</th>
@ <td>
@ %z(href("%R/dir?ci=%S",zUuid))files</a>
if( g.perm.Zip ){
char *zUrl = mprintf("%R/tarball/%s-%S.tar.gz?uuid=%s",
zProjName, zUuid, zUuid);
@ | %z(href("%s",zUrl))Tarball</a>
@ | %z(href("%R/zip/%s-%S.zip?uuid=%s",zProjName,zUuid,zUuid))
@ ZIP archive</a>
fossil_free(zUrl);
}
@ | %z(href("%R/artifact/%S",zUuid))manifest</a>
if( g.perm.Write ){
@ | %z(href("%R/ci_edit?r=%S",zUuid))edit</a>
}
@ </td>
@ </tr>
}
@ </table>
}else{
style_header("Check-in Information");
login_anonymous_available();
}
db_finalize(&q);
showTags(rid, "");
if( zParent ){
@ <div class="section">Changes</div>
@ <div class="sectionmenu">
showDiff = g.zPath[0]!='c';
if( db_get_boolean("show-version-diffs", 0)==0 ){
showDiff = !showDiff;
if( showDiff ){
@ %z(xhref("class='button'","%R/vinfo/%T",zName))
@ hide diffs</a>
if( sideBySide ){
@ %z(xhref("class='button'","%R/ci/%T?sbs=0",zName))
@ unified diffs</a>
}else{
@ %z(xhref("class='button'","%R/ci/%T?sbs=1",zName))
@ side-by-side diffs</a>
}
}else{
@ %z(xhref("class='button'","%R/ci/%T?sbs=0",zName))
@ show unified diffs</a>
@ %z(xhref("class='button'","%R/ci/%T?sbs=1",zName))
@ show side-by-side diffs</a>
}
}else{
if( showDiff ){
@ %z(xhref("class='button'","%R/ci/%T",zName))hide diffs</a>
if( sideBySide ){
@ %z(xhref("class='button'","%R/info/%T?sbs=0",zName))
@ unified diffs</a>
}else{
@ %z(xhref("class='button'","%R/info/%T?sbs=1",zName))
@ side-by-side diffs</a>
}
}else{
@ %z(xhref("class='button'","%R/vinfo/%T?sbs=0",zName))
@ show unified diffs</a>
@ %z(xhref("class='button'","%R/vinfo/%T?sbs=1",zName))
@ show side-by-side diffs</a>
}
}
@ %z(xhref("class='button'","%R/vpatch?from=%S&to=%S",zParent,zUuid))
@ patch</a></div>
db_prepare(&q,
"SELECT name,"
" mperm,"
" (SELECT uuid FROM blob WHERE rid=mlink.pid),"
" (SELECT uuid FROM blob WHERE rid=mlink.fid),"
" (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)"
|
| ︙ | ︙ | |||
662 663 664 665 666 667 668 |
@ <tr><th>Date:</th><td>
hyperlink_to_date(zDate, "</td></tr>");
if( g.perm.Setup ){
@ <tr><th>Record ID:</th><td>%d(rid)</td></tr>
}
@ <tr><th>Original User:</th><td>
hyperlink_to_user(zUser, zDate, "</td></tr>");
| | | | | 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 |
@ <tr><th>Date:</th><td>
hyperlink_to_date(zDate, "</td></tr>");
if( g.perm.Setup ){
@ <tr><th>Record ID:</th><td>%d(rid)</td></tr>
}
@ <tr><th>Original User:</th><td>
hyperlink_to_user(zUser, zDate, "</td></tr>");
if( g.perm.Hyperlink ){
@ <tr><th>Commands:</th>
@ <td>
@ %z(href("%R/whistory?name=%t",zName))history</a>
@ | %z(href("%R/artifact/%S",zUuid))raw-text</a>
@ </td>
@ </tr>
}
@ </table></p>
}else{
style_header("Wiki Information");
rid = 0;
|
| ︙ | ︙ | |||
756 757 758 759 760 761 762 | } db_finalize(&q); } /* ** WEBPAGE: vdiff | | | 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 |
}
db_finalize(&q);
}
/*
** WEBPAGE: vdiff
** URL: /vdiff?from=UUID&to=UUID&detail=BOOLEAN;sbs=BOOLEAN
**
** Show all differences between two checkins.
*/
void vdiff_page(void){
int ridFrom, ridTo;
int showDetail = 0;
int sideBySide = 0;
|
| ︙ | ︙ | |||
900 901 902 903 904 905 906 |
if( mPerm==PERM_LNK ){
@ <li>Symbolic link
}else if( mPerm==PERM_EXE ){
@ <li>Executable file
}else{
@ <li>File
}
| < | < < < < < < | | < | < | | | 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 |
if( mPerm==PERM_LNK ){
@ <li>Symbolic link
}else if( mPerm==PERM_EXE ){
@ <li>Executable file
}else{
@ <li>File
}
@ %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@ <ul>
prevName = fossil_strdup(zName);
}
@ <li>
hyperlink_to_date(zDate,"");
@ - part of checkin
hyperlink_to_uuid(zVers);
if( zBr && zBr[0] ){
@ on branch %z(href("%R/timeline?r=%T",zBr))%h(zBr)</a>
}
@ - %w(zCom) (user:
hyperlink_to_user(zUser,zDate,")");
if( g.perm.Hyperlink ){
@ %z(href("%R/annotate?checkin=%S&filename=%T",zVers,zName))
@ [annotate]</a>
}
cnt++;
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_append(pDownloadName, zName, -1);
}
}
|
| ︙ | ︙ | |||
953 954 955 956 957 958 959 |
const char *zDate = db_column_text(&q, 1);
const char *zUser = db_column_text(&q, 2);
if( cnt>0 ){
@ Also wiki page
}else{
@ Wiki page
}
| < < < | < < | 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 |
const char *zDate = db_column_text(&q, 1);
const char *zUser = db_column_text(&q, 2);
if( cnt>0 ){
@ Also wiki page
}else{
@ Wiki page
}
@ [%z(href("%R/wiki?name=%t",zPagename))%h(zPagename)</a>] by
hyperlink_to_user(zUser,zDate," on");
hyperlink_to_date(zDate,".");
nWiki++;
cnt++;
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_appendf(pDownloadName, "%s.wiki", zPagename);
}
|
| ︙ | ︙ | |||
1029 1030 1031 1032 1033 1034 1035 |
/* const char *zSrc = db_column_text(&q, 4); */
if( cnt>0 ){
@ Also attachment "%h(zFilename)" to
}else{
@ Attachment "%h(zFilename)" to
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
| | | | | | | | 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 |
/* const char *zSrc = db_column_text(&q, 4); */
if( cnt>0 ){
@ Also attachment "%h(zFilename)" to
}else{
@ Attachment "%h(zFilename)" to
}
if( strlen(zTarget)==UUID_SIZE && validate16(zTarget,UUID_SIZE) ){
if( g.perm.Hyperlink && g.perm.RdTkt ){
@ ticket [%z(href("%R/tktview?name=%S",zTarget))%S(zTarget)</a>]
}else{
@ ticket [%S(zTarget)]
}
}else{
if( g.perm.Hyperlink && g.perm.RdWiki ){
@ wiki page [%z(href("%R/wiki?name=%t",zTarget)))%h(zTarget)</a>]
}else{
@ wiki page [%h(zTarget)]
}
}
@ added by
hyperlink_to_user(zUser,zDate," on");
hyperlink_to_date(zDate,".");
cnt++;
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_append(pDownloadName, zFilename, -1);
}
}
db_finalize(&q);
if( cnt==0 ){
@ Control artifact.
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_appendf(pDownloadName, "%.10s.txt", zUuid);
}
}else if( linkToView && g.perm.Hyperlink ){
@ %z(href("%R/artifact/%S",zUuid))[view]</a>
}
}
/*
** WEBPAGE: fdiff
** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN
|
| ︙ | ︙ | |||
1124 1125 1126 1127 1128 1129 1130 |
style_submenu_element("Unified Diff", "udiff",
"%s/fdiff?v1=%T&v2=%T&sbs=0",
g.zTop, P("v1"), P("v2"));
}
if( P("smhdr")!=0 ){
@ <h2>Differences From Artifact
| | | | | < | 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 |
style_submenu_element("Unified Diff", "udiff",
"%s/fdiff?v1=%T&v2=%T&sbs=0",
g.zTop, P("v1"), P("v2"));
}
if( P("smhdr")!=0 ){
@ <h2>Differences From Artifact
@ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
@ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
}else{
@ <h2>Differences From
@ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
object_description(v1, 0, 0);
@ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
object_description(v2, 0, 0);
}
@ <hr />
@ <div class="%s(zStyle)">
@ %s(blob_str(&diff))
@ </div>
blob_reset(&diff);
|
| ︙ | ︙ | |||
1236 1237 1238 1239 1240 1241 1242 |
rid = name_to_rid_www("name");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 |
rid = name_to_rid_www("name");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
style_header("Hex Artifact Content");
|
| ︙ | ︙ | |||
1383 1384 1385 1386 1387 1388 1389 |
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 |
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if( rid==0 ) fossil_redirect_home();
if( g.perm.Admin ){
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
style_header("Artifact Content");
|
| ︙ | ︙ | |||
1442 1443 1444 1445 1446 1447 1448 |
output_text_with_line_numbers(z, zLn);
}else{
@ <pre>
@ %h(z)
@ </pre>
}
}else if( strncmp(zMime, "image/", 6)==0 ){
| | | 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 |
output_text_with_line_numbers(z, zLn);
}else{
@ <pre>
@ %h(z)
@ </pre>
}
}else if( strncmp(zMime, "image/", 6)==0 ){
@ <img src="%s(g.zTop)/raw?name=%s(zUuid)&m=%s(zMime)"></img>
}else{
@ <i>(file is %d(blob_size(&content)) bytes of binary data)</i>
}
@ </blockquote>
}
style_footer();
}
|
| ︙ | ︙ | |||
1471 1472 1473 1474 1475 1476 1477 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
rid = name_to_rid_www("name");
if( rid==0 ){ fossil_redirect_home(); }
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( g.perm.Admin ){
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
| | | | | | < | 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
rid = name_to_rid_www("name");
if( rid==0 ){ fossil_redirect_home(); }
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
if( g.perm.Admin ){
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
g.zTop, zUuid);
}else{
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
g.zTop, zUuid);
}
}
pTktChng = manifest_get(rid, CFTYPE_TICKET);
if( pTktChng==0 ){
fossil_redirect_home();
}
style_header("Ticket Change Details");
zDate = db_text(0, "SELECT datetime(%.12f)", pTktChng->rDate);
memcpy(zTktName, pTktChng->zTicketUuid, 10);
zTktName[10] = 0;
if( g.perm.Hyperlink ){
@ <h2>Changes to ticket
@ %z(href("%R/tktview/%s",pTktChng->zTicketUuid)))%s(zTktName)</a></h2>
@
@ <p>By %h(pTktChng->zUser) on %s(zDate). See also:
@ %z(href("%R/artifact/%T",zUuid))artifact content</a>, and
@ %z(href("%R/tkthistory/%s",pTktChng->zTicketUuid))ticket history</a></p>
}else{
@ <h2>Changes to ticket %s(zTktName)</h2>
@
@ <p>By %h(pTktChng->zUser) on %s(zDate).
@ </p>
}
@
|
| ︙ | ︙ | |||
1929 1930 1931 1932 1933 1934 1935 |
@ %s(blob_str(&suffix))
@ </td></tr></table>
@ </blockquote>
@ <hr />
blob_reset(&suffix);
}
@ <p>Make changes to attributes of check-in
| | | 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 |
@ %s(blob_str(&suffix))
@ </td></tr></table>
@ </blockquote>
@ <hr />
blob_reset(&suffix);
}
@ <p>Make changes to attributes of check-in
@ [%z(href("%R/ci/%s",zUuid))%s(zUuid)</a>]:</p>
@ <form action="%s(g.zTop)/ci_edit" method="post"><div>
login_insert_csrf_secret();
@ <input type="hidden" name="r" value="%S(zUuid)" />
@ <table border="0" cellspacing="10">
@ <tr><td align="right" valign="top"><b>User:</b></td>
@ <td valign="top">
|
| ︙ | ︙ |
Changes to src/json.c.
| ︙ | ︙ | |||
1982 1983 1984 1985 1986 1987 1988 | ADD(Setup,"setup"); ADD(Admin,"admin"); ADD(Delete,"delete"); ADD(Password,"password"); ADD(Query,"query"); /* don't think this one is actually used */ ADD(Write,"checkin"); ADD(Read,"checkout"); | | | 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 | ADD(Setup,"setup"); ADD(Admin,"admin"); ADD(Delete,"delete"); ADD(Password,"password"); ADD(Query,"query"); /* don't think this one is actually used */ ADD(Write,"checkin"); ADD(Read,"checkout"); ADD(Hyperlink,"history"); ADD(Clone,"clone"); ADD(RdWiki,"readWiki"); ADD(NewWiki,"createWiki"); ADD(ApndWiki,"appendWiki"); ADD(WrWiki,"editWiki"); ADD(RdTkt,"readTicket"); ADD(NewTkt,"createTicket"); |
| ︙ | ︙ |
Changes to src/json_dir.c.
| ︙ | ︙ | |||
64 65 66 67 68 69 70 | char const * zDX = NULL; int nD; char * zUuid = NULL; char const * zCI = NULL; Manifest * pM = NULL; Stmt q = empty_Stmt; int rid = 0; | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
char const * zDX = NULL;
int nD;
char * zUuid = NULL;
char const * zCI = NULL;
Manifest * pM = NULL;
Stmt q = empty_Stmt;
int rid = 0;
if( !g.perm.Hyperlink ){
json_set_err(FSL_JSON_E_DENIED, "Requires 'h' permissions.");
return NULL;
}
zCI = json_find_option_cstr("checkin",NULL,"ci" );
/* If a specific check-in is requested, fetch and parse it. If the
** specific check-in does not exist, clear zCI. zCI==0 will cause all
|
| ︙ | ︙ |
Changes to src/json_timeline.c.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 |
*/
cson_value * json_page_timeline(){
#if 0
/* The original timeline code does not require 'h' access,
but it arguably should. For JSON mode i think one could argue
that History permissions are required.
*/
| | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
*/
cson_value * json_page_timeline(){
#if 0
/* The original timeline code does not require 'h' access,
but it arguably should. For JSON mode i think one could argue
that History permissions are required.
*/
if(! g.perm.Hyperlink && !g.perm.Read ){
json_set_err(FSL_JSON_E_DENIED, "Timeline requires 'h' or 'o' access.");
return NULL;
}
#endif
return json_page_dispatch_helper(&JsonPageDefs_Timeline[0]);
}
|
| ︙ | ︙ | |||
424 425 426 427 428 429 430 | cson_value * listV = NULL; cson_array * list = NULL; int check = 0; char showFiles = -1/*magic number*/; Stmt q = empty_Stmt; char warnRowToJsonFailed = 0; Blob sql = empty_blob; | | | 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 |
cson_value * listV = NULL;
cson_array * list = NULL;
int check = 0;
char showFiles = -1/*magic number*/;
Stmt q = empty_Stmt;
char warnRowToJsonFailed = 0;
Blob sql = empty_blob;
if( !g.perm.Hyperlink ){
/* Reminder to self: HTML impl requires 'o' (Read)
rights.
*/
json_set_err( FSL_JSON_E_DENIED, "Checkin timeline requires 'h' access." );
return NULL;
}
showFiles = json_find_option_bool("files",NULL,"f",0);
|
| ︙ | ︙ |
Changes to src/json_wiki.c.
| ︙ | ︙ | |||
490 491 492 493 494 495 496 | int argPos = g.json.dispatchDepth; int r1 = 0, r2 = 0; Manifest * pW1 = NULL, *pW2 = NULL; Blob w1 = empty_blob, w2 = empty_blob, d = empty_blob; char const * zErrTag = NULL; int diffFlags; char * zUuid = NULL; | | | 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
int argPos = g.json.dispatchDepth;
int r1 = 0, r2 = 0;
Manifest * pW1 = NULL, *pW2 = NULL;
Blob w1 = empty_blob, w2 = empty_blob, d = empty_blob;
char const * zErrTag = NULL;
int diffFlags;
char * zUuid = NULL;
if( !g.perm.Hyperlink ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'h' permissions.");
return NULL;
}
zV1 = json_find_option_cstr2( "v1",NULL, NULL, ++argPos );
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
383 384 385 386 387 388 389 |
/*
** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
** is a manually operated browser or a bot. When in doubt, assume a bot.
** Return true if we believe the agent is a real person.
*/
static int isHuman(const char *zAgent){
int i;
| | | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
/*
** Look at the HTTP_USER_AGENT parameter and try to determine if the user agent
** is a manually operated browser or a bot. When in doubt, assume a bot.
** Return true if we believe the agent is a real person.
*/
static int isHuman(const char *zAgent){
int i;
if( zAgent==0 ) return 0; /* If not UserAgent, then probably a bot */
for(i=0; zAgent[i]; i++){
if( prefix_match("bot", zAgent+i) ) return 0;
if( prefix_match("spider", zAgent+i) ) return 0;
if( prefix_match("crawl", zAgent+i) ) return 0;
/* If a URI appears in the User-Agent, it is probably a bot */
if( memcmp("http", zAgent+i,4)==0 ) return 0;
}
|
| ︙ | ︙ | |||
462 463 464 465 466 467 468 469 470 471 472 473 474 475 |
** line on the title bar. The "my" page was never completed so it is now
** removed. Use this page as a placeholder in older installations.
*/
void login_page(void){
const char *zUsername, *zPasswd;
const char *zNew1, *zNew2;
const char *zAnonPw = 0;
int anonFlag;
char *zErrMsg = "";
int uid; /* User id loged in user */
char *zSha1Pw;
const char *zIpAddr; /* IP address of requestor */
login_check_credentials();
| > | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
** line on the title bar. The "my" page was never completed so it is now
** removed. Use this page as a placeholder in older installations.
*/
void login_page(void){
const char *zUsername, *zPasswd;
const char *zNew1, *zNew2;
const char *zAnonPw = 0;
const char *zGoto = P("g");
int anonFlag;
char *zErrMsg = "";
int uid; /* User id loged in user */
char *zSha1Pw;
const char *zIpAddr; /* IP address of requestor */
login_check_credentials();
|
| ︙ | ︙ | |||
559 560 561 562 563 564 565 566 |
*/
login_set_user_cookie(zUsername, uid, NULL);
redirect_to_g();
}
}
style_header("Login/Logout");
@ %s(zErrMsg)
@ <form action="login" method="post">
| > > > | | | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 |
*/
login_set_user_cookie(zUsername, uid, NULL);
redirect_to_g();
}
}
style_header("Login/Logout");
@ %s(zErrMsg)
if( zGoto && P("anon")==0 ){
@ <p>A login is required for <a href="%h(zGoto)">%h(zGoto)</a>.</p>
}
@ <form action="login" method="post">
if( zGoto ){
@ <input type="hidden" name="g" value="%h(zGoto)" />
}
@ <table class="login_out">
@ <tr>
@ <td class="login_out_label">User ID:</td>
if( anonFlag ){
@ <td><input type="text" id="u" name="u" value="anonymous" size="30" /></td>
}else{
|
| ︙ | ︙ | |||
759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 |
}
/*
** This routine examines the login cookie to see if it exists and and
** is valid. If the login cookie checks out, it then sets global
** variables appropriately. Global variables set include g.userUid
** and g.zLogin and the g.perm family of permission booleans.
*/
void login_check_credentials(void){
int uid = 0; /* User id */
const char *zCookie; /* Text of the login cookie */
const char *zIpAddr; /* Raw IP address of the requestor */
char *zRemoteAddr; /* Abbreviated IP address of the requestor */
const char *zCap = 0; /* Capability string */
/* Only run this check once. */
if( g.userUid!=0 ) return;
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
| > > > | 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 |
}
/*
** This routine examines the login cookie to see if it exists and and
** is valid. If the login cookie checks out, it then sets global
** variables appropriately. Global variables set include g.userUid
** and g.zLogin and the g.perm family of permission booleans.
**
** If the
*/
void login_check_credentials(void){
int uid = 0; /* User id */
const char *zCookie; /* Text of the login cookie */
const char *zIpAddr; /* Raw IP address of the requestor */
char *zRemoteAddr; /* Abbreviated IP address of the requestor */
const char *zCap = 0; /* Capability string */
const char *zPublicPages = 0; /* GLOB patterns of public pages */
/* Only run this check once. */
if( g.userUid!=0 ) return;
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
|
| ︙ | ︙ | |||
902 903 904 905 906 907 908 |
if( fossil_strcmp(g.zLogin,"nobody")==0 ){
g.zLogin = 0;
}
/* Set the capabilities */
login_replace_capabilities(zCap, 0);
login_set_anon_nobody_capabilities();
| | > | > > > > > > > > > > > > > > | 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 |
if( fossil_strcmp(g.zLogin,"nobody")==0 ){
g.zLogin = 0;
}
/* Set the capabilities */
login_replace_capabilities(zCap, 0);
login_set_anon_nobody_capabilities();
if( zCap[0] && !g.perm.Hyperlink
&& db_get_boolean("auto-hyperlink",1)
&& isHuman(P("HTTP_USER_AGENT")) ){
g.perm.Hyperlink = 1;
g.javascriptHyperlink = 1;
}
/* If the public-pages glob pattern is defined and REQUEST_URI matches
** one of the globs in public-pages, then also add in all default-perms
** permissions.
*/
zPublicPages = db_get("public-pages",0);
if( zPublicPages!=0 ){
Glob *pGlob = glob_create(zPublicPages);
if( glob_match(pGlob, PD("REQUEST_URI","no-match")) ){
login_set_capabilities(db_get("default-perms","u"), 0);
}
glob_free(pGlob);
}
}
/*
** Memory of settings
*/
static int login_anon_once = 1;
|
| ︙ | ︙ | |||
951 952 953 954 955 956 957 |
if(NULL==zCap){
return;
}
for(i=0; zCap[i]; i++){
switch( zCap[i] ){
case 's': g.perm.Setup = 1; /* Fall thru into Admin */
case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip =
| | | | | | | | 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 |
if(NULL==zCap){
return;
}
for(i=0; zCap[i]; i++){
switch( zCap[i] ){
case 's': g.perm.Setup = 1; /* Fall thru into Admin */
case 'a': g.perm.Admin = g.perm.RdTkt = g.perm.WrTkt = g.perm.Zip =
g.perm.RdWiki = g.perm.WrWiki = g.perm.NewWiki =
g.perm.ApndWiki = g.perm.Hyperlink = g.perm.Clone =
g.perm.NewTkt = g.perm.Password = g.perm.RdAddr =
g.perm.TktFmt = g.perm.Attach = g.perm.ApndTkt = 1;
/* Fall thru into Read/Write */
case 'i': g.perm.Read = g.perm.Write = 1; break;
case 'o': g.perm.Read = 1; break;
case 'z': g.perm.Zip = 1; break;
case 'd': g.perm.Delete = 1; break;
case 'h': g.perm.Hyperlink = 1; break;
case 'g': g.perm.Clone = 1; break;
case 'p': g.perm.Password = 1; break;
case 'j': g.perm.RdWiki = 1; break;
case 'k': g.perm.WrWiki = g.perm.RdWiki = g.perm.ApndWiki =1; break;
case 'm': g.perm.ApndWiki = 1; break;
case 'f': g.perm.NewWiki = 1; break;
|
| ︙ | ︙ | |||
1031 1032 1033 1034 1035 1036 1037 |
case 'a': rc = g.perm.Admin; break;
case 'b': rc = g.perm.Attach; break;
case 'c': rc = g.perm.ApndTkt; break;
case 'd': rc = g.perm.Delete; break;
case 'e': rc = g.perm.RdAddr; break;
case 'f': rc = g.perm.NewWiki; break;
case 'g': rc = g.perm.Clone; break;
| | < | 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 |
case 'a': rc = g.perm.Admin; break;
case 'b': rc = g.perm.Attach; break;
case 'c': rc = g.perm.ApndTkt; break;
case 'd': rc = g.perm.Delete; break;
case 'e': rc = g.perm.RdAddr; break;
case 'f': rc = g.perm.NewWiki; break;
case 'g': rc = g.perm.Clone; break;
case 'h': rc = g.perm.Hyperlink; break;
case 'i': rc = g.perm.Write; break;
case 'j': rc = g.perm.RdWiki; break;
case 'k': rc = g.perm.WrWiki; break;
case 'm': rc = g.perm.ApndWiki; break;
case 'n': rc = g.perm.NewTkt; break;
case 'o': rc = g.perm.Read; break;
case 'p': rc = g.perm.Password; break;
/* case 'q': */
case 'r': rc = g.perm.RdTkt; break;
case 's': rc = g.perm.Setup; break;
|
| ︙ | ︙ | |||
1107 1108 1109 1110 1111 1112 1113 |
cgi_redirect(mprintf("login?g=%T", zUrl));
/* NOTREACHED */
assert(0);
}
}
/*
| | | | | | 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 |
cgi_redirect(mprintf("login?g=%T", zUrl));
/* NOTREACHED */
assert(0);
}
}
/*
** Call this routine if the user lacks g.perm.Hyperlink permission. If
** the anonymous user has Hyperlink permission, then paint a mesage
** to inform the user that much more information is available by
** logging in as anonymous.
*/
void login_anonymous_available(void){
if( !g.perm.Hyperlink &&
db_exists("SELECT 1 FROM user"
" WHERE login='anonymous'"
" AND cap LIKE '%%h%%'") ){
const char *zUrl = PD("REQUEST_URI", "index");
@ <p>Many <span class="disabled">hyperlinks are disabled.</span><br />
@ Use <a href="%s(g.zTop)/login?anon=1&g=%T(zUrl)">anonymous login</a>
@ to enable hyperlinks.</p>
}
}
/*
** While rendering a form, call this routine to add the Anti-CSRF token
** as a hidden element of the form.
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
58 59 60 61 62 63 64 | char Setup; /* s: use Setup screens on web interface */ char Admin; /* a: administrative permission */ char Delete; /* d: delete wiki or tickets */ char Password; /* p: change password */ char Query; /* q: create new reports */ char Write; /* i: xfer inbound. checkin */ char Read; /* o: xfer outbound. checkout */ | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | char Setup; /* s: use Setup screens on web interface */ char Admin; /* a: administrative permission */ char Delete; /* d: delete wiki or tickets */ char Password; /* p: change password */ char Query; /* q: create new reports */ char Write; /* i: xfer inbound. checkin */ char Read; /* o: xfer outbound. checkout */ char Hyperlink; /* h: enable the display of hyperlinks */ char Clone; /* g: clone */ char RdWiki; /* j: view wiki via web */ char NewWiki; /* f: create new wiki via web */ char ApndWiki; /* m: append to wiki via web */ char WrWiki; /* k: edit wiki via web */ char RdTkt; /* r: view tickets via web */ char NewTkt; /* n: create new tickets */ |
| ︙ | ︙ | |||
133 134 135 136 137 138 139 | FILE *httpIn; /* Accept HTTP input from here */ FILE *httpOut; /* Send HTTP output here */ int xlinkClusterOnly; /* Set when cloning. Only process clusters */ int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ int clockSkewSeen; /* True if clocks on client and server out of sync */ | | > | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | FILE *httpIn; /* Accept HTTP input from here */ FILE *httpOut; /* Send HTTP output here */ int xlinkClusterOnly; /* Set when cloning. Only process clusters */ int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ int clockSkewSeen; /* True if clocks on client and server out of sync */ char isHTTP; /* True if erver/CGI modes, else assume CLI. */ char javascriptHyperlink; /* If true, set href= using script, not HTML */ int urlIsFile; /* True if a "file:" url */ int urlIsHttps; /* True if a "https:" url */ int urlIsSsh; /* True if an "ssh:" url */ char *urlName; /* Hostname for http: or filename for file: */ char *urlHostname; /* The HOST: parameter on http headers */ char *urlProtocol; /* "http" or "https" */ |
| ︙ | ︙ | |||
448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 |
fossil_print(
"Usage: %s COMMAND ...\n"
" or: %s help -- for a list of common commands\n"
" or: %s help COMMMAND -- for help with the named command\n",
argv[0], argv[0], argv[0]);
fossil_exit(1);
}else{
g.isHTTP = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
if( g.fSqlTrace ) g.fSqlStats = 1;
g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
g.zLogin = find_option("user", "U", 1);
g.zSSLIdentity = find_option("ssl-identity", 0, 1);
if( find_option("help",0,0)!=0 ){
/* --help anywhere on the command line is translated into
** "fossil help argv[1] argv[2]..." */
int i;
char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) );
for(i=1; i<g.argc; i++) zNewArgv[i+1] = argv[i];
zNewArgv[i+1] = 0;
| > > > > | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
fossil_print(
"Usage: %s COMMAND ...\n"
" or: %s help -- for a list of common commands\n"
" or: %s help COMMMAND -- for help with the named command\n",
argv[0], argv[0], argv[0]);
fossil_exit(1);
}else{
const char *zChdir = find_option("chdir",0,1);
g.isHTTP = 0;
g.fQuiet = find_option("quiet", 0, 0)!=0;
g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
if( g.fSqlTrace ) g.fSqlStats = 1;
g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
g.zLogin = find_option("user", "U", 1);
g.zSSLIdentity = find_option("ssl-identity", 0, 1);
if( zChdir && chdir(zChdir) ){
fossil_fatal("unable to change directories to %s", zChdir);
}
if( find_option("help",0,0)!=0 ){
/* --help anywhere on the command line is translated into
** "fossil help argv[1] argv[2]..." */
int i;
char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) );
for(i=1; i<g.argc; i++) zNewArgv[i+1] = argv[i];
zNewArgv[i+1] = 0;
|
| ︙ | ︙ | |||
553 554 555 556 557 558 559 |
else
#endif
{
if( g.cgiOutput && once ){
once = 0;
cgi_printf("<p class=\"generalError\">%h</p>", z);
cgi_reply();
| | | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 |
else
#endif
{
if( g.cgiOutput && once ){
once = 0;
cgi_printf("<p class=\"generalError\">%h</p>", z);
cgi_reply();
}else if( !g.fQuiet ){
char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z);
fossil_puts(zOut, 1);
}
}
free(z);
db_force_rollback();
fossil_exit(rc);
|
| ︙ | ︙ | |||
585 586 587 588 589 590 591 |
else
#endif
{
if( g.cgiOutput ){
g.cgiOutput = 0;
cgi_printf("<p class=\"generalError\">%h</p>", z);
cgi_reply();
| | | 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 |
else
#endif
{
if( g.cgiOutput ){
g.cgiOutput = 0;
cgi_printf("<p class=\"generalError\">%h</p>", z);
cgi_reply();
}else if( !g.fQuiet ){
char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z);
fossil_puts(zOut, 1);
}
}
free(z);
db_force_rollback();
fossil_exit(rc);
|
| ︙ | ︙ | |||
710 711 712 713 714 715 716 717 718 719 720 721 722 723 |
** Turn off any NL to CRNL translation on the stream given as an
** argument. This is a no-op on unix but is necessary on windows.
*/
void fossil_binary_mode(FILE *p){
#if defined(_WIN32)
_setmode(_fileno(p), _O_BINARY);
#endif
}
/*
** Return a name for an SQLite error code
*/
| > > > | 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 |
** Turn off any NL to CRNL translation on the stream given as an
** argument. This is a no-op on unix but is necessary on windows.
*/
void fossil_binary_mode(FILE *p){
#if defined(_WIN32)
_setmode(_fileno(p), _O_BINARY);
#endif
#ifdef __EMX__ /* OS/2 */
setmode(fileno(p), O_BINARY);
#endif
}
/*
** Return a name for an SQLite error code
*/
|
| ︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 |
if( fossil_stricmp(zMode,"on")==0 ){
g.zBaseURL = mprintf("https://%s%.*s", zHost, i, zCur);
g.zTop = &g.zBaseURL[8+strlen(zHost)];
}else{
g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur);
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"));
| > > > > > > > > > > > | 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 |
if( fossil_stricmp(zMode,"on")==0 ){
g.zBaseURL = mprintf("https://%s%.*s", zHost, i, zCur);
g.zTop = &g.zBaseURL[8+strlen(zHost)];
}else{
g.zBaseURL = mprintf("http://%s%.*s", zHost, i, zCur);
g.zTop = &g.zBaseURL[7+strlen(zHost)];
}
if( db_is_writeable("repository") ){
if( !db_exists("SELECT 1 FROM config WHERE name='baseurl:%q'", g.zBaseURL)){
db_multi_exec("INSERT INTO config(name,value,mtime)"
"VALUES('baseurl:%q',1,now())", g.zBaseURL);
}else{
db_optional_sql("repository",
"REPLACE INTO config(name,value,mtime)"
"VALUES('baseurl:%q',1,now())", g.zBaseURL
);
}
}
}
/*
** 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"));
|
| ︙ | ︙ | |||
1404 1405 1406 1407 1408 1409 1410 |
if( g.argc==3 && fossil_strcmp(g.argv[1],"cgi")==0 ){
zFile = g.argv[2];
}else{
zFile = g.argv[1];
}
g.httpOut = stdout;
g.httpIn = stdin;
| < < < < < < < < | | < | 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 |
if( g.argc==3 && fossil_strcmp(g.argv[1],"cgi")==0 ){
zFile = g.argv[2];
}else{
zFile = g.argv[1];
}
g.httpOut = stdout;
g.httpIn = stdin;
fossil_binary_mode(g.httpOut);
fossil_binary_mode(g.httpIn);
g.cgiOutput = 1;
blob_read_from_file(&config, zFile);
while( blob_line(&config, &line) ){
if( !blob_token(&line, &key) ) continue;
if( blob_buffer(&key)[0]=='#' ) continue;
if( blob_eq(&key, "debug:") && blob_token(&line, &value) ){
g.fDebug = fopen(blob_str(&value), "a");
|
| ︙ | ︙ | |||
1644 1645 1646 1647 1648 1649 1650 | g.cgiOutput = 1; g.fullHttpReply = 1; cgi_handle_http_request(0); process_one_web_page(0); } #if !defined(_WIN32) | | | 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 |
g.cgiOutput = 1;
g.fullHttpReply = 1;
cgi_handle_http_request(0);
process_one_web_page(0);
}
#if !defined(_WIN32)
#if !defined(__DARWIN__) && !defined(__APPLE__) && !defined(__HAIKU__)
/*
** Search for an executable on the PATH environment variable.
** Return true (1) if found and false (0) if not found.
*/
static int binaryOnPath(const char *zBinary){
const char *zPath = fossil_getenv("PATH");
char *zFull;
|
| ︙ | ︙ | |||
1740 1741 1742 1743 1744 1745 1746 |
}else{
iPort = db_get_int("http-port", 8080);
mxPort = iPort+100;
}
#if !defined(_WIN32)
/* Unix implementation */
if( isUiCmd ){
| | | 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 |
}else{
iPort = db_get_int("http-port", 8080);
mxPort = iPort+100;
}
#if !defined(_WIN32)
/* Unix implementation */
if( isUiCmd ){
#if !defined(__DARWIN__) && !defined(__APPLE__) && !defined(__HAIKU__)
zBrowser = db_get("web-browser", 0);
if( zBrowser==0 ){
static char *azBrowserProg[] = { "xdg-open", "gnome-open", "firefox" };
int i;
zBrowser = "echo";
for(i=0; i<sizeof(azBrowserProg)/sizeof(azBrowserProg[0]); i++){
if( binaryOnPath(azBrowserProg[i]) ){
|
| ︙ | ︙ |
Changes to src/makemake.tcl.
| ︙ | ︙ | |||
364 365 366 367 368 369 370 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # | | | | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # ZINCDIR = $(SRCDIR)/../zlib-1.2.7 ZLIBDIR = $(SRCDIR)/../zlib-1.2.7 #### The directories where the OpenSSL include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "openssl-1.x" sub-directory of the # Fossil source code directory and the target OpenSSL source directory. # OPENSSLINCDIR = $(SRCDIR)/../openssl-1.0.1a/include OPENSSLLIBDIR = $(SRCDIR)/../openssl-1.0.1a #### Either the directory where the Tcl library is installed or the Tcl # source code directory resides (depending on the value of the macro # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, # this directory must have "include" and "lib" sub-directories. If # this points to the Tcl source code directory, this directory must # have "generic" and "win" sub-directories. The recommended usage |
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
332 333 334 335 336 337 338 | ** The file consists of zero or more cards, one card per line. ** (Except: the content of the W card can extend of multiple lines.) ** Each card is divided into tokens by a single space character. ** The first token is a single upper-case letter which is the card type. ** The card type determines the other parameters to the card. ** Cards must occur in lexicographical order. */ | | > > | | 332 333 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 |
** The file consists of zero or more cards, one card per line.
** (Except: the content of the W card can extend of multiple lines.)
** Each card is divided into tokens by a single space character.
** The first token is a single upper-case letter which is the card type.
** The card type determines the other parameters to the card.
** Cards must occur in lexicographical order.
*/
Manifest *manifest_parse(Blob *pContent, int rid){
Manifest *p;
int seenZ = 0;
int i, lineNo=0;
ManifestText x;
char cPrevType = 0;
char cType;
char *z;
int n;
char *zUuid;
int sz = 0;
int isRepeat;
static Bag seen;
if( rid==0 ){
isRepeat = 1;
}else if( bag_find(&seen, rid) ){
isRepeat = 1;
}else{
isRepeat = 0;
bag_insert(&seen, rid);
}
/* Every control artifact ends with a '\n' character. Exit early
|
| ︙ | ︙ |
Changes to src/printf.c.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */ #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */ #define etFOSSILIZE 19 /* The fossil header encoding format. */ #define etPATH 20 /* Path type */ #define etWIKISTR 21 /* Wiki text rendered from a char*: %w */ #define etWIKIBLOB 22 /* Wiki text rendered from a Blob*: %W */ #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ /* ** An "etByte" is an 8-bit unsigned value. */ typedef unsigned char etByte; | > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | #define etHTTPIZE 17 /* Make text safe for HTTP. "/" encoded as %2f */ #define etURLIZE 18 /* Make text safe for HTTP. "/" not encoded */ #define etFOSSILIZE 19 /* The fossil header encoding format. */ #define etPATH 20 /* Path type */ #define etWIKISTR 21 /* Wiki text rendered from a char*: %w */ #define etWIKIBLOB 22 /* Wiki text rendered from a Blob*: %W */ #define etSTRINGID 23 /* String with length limit for a UUID prefix: %S */ #define etROOT 24 /* String value of g.zTop: % */ /* ** An "etByte" is an 8-bit unsigned value. */ typedef unsigned char etByte; |
| ︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
{ 'b', 0, 2, etBLOB, 0, 0 },
{ 'B', 0, 2, etBLOBSQL, 0, 0 },
{ 'w', 0, 2, etWIKISTR, 0, 0 },
{ 'W', 0, 2, etWIKIBLOB, 0, 0 },
{ 'h', 0, 4, etHTMLIZE, 0, 0 },
{ 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
{ 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
{ 'F', 0, 4, etFOSSILIZE, 0, 0 },
{ 'S', 0, 4, etSTRINGID, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
{ 'u', 10, 0, etRADIX, 0, 0 },
| > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
{ 'b', 0, 2, etBLOB, 0, 0 },
{ 'B', 0, 2, etBLOBSQL, 0, 0 },
{ 'w', 0, 2, etWIKISTR, 0, 0 },
{ 'W', 0, 2, etWIKIBLOB, 0, 0 },
{ 'h', 0, 4, etHTMLIZE, 0, 0 },
{ 'R', 0, 0, etROOT, 0, 0 },
{ 't', 0, 4, etHTTPIZE, 0, 0 }, /* "/" -> "%2F" */
{ 'T', 0, 4, etURLIZE, 0, 0 }, /* "/" unchanged */
{ 'F', 0, 4, etFOSSILIZE, 0, 0 },
{ 'S', 0, 4, etSTRINGID, 0, 0 },
{ 'c', 0, 0, etCHARX, 0, 0 },
{ 'o', 8, 0, etRADIX, 0, 2 },
{ 'u', 10, 0, etRADIX, 0, 0 },
|
| ︙ | ︙ | |||
568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
bufpt[i]='/';
}else{
bufpt[i]=e[i];
}
}
bufpt[length]='\0';
break;
}
case etSTRINGID: {
precision = 16;
/* Fall through */
}
case etSTRING:
case etDYNSTRING: {
| > > > > > | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 |
bufpt[i]='/';
}else{
bufpt[i]=e[i];
}
}
bufpt[length]='\0';
break;
}
case etROOT: {
bufpt = g.zTop;
length = (int)strlen(bufpt);
break;
}
case etSTRINGID: {
precision = 16;
/* Fall through */
}
case etSTRING:
case etDYNSTRING: {
|
| ︙ | ︙ | |||
860 861 862 863 864 865 866 867 868 869 870 871 872 873 |
int a, b;
do{
a = *zA++;
b = *zB++;
}while( a==b && a!=0 );
return ((unsigned char)a) - (unsigned char)b;
}
}
/*
** Case insensitive string comparison.
*/
int fossil_strnicmp(const char *zA, const char *zB, int nByte){
if( zA==0 ){
| > > > > > > > > > > > > > > > > > | 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 |
int a, b;
do{
a = *zA++;
b = *zB++;
}while( a==b && a!=0 );
return ((unsigned char)a) - (unsigned char)b;
}
}
int fossil_strncmp(const char *zA, const char *zB, int nByte){
if( zA==0 ){
if( zB==0 ) return 0;
return -1;
}else if( zB==0 ){
return +1;
}else if( nByte>0 ){
int a, b;
do{
a = *zA++;
b = *zB++;
}while( a==b && a!=0 && (--nByte)>0 );
return ((unsigned char)a) - (unsigned char)b;
}else{
return 0;
}
}
/*
** Case insensitive string comparison.
*/
int fossil_strnicmp(const char *zA, const char *zB, int nByte){
if( zA==0 ){
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
54 55 56 57 58 59 60 |
}
rn = db_column_int(&q, 0);
cnt++;
blob_appendf(&ril, "<li>");
if( zTitle[0] == '_' ){
blob_appendf(&ril, "%s", zTitle);
} else {
| | | > | > | > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
}
rn = db_column_int(&q, 0);
cnt++;
blob_appendf(&ril, "<li>");
if( zTitle[0] == '_' ){
blob_appendf(&ril, "%s", zTitle);
} else {
blob_appendf(&ril, "%z%h</a>", href("%R/rptview?rn=%d", rn), zTitle);
}
blob_appendf(&ril, " ");
if( g.perm.Write && zOwner && zOwner[0] ){
blob_appendf(&ril, "(by <i>%h</i></i>) ", zOwner);
}
if( g.perm.TktFmt ){
blob_appendf(&ril, "[%zcopy</a>] ",
href("%R/rptedit?rn=%d©=1", rn));
}
if( g.perm.Admin
|| (g.perm.WrTkt && zOwner && fossil_strcmp(g.zLogin,zOwner)==0)
){
blob_appendf(&ril, "[%zedit</a>]",
href("%R/rptedit?rn=%d", rn));
}
if( g.perm.TktFmt ){
blob_appendf(&ril, "[%zsql</a>]",
href("%R/rptsql?rn=%d", rn));
}
blob_appendf(&ril, "</li>\n");
}
Th_Store("report_items", blob_str(&ril));
Th_Render(zScript);
|
| ︙ | ︙ | |||
414 415 416 417 418 419 420 |
zTitle = mprintf("Copy Of %s", zTitle);
zOwner = g.zLogin;
}
}
if( zOwner==0 ) zOwner = g.zLogin;
style_submenu_element("Cancel", "Cancel", "reportlist");
if( rn>0 ){
| | | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
zTitle = mprintf("Copy Of %s", zTitle);
zOwner = g.zLogin;
}
}
if( zOwner==0 ) zOwner = g.zLogin;
style_submenu_element("Cancel", "Cancel", "reportlist");
if( rn>0 ){
style_submenu_element("Delete", "Delete", "rptedit?rn=%d&del1=1", rn);
}
style_header(rn>0 ? "Edit Report Format":"Create New Report Format");
if( zErr ){
@ <blockquote class="reportError">%h(zErr)</blockquote>
}
@ <form action="rptedit" method="post"><div>
@ <input type="hidden" name="rn" value="%d(rn)" />
|
| ︙ | ︙ | |||
718 719 720 721 722 723 724 |
for(i=0; i<nArg; i++){
char *zData;
if( i==pState->iBg ) continue;
zData = azArg[i];
if( zData==0 ) zData = "";
if( pState->iNewRow>=0 && i>=pState->iNewRow ){
if( zTid && g.perm.Write ){
| | < < < | < | | 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 |
for(i=0; i<nArg; i++){
char *zData;
if( i==pState->iBg ) continue;
zData = azArg[i];
if( zData==0 ) zData = "";
if( pState->iNewRow>=0 && i>=pState->iNewRow ){
if( zTid && g.perm.Write ){
@ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td>
zTid = 0;
}
if( zData[0] ){
Blob content;
@ </tr><tr style="background-color:%h(zBg)"><td colspan=%d(pState->nCol)>
blob_init(&content, zData, -1);
wiki_convert(&content, 0, 0);
blob_reset(&content);
}
}else if( azName[i][0]=='#' ){
zTid = zData;
@ <td valign="top">%z(href("%R/tktview?name=%h",zData))%h(zData)</a></td>
}else if( zData[0]==0 ){
@ <td valign="top"> </td>
}else{
@ <td valign="top">
@ %h(zData)
@ </td>
}
}
if( zTid && g.perm.Write ){
@ <td valign="top">%z(href("%R/tktedit/%h",zTid))edit</a></td>
}
@ </tr>
return 0;
}
/*
** Output the text given in the argument. Convert tabs and newlines into
|
| ︙ | ︙ | |||
947 948 949 950 951 952 953 |
count = 0;
if( !tabs ){
struct GenerateHTML sState;
db_multi_exec("PRAGMA empty_result_callbacks=ON");
style_submenu_element("Raw", "Raw",
| | | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 |
count = 0;
if( !tabs ){
struct GenerateHTML sState;
db_multi_exec("PRAGMA empty_result_callbacks=ON");
style_submenu_element("Raw", "Raw",
"rptview?tablist=1&%h", PD("QUERY_STRING",""));
if( g.perm.Admin
|| (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn);
}
if( g.perm.TktFmt ){
style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn);
}
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
** WEBPAGE: setup_ulist
**
** Show a list of users. Clicking on any user jumps to the edit
** screen for that user.
*/
void setup_ulist(void){
Stmt s;
login_check_credentials();
if( !g.perm.Admin ){
login_needed();
return;
}
style_submenu_element("Add", "Add User", "setup_uedit");
style_header("User List");
@ <table class="usetupLayoutTable">
@ <tr><td class="usetupColumnLayout">
@ <span class="note">Users:</span>
@ <table class="usetupUserList">
| > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > | > | | > | < < > | > > | | | 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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
** WEBPAGE: setup_ulist
**
** Show a list of users. Clicking on any user jumps to the edit
** screen for that user.
*/
void setup_ulist(void){
Stmt s;
int prevLevel = 0;
login_check_credentials();
if( !g.perm.Admin ){
login_needed();
return;
}
style_submenu_element("Add", "Add User", "setup_uedit");
style_header("User List");
@ <table class="usetupLayoutTable">
@ <tr><td class="usetupColumnLayout">
@ <span class="note">Users:</span>
@ <table class="usetupUserList">
prevLevel = 0;
db_prepare(&s,
"SELECT uid, login, cap, info, 1 FROM user"
" WHERE login IN ('anonymous','nobody','developer','reader') "
" UNION ALL "
"SELECT uid, login, cap, info, 2 FROM user"
" WHERE login NOT IN ('anonymous','nobody','developer','reader') "
"ORDER BY 5, 2"
);
while( db_step(&s)==SQLITE_ROW ){
int iLevel = db_column_int(&s, 4);
const char *zCap = db_column_text(&s, 2);
const char *zLogin = db_column_text(&s, 1);
if( iLevel>prevLevel ){
if( prevLevel>0 ){
@ <tr><td colspan="3"><hr></td></tr>
}
if( iLevel==1 ){
@ <tr>
@ <th class="usetupListUser"
@ style="text-align: right;padding-right: 20px;">Category</th>
@ <th class="usetupListCap"
@ style="text-align: center;padding-right: 15px;">Capabilities</th>
@ <th class="usetupListCon"
@ style="text-align: left;">Notes</th>
@ </tr>
}else{
@ <tr>
@ <th class="usetupListUser"
@ style="text-align: right;padding-right: 20px;">User ID</th>
@ <th class="usetupListCap"
@ style="text-align: center;padding-right: 15px;">Capabilities</th>
@ <th class="usetupListCon"
@ style="text-align: left;">Contact Info</th>
@ </tr>
}
prevLevel = iLevel;
}
@ <tr>
@ <td class="usetupListUser"
@ style="text-align: right;padding-right: 20px;white-space:nowrap;">
if( g.perm.Admin && (zCap[0]!='s' || g.perm.Setup) ){
@ <a href="setup_uedit?id=%d(db_column_int(&s,0))">
}
@ %h(zLogin)
if( g.perm.Admin ){
@ </a>
}
@ </td>
@ <td class="usetupListCap" style="text-align: center;padding-right: 15px;">%s(zCap)</td>
@ <td class="usetupListCon" style="text-align: left;">%h(db_column_text(&s,3))</td>
@ </tr>
|
| ︙ | ︙ | |||
522 523 524 525 526 527 528 |
}
@ <input type="checkbox" name="aa"%s(oaa) />%s(B('a'))Admin<br />
@ <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br />
@ <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br />
@ <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br />
@ <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br />
@ <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br />
| | | 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 |
}
@ <input type="checkbox" name="aa"%s(oaa) />%s(B('a'))Admin<br />
@ <input type="checkbox" name="ad"%s(oad) />%s(B('d'))Delete<br />
@ <input type="checkbox" name="ae"%s(oae) />%s(B('e'))Email<br />
@ <input type="checkbox" name="ap"%s(oap) />%s(B('p'))Password<br />
@ <input type="checkbox" name="ai"%s(oai) />%s(B('i'))Check-In<br />
@ <input type="checkbox" name="ao"%s(oao) />%s(B('o'))Check-Out<br />
@ <input type="checkbox" name="ah"%s(oah) />%s(B('h'))Hyperlinks<br />
@ <input type="checkbox" name="au"%s(oau) />%s(B('u'))Reader<br />
@ <input type="checkbox" name="av"%s(oav) />%s(B('v'))Developer<br />
@ <input type="checkbox" name="ag"%s(oag) />%s(B('g'))Clone<br />
@ <input type="checkbox" name="aj"%s(oaj) />%s(B('j'))Read Wiki<br />
@ <input type="checkbox" name="af"%s(oaf) />%s(B('f'))New Wiki<br />
@ <input type="checkbox" name="am"%s(oam) />%s(B('m'))Append Wiki<br />
@ <input type="checkbox" name="ak"%s(oak) />%s(B('k'))Write Wiki<br />
|
| ︙ | ︙ | |||
623 624 625 626 627 628 629 | @ by anonymous users. This capability is intended for deletion of spam. @ The delete capability is only in effect for 24 hours after the item @ is first posted. The <span class="usertype">Setup</span> user can @ delete anything at any time. @ </p></li> @ @ <li><p> | | | | | | 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 | @ by anonymous users. This capability is intended for deletion of spam. @ The delete capability is only in effect for 24 hours after the item @ is first posted. The <span class="usertype">Setup</span> user can @ delete anything at any time. @ </p></li> @ @ <li><p> @ The <span class="capability">Hyperlinks</span> privilege allows a user @ to see most hyperlinks. This is recommended ON for most logged-in users @ but OFF for user "nobody" to avoid problems with spiders trying to walk @ every diff and annotation of every historical check-in and file. @ </p></li> @ @ <li><p> @ The <span class="capability">Zip</span> privilege allows a user to @ see the "download as ZIP" @ hyperlink and permits access to the <tt>/zip</tt> page. This allows @ users to download ZIP archives without granting other rights like @ <span class="capability">Read</span> or @ <span class="capability">Hyperlink</span>. The "z" privilege is recommended @ for user <span class="usertype">nobody</span> so that automatic package @ downloaders can obtain the sources without going through the login @ procedure. @ </p></li> @ @ <li><p> @ The <span class="capability">Check-in</span> privilege allows remote @ users to "push". The <span class="capability">Check-out</span> privilege |
| ︙ | ︙ | |||
702 703 704 705 706 707 708 | @ capabilities of the <span class="usertype">nobody</span> user are @ inherited by all users, regardless of whether or not they are logged in. @ To disable universal access to the repository, make sure no user named @ <span class="usertype">nobody</span> exists or that the @ <span class="usertype">nobody</span> user has no capabilities @ enabled. The password for <span class="usertype">nobody</span> is ignore. @ To avoid problems with spiders overloading the server, it is recommended | | | | 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 | @ capabilities of the <span class="usertype">nobody</span> user are @ inherited by all users, regardless of whether or not they are logged in. @ To disable universal access to the repository, make sure no user named @ <span class="usertype">nobody</span> exists or that the @ <span class="usertype">nobody</span> user has no capabilities @ enabled. The password for <span class="usertype">nobody</span> is ignore. @ To avoid problems with spiders overloading the server, it is recommended @ that the <span class="capability">h</span> (Hyperlinks) capability be @ turned off for the <span class="usertype">nobody</span> user. @ </p></li> @ @ <li><p> @ Login is required for user <span class="usertype">anonymous</span> but the @ password is displayed on the login screen beside the password entry box @ so anybody who can read should be able to login as anonymous. @ On the other hand, spiders and web-crawlers will typically not |
| ︙ | ︙ | |||
889 890 891 892 893 894 895 | @ <p>Fossil tries to limit out-bound sync, clone, and pull packets @ to this many bytes, uncompressed. If the client requires more data @ than this, then the client will issue multiple HTTP requests. @ Values below 1 million are not recommended. 5 million is a @ reasonable number.</p> @ <hr /> | > | | | | > > | > | > > > > > > | > > > > > > > > > > | > > | | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 |
@ <p>Fossil tries to limit out-bound sync, clone, and pull packets
@ to this many bytes, uncompressed. If the client requires more data
@ than this, then the client will issue multiple HTTP requests.
@ Values below 1 million are not recommended. 5 million is a
@ reasonable number.</p>
@ <hr />
onoff_attribute(
"Enable hyperlinks for \"nobody\" based on User-Agent and Javascript",
"auto-hyperlink", "autohyperlink", 1);
@ <p>Enable hyperlinks (the equivalent of the "h" permission) for all users
@ including user "nobody", as long as (1) the User-Agent string in the
@ HTTP header indicates that the request is coming from an actual human
@ being and not a a robot or spider and (2) the user agent is able to
@ run Javascript in order to set the href= attribute of hyperlinks. Bots
@ and spiders can specify whatever User-Agent string they that want and
@ they can run javascript just like browsers. But most bots don't go to
@ that much trouble so this is normally an effective defense.</p>
@
@ <p>You do not normally want a bot to walk your entire repository because
@ if it does, your server will end up computing diffs and annotations for
@ every historical version of every file and creating ZIPs and tarballs of
@ every historical check-in, which can use a lot of CPU and bandwidth
@ even for relatively small projects.</p>
@ <hr />
entry_attribute("Public pages", 30, "public-pages",
"pubpage", "");
@ <p>A comma-separated list of glob patterns for pages that are accessible
@ without needing a login and using the privileges given by the
@ "Default privileges" setting below. Example use case: Set this field
@ to "/doc/trunk/www/*" to give anonymous users read-only permission to the
@ latest version of the embedded documentation in the www/ folder without
@ allowing them to see the rest of the source code.
@ </p>
@ <hr />
onoff_attribute("Allow users to register themselves",
"self-register", "selfregister", 0);
@ <p>Allow users to register themselves through the HTTP UI.
@ The registration form always requires filling in a CAPTCHA
@ (<em>auto-captcha</em> setting is ignored). Still, bear in mind that anyone
@ can register under any user name. This option is useful for public projects
@ where you do not want everyone in any ticket discussion to be named
@ "Anonymous".</p>
@ <hr />
entry_attribute("Default privileges", 10, "default-perms",
"defaultperms", "u");
@ <p>Permissions given to users that... <ul><li>register themselves using
@ the self-registration procedure (if enabled), or <li>access "public"
@ pages identified by the public-pages glob pattern above, or <li>
@ are users newly created by the administrator.</ul>
@ </p>
@ <hr />
onoff_attribute("Show javascript button to fill in CAPTCHA",
"auto-captcha", "autocaptcha", 0);
@ <p>When enabled, a button appears on the login screen for user
@ "anonymous" that will automatically fill in the CAPTCHA password.
|
| ︙ | ︙ |
Changes to src/shell.c.
| ︙ | ︙ | |||
417 418 419 420 421 422 423 424 425 426 427 428 429 430 |
*/
struct callback_data {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
int statsOn; /* True to display memory stats before each finalize */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
int nErr; /* Number of errors seen */
int mode; /* An output mode setting */
int writableSchema; /* True if PRAGMA writable_schema=ON */
int showHeader; /* True to show column names in List or Column mode */
char *zDestTable; /* Name of destination table when MODE_Insert */
char separator[20]; /* Separator character for MODE_List */
int colWidth[100]; /* Requested width of each column when in column mode*/
| > | 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
*/
struct callback_data {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
int statsOn; /* True to display memory stats before each finalize */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
FILE *traceOut; /* Output for sqlite3_trace() */
int nErr; /* Number of errors seen */
int mode; /* An output mode setting */
int writableSchema; /* True if PRAGMA writable_schema=ON */
int showHeader; /* True to show column names in List or Column mode */
char *zDestTable; /* Name of destination table when MODE_Insert */
char separator[20]; /* Separator character for MODE_List */
int colWidth[100]; /* Requested width of each column when in column mode*/
|
| ︙ | ︙ | |||
494 495 496 497 498 499 500 |
/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
int i;
char *zBlob = (char *)pBlob;
fprintf(out,"X'");
| | | 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
int i;
char *zBlob = (char *)pBlob;
fprintf(out,"X'");
for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
fprintf(out,"'");
}
/*
** Output the given string as a quoted string using SQL quoting conventions.
*/
static void output_quoted_string(FILE *out, const char *z){
|
| ︙ | ︙ | |||
1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 |
zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
/* Always quote the table name, even if it appears to be pure ascii,
** in case it is a keyword. Ex: INSERT INTO "table" ... */
zTmp = appendText(zTmp, zTable, '"');
if( zTmp ){
zSelect = appendText(zSelect, zTmp, '\'');
}
zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
rc = sqlite3_step(pTableInfo);
while( rc==SQLITE_ROW ){
const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
zSelect = appendText(zSelect, "quote(", 0);
zSelect = appendText(zSelect, zText, '"');
| > | 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 |
zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
/* Always quote the table name, even if it appears to be pure ascii,
** in case it is a keyword. Ex: INSERT INTO "table" ... */
zTmp = appendText(zTmp, zTable, '"');
if( zTmp ){
zSelect = appendText(zSelect, zTmp, '\'');
free(zTmp);
}
zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
rc = sqlite3_step(pTableInfo);
while( rc==SQLITE_ROW ){
const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
zSelect = appendText(zSelect, "quote(", 0);
zSelect = appendText(zSelect, zText, '"');
|
| ︙ | ︙ | |||
1333 1334 1335 1336 1337 1338 1339 |
zSelect = appendText(zSelect, zTable, '"');
rc = run_table_dump_query(p, zSelect, zPrepStmt);
if( rc==SQLITE_CORRUPT ){
zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
run_table_dump_query(p, zSelect, 0);
}
| | | 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 |
zSelect = appendText(zSelect, zTable, '"');
rc = run_table_dump_query(p, zSelect, zPrepStmt);
if( rc==SQLITE_CORRUPT ){
zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
run_table_dump_query(p, zSelect, 0);
}
free(zSelect);
}
return 0;
}
/*
** Run zQuery. Use dump_callback() as the callback routine so that
** the contents of the query are output as SQL statements.
|
| ︙ | ︙ | |||
1363 1364 1365 1366 1367 1368 1369 |
if( zErr ){
fprintf(p->out, "/****** %s ******/\n", zErr);
sqlite3_free(zErr);
zErr = 0;
}
zQ2 = malloc( len+100 );
if( zQ2==0 ) return rc;
| | | 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 |
if( zErr ){
fprintf(p->out, "/****** %s ******/\n", zErr);
sqlite3_free(zErr);
zErr = 0;
}
zQ2 = malloc( len+100 );
if( zQ2==0 ) return rc;
sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
if( rc ){
fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
}else{
rc = SQLITE_CORRUPT;
}
sqlite3_free(zErr);
|
| ︙ | ︙ | |||
1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 | ".separator STRING Change separator used by output mode and .import\n" ".show Show the current values for various settings\n" ".stats ON|OFF Turn stats on or off\n" ".tables ?TABLE? List names of tables\n" " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\n" ".timeout MS Try opening locked tables for MS milliseconds\n" ".vfsname ?AUX? Print the name of the VFS stack\n" ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" ; static char zTimerHelp[] = ".timer ON|OFF Turn the CPU timer measurement on or off\n" ; | > | 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 | ".separator STRING Change separator used by output mode and .import\n" ".show Show the current values for various settings\n" ".stats ON|OFF Turn stats on or off\n" ".tables ?TABLE? List names of tables\n" " If TABLE specified, only list tables matching\n" " LIKE pattern TABLE.\n" ".timeout MS Try opening locked tables for MS milliseconds\n" ".trace FILE|off Output each SQL statement as it is run\n" ".vfsname ?AUX? Print the name of the VFS stack\n" ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n" ; static char zTimerHelp[] = ".timer ON|OFF Turn the CPU timer measurement on or off\n" ; |
| ︙ | ︙ | |||
1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 |
if( strcmp(zArg,"on")==0 ){
val = 1;
}else if( strcmp(zArg,"yes")==0 ){
val = 1;
}
return val;
}
/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 |
if( strcmp(zArg,"on")==0 ){
val = 1;
}else if( strcmp(zArg,"yes")==0 ){
val = 1;
}
return val;
}
/*
** Close an output file, assuming it is not stderr or stdout
*/
static void output_file_close(FILE *f){
if( f && f!=stdout && f!=stderr ) fclose(f);
}
/*
** Try to open an output file. The names "stdout" and "stderr" are
** recognized and do the right thing. NULL is returned if the output
** filename is "off".
*/
static FILE *output_file_open(const char *zFile){
FILE *f;
if( strcmp(zFile,"stdout")==0 ){
f = stdout;
}else if( strcmp(zFile, "stderr")==0 ){
f = stderr;
}else if( strcmp(zFile, "off")==0 ){
f = 0;
}else{
f = fopen(zFile, "wb");
if( f==0 ){
fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
}
}
return f;
}
/*
** A routine for handling output from sqlite3_trace().
*/
static void sql_trace_callback(void *pArg, const char *z){
FILE *f = (FILE*)pArg;
if( f ) fprintf(f, "%s\n", z);
}
/*
** A no-op routine that runs with the ".breakpoint" doc-command. This is
** a useful spot to set a debugger breakpoint.
*/
static void test_breakpoint(void){
static int nCall = 0;
nCall++;
}
/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
|
| ︙ | ︙ | |||
1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 |
}
sqlite3_close(pDest);
}else
if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
bail_on_error = booleanValue(azArg[1]);
}else
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
struct callback_data data;
char *zErrMsg = 0;
open_db(p);
memcpy(&data, p, sizeof(data));
data.showHeader = 1;
| > > > > > > > | 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 |
}
sqlite3_close(pDest);
}else
if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
bail_on_error = booleanValue(azArg[1]);
}else
/* The undocumented ".breakpoint" command causes a call to the no-op
** routine named test_breakpoint().
*/
if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
test_breakpoint();
}else
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
struct callback_data data;
char *zErrMsg = 0;
open_db(p);
memcpy(&data, p, sizeof(data));
data.showHeader = 1;
|
| ︙ | ︙ | |||
1928 1929 1930 1931 1932 1933 1934 |
rc = 1;
}
}else
#endif
if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
const char *zFile = azArg[1];
| < | | < < < < < < < < < < < < < | 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 |
rc = 1;
}
}else
#endif
if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
const char *zFile = azArg[1];
output_file_close(p->pLog);
p->pLog = output_file_open(zFile);
}else
if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
int n2 = strlen30(azArg[1]);
if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
||
(n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
|
| ︙ | ︙ | |||
1996 1997 1998 1999 2000 2001 2002 |
if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
"%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
}else
if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
| < | | | | | < < | < | | > | > | | 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 |
if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
"%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
}else
if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
if( p->outfile[0]=='|' ){
pclose(p->out);
}else{
output_file_close(p->out);
}
p->outfile[0] = 0;
if( azArg[1][0]=='|' ){
p->out = popen(&azArg[1][1], "w");
if( p->out==0 ){
fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
p->out = stdout;
rc = 1;
}else{
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
}
}else{
p->out = output_file_open(azArg[1]);
if( p->out==0 ){
if( strcmp(azArg[1],"off")!=0 ){
fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
}
p->out = stdout;
rc = 1;
} else {
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
}
}
}else
if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
if( nArg >= 2) {
strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
|
| ︙ | ︙ | |||
2140 2141 2142 2143 2144 2145 2146 |
new_colv[1] = 0;
callback(&data, 1, new_argv, new_colv);
rc = SQLITE_OK;
}else{
zShellStatic = azArg[1];
rc = sqlite3_exec(p->db,
"SELECT sql FROM "
| | | | > | | | > | 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 |
new_colv[1] = 0;
callback(&data, 1, new_argv, new_colv);
rc = SQLITE_OK;
}else{
zShellStatic = azArg[1];
rc = sqlite3_exec(p->db,
"SELECT sql FROM "
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_master UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
"WHERE lower(tbl_name) LIKE shellstatic()"
" AND type!='meta' AND sql NOTNULL "
"ORDER BY substr(type,2,1), "
" CASE type WHEN 'view' THEN rowid ELSE name END",
callback, &data, &zErrMsg);
zShellStatic = 0;
}
}else{
rc = sqlite3_exec(p->db,
"SELECT sql FROM "
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_master UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
"ORDER BY substr(type,2,1),"
" CASE type WHEN 'view' THEN rowid ELSE name END",
callback, &data, &zErrMsg
);
}
if( zErrMsg ){
fprintf(stderr,"Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
|
| ︙ | ︙ | |||
2204 2205 2206 2207 2208 2209 2210 2211 |
}else
if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
p->statsOn = booleanValue(azArg[1]);
}else
if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
char **azResult;
| > | | > > | | | | > > > > > > > | | | > | < < | < | < < | | | > > > > > | > > > > | | > | > > > > > > | | | > | > > > | > | | < | < | | > | | 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 |
}else
if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
p->statsOn = booleanValue(azArg[1]);
}else
if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
sqlite3_stmt *pStmt;
char **azResult;
int nRow, nAlloc;
char *zSql = 0;
int ii;
open_db(p);
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ) return rc;
zSql = sqlite3_mprintf(
"SELECT name FROM sqlite_master"
" WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite_%%'"
" AND name LIKE ?1");
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
if( strcmp(zDbName,"temp")==0 ){
zSql = sqlite3_mprintf(
"%z UNION ALL "
"SELECT 'temp.' || name FROM sqlite_temp_master"
" WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite_%%'"
" AND name LIKE ?1", zSql);
}else{
zSql = sqlite3_mprintf(
"%z UNION ALL "
"SELECT '%q.' || name FROM \"%w\".sqlite_master"
" WHERE type IN ('table','view')"
" AND name NOT LIKE 'sqlite_%%'"
" AND name LIKE ?1", zSql, zDbName, zDbName);
}
}
sqlite3_finalize(pStmt);
zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ) return rc;
nRow = nAlloc = 0;
azResult = 0;
if( nArg>1 ){
sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
}else{
sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
}
while( sqlite3_step(pStmt)==SQLITE_ROW ){
if( nRow>=nAlloc ){
char **azNew;
int n = nAlloc*2 + 10;
azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
if( azNew==0 ){
fprintf(stderr, "Error: out of memory\n");
break;
}
nAlloc = n;
azResult = azNew;
}
azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
if( azResult[nRow] ) nRow++;
}
sqlite3_finalize(pStmt);
if( nRow>0 ){
int len, maxlen = 0;
int i, j;
int nPrintCol, nPrintRow;
for(i=0; i<nRow; i++){
len = strlen30(azResult[i]);
if( len>maxlen ) maxlen = len;
}
nPrintCol = 80/(maxlen+2);
if( nPrintCol<1 ) nPrintCol = 1;
nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
for(i=0; i<nPrintRow; i++){
for(j=i; j<nRow; j+=nPrintRow){
char *zSp = j<nPrintRow ? "" : " ";
printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
}
printf("\n");
}
}
for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
sqlite3_free(azResult);
}else
if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
static const struct {
const char *zCtrlName; /* Name of a test-control option */
int ctrlCode; /* Integer code for that option */
} aCtrl[] = {
|
| ︙ | ︙ | |||
2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 |
if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
&& nArg==2
){
enableTimer = booleanValue(azArg[1]);
}else
if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
printf("SQLite %s %s\n" /*extra-version-info*/,
sqlite3_libversion(), sqlite3_sourceid());
}else
if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
const char *zDbName = nArg==2 ? azArg[1] : "main";
| > > > > > > > > > > > > > | 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 |
if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
&& nArg==2
){
enableTimer = booleanValue(azArg[1]);
}else
if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
open_db(p);
output_file_close(p->traceOut);
p->traceOut = output_file_open(azArg[1]);
#ifndef SQLITE_OMIT_TRACE
if( p->traceOut==0 ){
sqlite3_trace(p->db, 0, 0);
}else{
sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
}
#endif
}else
if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
printf("SQLite %s %s\n" /*extra-version-info*/,
sqlite3_libversion(), sqlite3_sourceid());
}else
if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
const char *zDbName = nArg==2 ? azArg[1] : "main";
|
| ︙ | ︙ | |||
2516 2517 2518 2519 2520 2521 2522 |
int startline = 0;
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
fflush(p->out);
free(zLine);
zLine = one_input_line(zSql, in);
if( zLine==0 ){
| > > | | 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 |
int startline = 0;
while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
fflush(p->out);
free(zLine);
zLine = one_input_line(zSql, in);
if( zLine==0 ){
/* End of input */
if( stdin_is_interactive ) printf("\n");
break;
}
if( seenInterrupt ){
if( in!=0 ) break;
seenInterrupt = 0;
}
lineno++;
if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
|
| ︙ | ︙ | |||
2603 2604 2605 2606 2607 2608 2609 | } free(zLine); return errCnt; } /* ** Return a pathname which is the user's home directory. A | | < < | > | | 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 |
}
free(zLine);
return errCnt;
}
/*
** Return a pathname which is the user's home directory. A
** 0 return indicates an error of some kind.
*/
static char *find_home_dir(void){
static char *home_dir = NULL;
if( home_dir ) return home_dir;
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(_WIN32_WCE) && !defined(__RTP__) && !defined(_WRS_KERNEL)
struct passwd *pwent;
uid_t uid = getuid();
if( (pwent=getpwuid(uid)) != NULL) {
home_dir = pwent->pw_dir;
}
#endif
#if defined(_WIN32_WCE)
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
*/
home_dir = "/";
#else
#if defined(_WIN32) || defined(WIN32) || defined(__OS2__)
if (!home_dir) {
home_dir = getenv("USERPROFILE");
}
#endif
|
| ︙ | ︙ | |||
2677 2678 2679 2680 2681 2682 2683 |
struct callback_data *p, /* Configuration data */
const char *sqliterc_override /* Name of config file. NULL to use default */
){
char *home_dir = NULL;
const char *sqliterc = sqliterc_override;
char *zBuf = 0;
FILE *in = NULL;
| < < < < < < < | < | | | 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 |
struct callback_data *p, /* Configuration data */
const char *sqliterc_override /* Name of config file. NULL to use default */
){
char *home_dir = NULL;
const char *sqliterc = sqliterc_override;
char *zBuf = 0;
FILE *in = NULL;
int rc = 0;
if (sqliterc == NULL) {
home_dir = find_home_dir();
if( home_dir==0 ){
#if !defined(__RTP__) && !defined(_WRS_KERNEL)
fprintf(stderr,"%s: Error: cannot locate your home directory\n", Argv0);
#endif
return 1;
}
zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
sqliterc = zBuf;
}
in = fopen(sqliterc,"rb");
if( in ){
if( stdin_is_interactive ){
fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
}
rc = process_input(p,in);
fclose(in);
}
sqlite3_free(zBuf);
return rc;
}
/*
** Show available command line options
*/
static const char zOptions[] =
|
| ︙ | ︙ | |||
3053 3054 3055 3056 3057 3058 3059 |
#endif
rc = process_input(&data, 0);
if( zHistory ){
stifle_history(100);
write_history(zHistory);
free(zHistory);
}
| < | 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 |
#endif
rc = process_input(&data, 0);
if( zHistory ){
stifle_history(100);
write_history(zHistory);
free(zHistory);
}
}else{
rc = process_input(&data, stdin);
}
}
set_table_name(&data, 0);
if( data.db ){
sqlite3_close(data.db);
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | 1 2 3 4 5 6 7 8 9 10 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.7.13. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other |
| ︙ | ︙ | |||
439 440 441 442 443 444 445 | ** The TCL headers are only needed when compiling the TCL bindings. */ #if defined(SQLITE_TCL) || defined(TCLSH) # include <tcl.h> #endif /* | > > | > | > | | > > > | 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | ** The TCL headers are only needed when compiling the TCL bindings. */ #if defined(SQLITE_TCL) || defined(TCLSH) # include <tcl.h> #endif /* ** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that ** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true, ** make it true by defining or undefining NDEBUG. ** ** Setting NDEBUG makes the code smaller and run faster by disabling the ** number assert() statements in the code. So we want the default action ** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG ** is set. Thus NDEBUG becomes an opt-in rather than an opt-out ** feature. */ #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif #if defined(NDEBUG) && defined(SQLITE_DEBUG) # undef NDEBUG #endif /* ** The testcase() macro is used to aid in coverage testing. When ** doing coverage testing, the condition inside the argument to ** testcase() must be evaluated both true and false in order to ** get full branch coverage. The testcase() macro is inserted |
| ︙ | ︙ | |||
653 654 655 656 657 658 659 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.13" #define SQLITE_VERSION_NUMBER 3007013 #define SQLITE_SOURCE_ID "2012-06-07 07:24:04 506008f000ba4af0b35da023b8c52f7a3f5033bd" /* ** 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 |
| ︙ | ︙ | |||
1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ | > > | 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ |
| ︙ | ︙ | |||
1317 1318 1319 1320 1321 1322 1323 | ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the | | | 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 | ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary ** write ahead log and shared memory files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after ** close. Persisting the files is useful when other processes that do not ** have write permission on the directory containing the database file want ** to read the database file, as the WAL and shared memory files must exist ** in order for the database to be readable. The fourth parameter to |
| ︙ | ︙ | |||
2093 2094 2095 2096 2097 2098 2099 | ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] | | | 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 | ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE ** <dd> These options are obsolete and should not be used by new code. ** They are retained for backwards compatibility but are now no-ops. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ |
| ︙ | ︙ | |||
2714 2715 2716 2717 2718 2719 2720 | ** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in ** implementation of these routines to be omitted. That capability ** is no longer provided. Only built-in memory allocators can be used. ** | | | | | 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 | ** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in ** implementation of these routines to be omitted. That capability ** is no longer provided. Only built-in memory allocators can be used. ** ** Prior to SQLite version 3.7.10, the Windows OS interface layer called ** the system malloc() and free() directly when converting ** filenames between the UTF-8 encoding used by SQLite ** and whatever filename encoding is used by the particular Windows ** installation. Memory allocation errors were detected, but ** they were reported back as [SQLITE_CANTOPEN] or ** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. ** ** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] ** must be either NULL or else pointers obtained from a prior ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** |
| ︙ | ︙ | |||
3120 3121 3122 3123 3124 3125 3126 | ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** | | | > | > | | | | 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 | ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** ** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw", ** "rwc", or "memory". Attempting to set it to any other value is ** an error)^. ** ^If "ro" is specified, then the database is opened for read-only ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to ** "rw", then the database is opened for read-write (but not create) ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** been set. ^Value "rwc" is equivalent to setting both ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is ** set to "memory" then a pure [in-memory database] that never reads ** or writes from disk is used. ^It is an error to specify a value for ** the mode parameter that is less restrictive than that specified by ** the flags passed in the third parameter to sqlite3_open_v2(). ** ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| ︙ | ︙ | |||
4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 |
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API char *sqlite3_temp_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 |
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API char *sqlite3_temp_directory;
/*
** CAPI3REF: Name Of The Folder Holding Database Files
**
** ^(If this global variable is made to point to a string which is
** the name of a folder (a.k.a. directory), then all database files
** specified with a relative pathname and created or accessed by
** SQLite when using a built-in [sqlite3_vfs | VFS] will be assumed
** to be relative to that directory.)^ ^If this variable is a NULL
** pointer, then SQLite assumes that all database files specified
** with a relative pathname are relative to the current directory
** for the process.
**
** Changing the value of this variable while a database connection is
** open can result in a corrupt database.
**
** It is not safe to read or modify this variable in more than one
** thread at a time. It is not safe to read or modify this variable
** if a [database connection] is being used at the same time in a separate
** thread.
** It is intended that this variable be set once
** as part of process initialization and before any SQLite interface
** routines have been called and that this variable remain unchanged
** thereafter.
**
** ^The [data_store_directory pragma] may modify this variable and cause
** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
** the [data_store_directory pragma] always assumes that any string
** that this variable points to is held in memory obtained from
** [sqlite3_malloc] and the pragma may attempt to free that memory
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [data_store_directory pragma] should be avoided.
*/
SQLITE_API char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
|
| ︙ | ︙ | |||
5172 5173 5174 5175 5176 5177 5178 | sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache | < | 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 | sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache ** ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** ** ^Cache sharing is enabled and disabled for an entire process. |
| ︙ | ︙ | |||
6560 6561 6562 6563 6564 6565 6566 | ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect | | | 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 | ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 |
| ︙ | ︙ | |||
7531 7532 7533 7534 7535 7536 7537 | ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, | > > > | > | 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 | ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, #ifdef SQLITE_RTREE_INT_ONLY int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), #else int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), #endif void *pContext ); /* ** A pointer to a structure of the following type is passed as the first ** argument to callbacks registered using rtree_geometry_callback(). |
| ︙ | ︙ | |||
9007 9008 9009 9010 9011 9012 9013 | SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); #endif /* Functions used to query pager state and configuration. */ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); | | | 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 | SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); #endif /* Functions used to query pager state and configuration. */ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int); SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager*); SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE int sqlite3PagerNosync(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); |
| ︙ | ︙ | |||
9277 9278 9279 9280 9281 9282 9283 | # endif #else # ifndef SQLITE_OS_WIN # define SQLITE_OS_WIN 0 # endif #endif | < < < > | | < < < | 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 | # endif #else # ifndef SQLITE_OS_WIN # define SQLITE_OS_WIN 0 # endif #endif #if SQLITE_OS_WIN # include <windows.h> #endif #if SQLITE_OS_OS2 # if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY) # include <os2safe.h> /* has to be included before os2.h for linking to work */ # endif # define INCL_DOSDATETIME # define INCL_DOSFILEMGR # define INCL_DOSERRORS # define INCL_DOSMISC # define INCL_DOSPROCESS # define INCL_DOSMODULEMGR # define INCL_DOSSEMAPHORES # include <os2.h> # include <uconv.h> #endif /* ** Determine if we are dealing with Windows NT. ** ** We ought to be able to determine if we are compiling for win98 or winNT ** using the _WIN32_WINNT macro as follows: |
| ︙ | ︙ | |||
9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 | */ #if defined(_WIN32_WCE) # define SQLITE_OS_WINCE 1 #else # define SQLITE_OS_WINCE 0 #endif /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ #ifndef SET_FULLSYNC # define SET_FULLSYNC(x,y) #endif | > > > > > > > > > > > > > > > > | 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 | */ #if defined(_WIN32_WCE) # define SQLITE_OS_WINCE 1 #else # define SQLITE_OS_WINCE 0 #endif /* ** Determine if we are dealing with WindowsRT (Metro) as this has a different and ** incompatible API from win32. */ #if !defined(SQLITE_OS_WINRT) # define SQLITE_OS_WINRT 0 #endif /* ** When compiled for WinCE or WinRT, there is no concept of the current ** directory. */ #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT # define SQLITE_CURDIR 1 #endif /* If the SET_FULLSYNC macro is not defined above, then make it ** a no-op */ #ifndef SET_FULLSYNC # define SET_FULLSYNC(x,y) #endif |
| ︙ | ︙ | |||
10926 10927 10928 10929 10930 10931 10932 10933 10934 |
** NameContext list corresponds to searching through successively outer
** subqueries looking for a match.
*/
struct NameContext {
Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */
ExprList *pEList; /* Optional list of named expressions */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
| > > < < | < < < > > > > > > > > | 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008 11009 11010 11011 11012 11013 11014 11015 |
** NameContext list corresponds to searching through successively outer
** subqueries looking for a match.
*/
struct NameContext {
Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */
ExprList *pEList; /* Optional list of named expressions */
AggInfo *pAggInfo; /* Information about aggregates at this level */
NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
u8 ncFlags; /* Zero or more NC_* flags defined below */
};
/*
** Allowed values for the NameContext, ncFlags field.
*/
#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
/*
** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement.
**
** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
** If there is a LIMIT clause, the parser sets nLimit to the value of the
** limit and nOffset to the value of the offset (or 0 if there is not
|
| ︙ | ︙ | |||
11397 11398 11399 11400 11401 11402 11403 11404 11405 11406 11407 11408 11409 11410 |
struct Walker {
int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
Parse *pParse; /* Parser context. */
union { /* Extra data for callback */
NameContext *pNC; /* Naming context */
int i; /* Integer value */
} u;
};
/* Forward declarations */
SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*);
SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*);
SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*);
| > | 11463 11464 11465 11466 11467 11468 11469 11470 11471 11472 11473 11474 11475 11476 11477 |
struct Walker {
int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
Parse *pParse; /* Parser context. */
union { /* Extra data for callback */
NameContext *pNC; /* Naming context */
int i; /* Integer value */
SrcList *pSrcList; /* FROM clause */
} u;
};
/* Forward declarations */
SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*);
SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*);
SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*);
|
| ︙ | ︙ | |||
11616 11617 11618 11619 11620 11621 11622 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); | > | > | 11683 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 | SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); SQLITE_PRIVATE void sqlite3BeginParse(Parse*,int); SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*); SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int); SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*); SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); |
| ︙ | ︙ | |||
11765 11766 11767 11768 11769 11770 11771 | SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int); SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*); | | | 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 | SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int); SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void); SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); |
| ︙ | ︙ | |||
12021 12022 12023 12024 12025 12026 12027 12028 12029 12030 12031 12032 12033 12034 | # 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); | > | 12090 12091 12092 12093 12094 12095 12096 12097 12098 12099 12100 12101 12102 12103 12104 | # 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 void sqlite3VtabDisconnect(sqlite3 *db, Table *p); 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); |
| ︙ | ︙ | |||
12474 12475 12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 | "CASE_SENSITIVE_LIKE", #endif #ifdef SQLITE_CHECK_PAGES "CHECK_PAGES", #endif #ifdef SQLITE_COVERAGE_TEST "COVERAGE_TEST", #endif #ifdef SQLITE_DEBUG "DEBUG", #endif #ifdef SQLITE_DEFAULT_LOCKING_MODE "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), #endif | > > > | 12544 12545 12546 12547 12548 12549 12550 12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 | "CASE_SENSITIVE_LIKE", #endif #ifdef SQLITE_CHECK_PAGES "CHECK_PAGES", #endif #ifdef SQLITE_COVERAGE_TEST "COVERAGE_TEST", #endif #ifdef SQLITE_CURDIR "CURDIR", #endif #ifdef SQLITE_DEBUG "DEBUG", #endif #ifdef SQLITE_DEFAULT_LOCKING_MODE "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), #endif |
| ︙ | ︙ | |||
18328 18329 18330 18331 18332 18333 18334 | ** mutexIsNT() is only used for the TryEnterCriticalSection() API call, ** which is only available if your application was compiled with ** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only ** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef ** this out as well. */ #if 0 | | | 18401 18402 18403 18404 18405 18406 18407 18408 18409 18410 18411 18412 18413 18414 18415 |
** mutexIsNT() is only used for the TryEnterCriticalSection() API call,
** which is only available if your application was compiled with
** _WIN32_WINNT defined to a value >= 0x0400. Currently, the only
** call to TryEnterCriticalSection() is #ifdef'ed out, so #ifdef
** this out as well.
*/
#if 0
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define mutexIsNT() (1)
#else
static int mutexIsNT(void){
static int osType = 0;
if( osType==0 ){
OSVERSIONINFO sInfo;
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
| ︙ | ︙ | |||
18381 18382 18383 18384 18385 18386 18387 18388 18389 18390 18391 18392 18393 18394 18395 18396 18397 18398 |
/* As winMutexInit() and winMutexEnd() are called as part
** of the sqlite3_initialize and sqlite3_shutdown()
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static long winMutex_lock = 0;
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
int i;
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
}
winMutex_isInit = 1;
}else{
/* Someone else is in the process of initing the static mutexes */
while( !winMutex_isInit ){
| > > > > > > | | 18454 18455 18456 18457 18458 18459 18460 18461 18462 18463 18464 18465 18466 18467 18468 18469 18470 18471 18472 18473 18474 18475 18476 18477 18478 18479 18480 18481 18482 18483 18484 18485 |
/* As winMutexInit() and winMutexEnd() are called as part
** of the sqlite3_initialize and sqlite3_shutdown()
** processing, the "interlocked" magic is probably not
** strictly necessary.
*/
static long winMutex_lock = 0;
SQLITE_API extern void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
static int winMutexInit(void){
/* The first to increment to 1 does actual initialization */
if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){
int i;
for(i=0; i<ArraySize(winMutex_staticMutexes); i++){
#if SQLITE_OS_WINRT
InitializeCriticalSectionEx(&winMutex_staticMutexes[i].mutex, 0, 0);
#else
InitializeCriticalSection(&winMutex_staticMutexes[i].mutex);
#endif
}
winMutex_isInit = 1;
}else{
/* Someone else is in the process of initing the static mutexes */
while( !winMutex_isInit ){
sqlite3_win32_sleep(1);
}
}
return SQLITE_OK;
}
static int winMutexEnd(void){
/* The first to decrement to 0 does actual shutdown
|
| ︙ | ︙ | |||
18466 18467 18468 18469 18470 18471 18472 18473 18474 18475 18476 18477 18478 18479 18480 |
case SQLITE_MUTEX_FAST:
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
#ifdef SQLITE_DEBUG
p->id = iType;
#endif
InitializeCriticalSection(&p->mutex);
}
break;
}
default: {
assert( winMutex_isInit==1 );
assert( iType-2 >= 0 );
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
| > > > > | 18545 18546 18547 18548 18549 18550 18551 18552 18553 18554 18555 18556 18557 18558 18559 18560 18561 18562 18563 |
case SQLITE_MUTEX_FAST:
case SQLITE_MUTEX_RECURSIVE: {
p = sqlite3MallocZero( sizeof(*p) );
if( p ){
#ifdef SQLITE_DEBUG
p->id = iType;
#endif
#if SQLITE_OS_WINRT
InitializeCriticalSectionEx(&p->mutex, 0, 0);
#else
InitializeCriticalSection(&p->mutex);
#endif
}
break;
}
default: {
assert( winMutex_isInit==1 );
assert( iType-2 >= 0 );
assert( iType-2 < ArraySize(winMutex_staticMutexes) );
|
| ︙ | ︙ | |||
19097 19098 19099 19100 19101 19102 19103 19104 19105 19106 19107 19108 19109 19110 |
if( db ){
if( db->pnBytesFreed ){
*db->pnBytesFreed += sqlite3DbMallocSize(db, p);
return;
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
pBuf->pNext = db->lookaside.pFree;
db->lookaside.pFree = pBuf;
db->lookaside.nOut--;
return;
}
}
assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
| > > > > | 19180 19181 19182 19183 19184 19185 19186 19187 19188 19189 19190 19191 19192 19193 19194 19195 19196 19197 |
if( db ){
if( db->pnBytesFreed ){
*db->pnBytesFreed += sqlite3DbMallocSize(db, p);
return;
}
if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p;
#if SQLITE_DEBUG
/* Trash all content in the buffer being freed */
memset(p, 0xaa, db->lookaside.sz);
#endif
pBuf->pNext = db->lookaside.pFree;
db->lookaside.pFree = pBuf;
db->lookaside.nOut--;
return;
}
}
assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
|
| ︙ | ︙ | |||
24993 24994 24995 24996 24997 24998 24999 | ** Default permissions when creating a new file */ #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 #endif /* | | | | 25080 25081 25082 25083 25084 25085 25086 25087 25088 25089 25090 25091 25092 25093 25094 25095 | ** Default permissions when creating a new file */ #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644 #endif /* ** Default permissions when creating auto proxy dir */ #ifndef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS # define SQLITE_DEFAULT_PROXYDIR_PERMISSIONS 0755 #endif /* ** Maximum supported path-length. */ |
| ︙ | ︙ | |||
25055 25056 25057 25058 25059 25060 25061 | #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID */ #endif | | | 25142 25143 25144 25145 25146 25147 25148 25149 25150 25151 25152 25153 25154 25155 25156 | #endif #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) unsigned fsFlags; /* cached details from statfs() */ #endif #if OS_VXWORKS struct vxworksFileId *pId; /* Unique file ID */ #endif #ifdef SQLITE_DEBUG /* The next group of variables are used to track whether or not the ** transaction counter in bytes 24-27 of database files are updated ** whenever any part of the database changes. An assertion fault will ** occur if a file is updated without also updating the transaction ** counter. This test is made to avoid new problems similar to the ** one described by ticket #3584. */ |
| ︙ | ︙ | |||
25090 25091 25092 25093 25094 25095 25096 | #else # define UNIXFILE_DIRSYNC 0x00 #endif #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ | < | 25177 25178 25179 25180 25181 25182 25183 25184 25185 25186 25187 25188 25189 25190 | #else # define UNIXFILE_DIRSYNC 0x00 #endif #define UNIXFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ #define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of os_unix.c ***************/ /************** Begin file os_common.h ***************************************/ /* |
| ︙ | ︙ | |||
25343 25344 25345 25346 25347 25348 25349 25350 25351 25352 25353 25354 25355 25356 |
**
** The safest way to deal with the problem is to always use this wrapper
** which always has the same well-defined interface.
*/
static int posixOpen(const char *zFile, int flags, int mode){
return open(zFile, flags, mode);
}
/* Forward reference */
static int openDirectory(const char*, int*);
/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
| > > > > > > > > > | 25429 25430 25431 25432 25433 25434 25435 25436 25437 25438 25439 25440 25441 25442 25443 25444 25445 25446 25447 25448 25449 25450 25451 |
**
** The safest way to deal with the problem is to always use this wrapper
** which always has the same well-defined interface.
*/
static int posixOpen(const char *zFile, int flags, int mode){
return open(zFile, flags, mode);
}
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int posixFchown(int fd, uid_t uid, gid_t gid){
return geteuid() ? 0 : fchown(fd,uid,gid);
}
/* Forward reference */
static int openDirectory(const char*, int*);
/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
|
| ︙ | ︙ | |||
25455 25456 25457 25458 25459 25460 25461 |
{ "mkdir", (sqlite3_syscall_ptr)mkdir, 0 },
#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
| | | 25550 25551 25552 25553 25554 25555 25556 25557 25558 25559 25560 25561 25562 25563 25564 |
{ "mkdir", (sqlite3_syscall_ptr)mkdir, 0 },
#define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent)
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
{ "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
{ "umask", (sqlite3_syscall_ptr)umask, 0 },
#define osUmask ((mode_t(*)(mode_t))aSyscall[21].pCurrent)
}; /* End of the overrideable system calls */
|
| ︙ | ︙ | |||
25548 25549 25550 25551 25552 25553 25554 |
if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
}
return 0;
}
/*
** Invoke open(). Do so multiple times, until it either succeeds or
| | | > > > > > > | > > > | | 25643 25644 25645 25646 25647 25648 25649 25650 25651 25652 25653 25654 25655 25656 25657 25658 25659 25660 25661 25662 25663 25664 25665 25666 25667 25668 25669 25670 25671 25672 25673 25674 25675 25676 25677 25678 25679 25680 25681 25682 25683 25684 25685 25686 25687 25688 25689 25690 25691 25692 25693 25694 25695 |
if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
}
return 0;
}
/*
** Invoke open(). Do so multiple times, until it either succeeds or
** fails for some reason other than EINTR.
**
** If the file creation mode "m" is 0 then set it to the default for
** SQLite. The default is SQLITE_DEFAULT_FILE_PERMISSIONS (normally
** 0644) as modified by the system umask. If m is not 0, then
** make the file creation mode be exactly m ignoring the umask.
**
** The m parameter will be non-zero only when creating -wal, -journal,
** and -shm files. We want those files to have *exactly* the same
** permissions as their original database, unadulterated by the umask.
** In that way, if a database file is -rw-rw-rw or -rw-rw-r-, and a
** transaction crashes and leaves behind hot journals, then any
** process that is able to write to the database will also be able to
** recover the hot journals.
*/
static int robust_open(const char *z, int f, mode_t m){
int fd;
mode_t m2;
mode_t origM = 0;
if( m==0 ){
m2 = SQLITE_DEFAULT_FILE_PERMISSIONS;
}else{
m2 = m;
origM = osUmask(0);
}
do{
#if defined(O_CLOEXEC)
fd = osOpen(z,f|O_CLOEXEC,m2);
#else
fd = osOpen(z,f,m2);
#endif
}while( fd<0 && errno==EINTR );
if( m ){
osUmask(origM);
}
#if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
if( fd>=0 ) osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
#endif
return fd;
}
/*
** Helper functions to obtain and relinquish the global mutex. The
** global mutex is used to protect the unixInodeInfo and
** vxworksFileId objects used by this file, all of which may be
** shared by multiple threads.
|
| ︙ | ︙ | |||
26590 26591 26592 26593 26594 26595 26596 |
if( rc!=SQLITE_BUSY ){
pFile->lastErrno = tErrno;
}
}
}
| | | 26694 26695 26696 26697 26698 26699 26700 26701 26702 26703 26704 26705 26706 26707 26708 |
if( rc!=SQLITE_BUSY ){
pFile->lastErrno = tErrno;
}
}
}
#ifdef SQLITE_DEBUG
/* Set up the transaction-counter change checking flags when
** transitioning from a SHARED to a RESERVED lock. The change
** from SHARED to RESERVED marks the beginning of a normal
** write operation (not a hot journal rollback).
*/
if( rc==SQLITE_OK
&& pFile->eFileLock<=SHARED_LOCK
|
| ︙ | ︙ | |||
26669 26670 26671 26672 26673 26674 26675 |
}
unixEnterMutex();
pInode = pFile->pInode;
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
| | | 26773 26774 26775 26776 26777 26778 26779 26780 26781 26782 26783 26784 26785 26786 26787 |
}
unixEnterMutex();
pInode = pFile->pInode;
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
#ifdef SQLITE_DEBUG
/* 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.
|
| ︙ | ︙ | |||
27868 27869 27870 27871 27872 27873 27874 |
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
SimulateIOErrorBenign(1);
SimulateIOError( h=(-1) )
SimulateIOErrorBenign(0);
| | | 27972 27973 27974 27975 27976 27977 27978 27979 27980 27981 27982 27983 27984 27985 27986 |
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock );
SimulateIOErrorBenign(1);
SimulateIOError( h=(-1) )
SimulateIOErrorBenign(0);
#ifdef SQLITE_DEBUG
/* 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.
|
| ︙ | ︙ | |||
28172 28173 28174 28175 28176 28177 28178 |
#if 0
assert( pFile->pUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
#endif
| | | 28276 28277 28278 28279 28280 28281 28282 28283 28284 28285 28286 28287 28288 28289 28290 |
#if 0
assert( pFile->pUnused==0
|| offset>=PENDING_BYTE+512
|| offset+amt<=PENDING_BYTE
);
#endif
#ifdef SQLITE_DEBUG
/* If we are doing a normal write to a database file (as opposed to
** doing a hot-journal rollback or a write to some file other than a
** normal database file) then record the fact that the database
** has changed. If the transaction counter is modified, record that
** fact too.
*/
if( pFile->inNormalWrite ){
|
| ︙ | ︙ | |||
28372 28373 28374 28375 28376 28377 28378 |
sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
if( ii>0 ){
zDirname[ii] = '\0';
fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
if( fd>=0 ){
| < < < | 28476 28477 28478 28479 28480 28481 28482 28483 28484 28485 28486 28487 28488 28489 |
sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
if( ii>0 ){
zDirname[ii] = '\0';
fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
if( fd>=0 ){
OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
}
}
*pFd = fd;
return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname));
}
|
| ︙ | ︙ | |||
28457 28458 28459 28460 28461 28462 28463 | SimulateIOError( return SQLITE_IOERR_TRUNCATE ); /* If the user has configured a chunk-size for this file, truncate the ** file so that it consists of an integer number of chunks (i.e. the ** actual file size after the operation may be larger than the requested ** size). */ | | | | 28558 28559 28560 28561 28562 28563 28564 28565 28566 28567 28568 28569 28570 28571 28572 28573 28574 28575 28576 28577 28578 28579 28580 28581 |
SimulateIOError( return SQLITE_IOERR_TRUNCATE );
/* If the user has configured a chunk-size for this file, truncate the
** file so that it consists of an integer number of chunks (i.e. the
** actual file size after the operation may be larger than the requested
** size).
*/
if( pFile->szChunk>0 ){
nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
}
rc = robust_ftruncate(pFile->h, (off_t)nByte);
if( rc ){
pFile->lastErrno = errno;
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
}else{
#ifdef SQLITE_DEBUG
/* If we are doing a normal write to a database file (as opposed to
** doing a hot-journal rollback or a write to some file other than a
** normal database file) and we truncate the file to zero length,
** that effectively updates the change counter. This might happen
** when restoring a database using the backup API from a zero-length
** source.
*/
|
| ︙ | ︙ | |||
28623 28624 28625 28626 28627 28628 28629 |
unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK;
}
| | | 28724 28725 28726 28727 28728 28729 28730 28731 28732 28733 28734 28735 28736 28737 28738 |
unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK;
}
#ifdef SQLITE_DEBUG
/* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and
** it hence it is OK for the transaction change counter to be
** unchanged.
*/
case SQLITE_FCNTL_DB_UNCHANGED: {
((unixFile*)id)->dbUpdate = 0;
|
| ︙ | ︙ | |||
28974 28975 28976 28977 28978 28979 28980 |
if( pShmNode->h<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
goto shm_open_err;
}
/* If this process is running as root, make sure that the SHM file
** is owned by the same user that owns the original database. Otherwise,
| | < < < | < < | 29075 29076 29077 29078 29079 29080 29081 29082 29083 29084 29085 29086 29087 29088 29089 29090 29091 |
if( pShmNode->h<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
goto shm_open_err;
}
/* If this process is running as root, make sure that the SHM file
** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect.
*/
osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
/* Check to see if another process is holding the dead-man switch.
** If not, truncate the file to zero length.
*/
rc = SQLITE_OK;
if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
if( robust_ftruncate(pShmNode->h, 0) ){
|
| ︙ | ︙ | |||
30187 30188 30189 30190 30191 30192 30193 |
if( fd<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
goto open_finished;
}
/* If this process is running as root and if creating a new rollback
** journal or WAL file, set the ownership of the journal or WAL to be
| | < < < | | 30283 30284 30285 30286 30287 30288 30289 30290 30291 30292 30293 30294 30295 30296 30297 30298 30299 30300 |
if( fd<0 ){
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
goto open_finished;
}
/* If this process is running as root and if creating a new rollback
** journal or WAL file, set the ownership of the journal or WAL to be
** the same as the original database.
*/
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
osFchown(fd, uid, gid);
}
}
assert( fd>=0 );
if( pOutFlags ){
*pOutFlags = flags;
}
|
| ︙ | ︙ | |||
30219 30220 30221 30222 30223 30224 30225 |
}
#if SQLITE_ENABLE_LOCKING_STYLE
else{
p->openFlags = openFlags;
}
#endif
| < < < < | 30312 30313 30314 30315 30316 30317 30318 30319 30320 30321 30322 30323 30324 30325 |
}
#if SQLITE_ENABLE_LOCKING_STYLE
else{
p->openFlags = openFlags;
}
#endif
noLock = eType!=SQLITE_OPEN_MAIN_DB;
#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
if( fstatfs(fd, &fsInfo) == -1 ){
((unixFile*)pFile)->lastErrno = errno;
robust_close(p, fd, __LINE__);
|
| ︙ | ︙ | |||
32158 32159 32160 32161 32162 32163 32164 32165 32166 32167 32168 32169 32170 32171 32172 32173 32174 32175 32176 32177 | #endif #endif /* !defined(_OS_COMMON_H_) */ /************** End of os_common.h *******************************************/ /************** Continuing where we left off in os_win.c *********************/ /* ** Some Microsoft compilers lack this definition. */ #ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif /* Forward references */ typedef struct winShm winShm; /* A connection to shared-memory */ typedef struct winShmNode winShmNode; /* A region of shared-memory */ /* ** WinCE lacks native support for file locking so we have to fake it | > > > > > > > > > > > > > > > | 32247 32248 32249 32250 32251 32252 32253 32254 32255 32256 32257 32258 32259 32260 32261 32262 32263 32264 32265 32266 32267 32268 32269 32270 32271 32272 32273 32274 32275 32276 32277 32278 32279 32280 32281 | #endif #endif /* !defined(_OS_COMMON_H_) */ /************** End of os_common.h *******************************************/ /************** Continuing where we left off in os_win.c *********************/ /* ** Macro to find the minimum of two numeric values. */ #ifndef MIN # define MIN(x,y) ((x)<(y)?(x):(y)) #endif /* ** Some Microsoft compilers lack this definition. */ #ifndef INVALID_FILE_ATTRIBUTES # define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif #ifndef FILE_FLAG_MASK # define FILE_FLAG_MASK (0xFF3C0000) #endif #ifndef FILE_ATTRIBUTE_MASK # define FILE_ATTRIBUTE_MASK (0x0003FFF7) #endif /* Forward references */ typedef struct winShm winShm; /* A connection to shared-memory */ typedef struct winShmNode winShmNode; /* A region of shared-memory */ /* ** WinCE lacks native support for file locking so we have to fake it |
| ︙ | ︙ | |||
32213 32214 32215 32216 32217 32218 32219 32220 32221 32222 32223 32224 32225 32226 32227 32228 32229 32230 32231 |
/*
** Allowed values for winFile.ctrlFlags
*/
#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
/*
* If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
* various Win32 API heap functions instead of our own.
*/
#ifdef SQLITE_WIN32_MALLOC
/*
* The initial size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
#endif
| > > > > > > > > > > > > > > > > > > > > > > > > > > | 32317 32318 32319 32320 32321 32322 32323 32324 32325 32326 32327 32328 32329 32330 32331 32332 32333 32334 32335 32336 32337 32338 32339 32340 32341 32342 32343 32344 32345 32346 32347 32348 32349 32350 32351 32352 32353 32354 32355 32356 32357 32358 32359 32360 32361 |
/*
** Allowed values for winFile.ctrlFlags
*/
#define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */
#define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
/*
* The size of the buffer used by sqlite3_win32_write_debug().
*/
#ifndef SQLITE_WIN32_DBG_BUF_SIZE
# define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD)))
#endif
/*
* If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
* various Win32 API heap functions instead of our own.
*/
#ifdef SQLITE_WIN32_MALLOC
/*
* If this is non-zero, an isolated heap will be created by the native Win32
* allocator subsystem; otherwise, the default process heap will be used. This
* setting has no effect when compiling for WinRT. By default, this is enabled
* and an isolated heap will be created to store all allocated data.
*
******************************************************************************
* WARNING: It is important to note that when this setting is non-zero and the
* winMemShutdown function is called (e.g. by the sqlite3_shutdown
* function), all data that was allocated using the isolated heap will
* be freed immediately and any attempt to access any of that freed
* data will almost certainly result in an immediate access violation.
******************************************************************************
*/
#ifndef SQLITE_WIN32_HEAP_CREATE
# define SQLITE_WIN32_HEAP_CREATE (TRUE)
#endif
/*
* The initial size of the Win32-specific heap. This value may be zero.
*/
#ifndef SQLITE_WIN32_HEAP_INIT_SIZE
# define SQLITE_WIN32_HEAP_INIT_SIZE ((SQLITE_DEFAULT_CACHE_SIZE) * \
(SQLITE_DEFAULT_PAGE_SIZE) + 4194304)
#endif
|
| ︙ | ︙ | |||
32302 32303 32304 32305 32306 32307 32308 | */ #ifdef SQLITE_TEST SQLITE_API int sqlite3_os_type = 0; #else static int sqlite3_os_type = 0; #endif | < < < < < < | | < | < > | < < > > > | | | < < < < < < < | < < > > > > | 32432 32433 32434 32435 32436 32437 32438 32439 32440 32441 32442 32443 32444 32445 32446 32447 32448 32449 32450 32451 32452 32453 32454 32455 32456 32457 32458 32459 32460 32461 32462 32463 32464 32465 32466 32467 32468 32469 32470 32471 32472 32473 32474 32475 32476 32477 32478 32479 32480 32481 32482 32483 32484 32485 |
*/
#ifdef SQLITE_TEST
SQLITE_API int sqlite3_os_type = 0;
#else
static int sqlite3_os_type = 0;
#endif
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_ANSI
#endif
#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT
# define SQLITE_WIN32_HAS_WIDE
#endif
#ifndef SYSCALL
# define SYSCALL sqlite3_syscall_ptr
#endif
/*
** This function is not available on Windows CE or WinRT.
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define osAreFileApisANSI() 1
#endif
/*
** Many system calls are accessed through pointer-to-functions so that
** they may be overridden at runtime to facilitate fault injection during
** testing and sandboxing. The following array holds the names and pointers
** to all overrideable system calls.
*/
static struct win_syscall {
const char *zName; /* Name of the sytem call */
sqlite3_syscall_ptr pCurrent; /* Current value of the system call */
sqlite3_syscall_ptr pDefault; /* Default value */
} aSyscall[] = {
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 },
#else
{ "AreFileApisANSI", (SYSCALL)0, 0 },
#endif
#ifndef osAreFileApisANSI
#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
#endif
#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
{ "CharLowerW", (SYSCALL)CharLowerW, 0 },
#else
{ "CharLowerW", (SYSCALL)0, 0 },
#endif
|
| ︙ | ︙ | |||
32383 32384 32385 32386 32387 32388 32389 |
#else
{ "CreateFileA", (SYSCALL)0, 0 },
#endif
#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
| | < < < < < | | | | | | | | | | | | | | | | | | | | > > > > | | | | | | > > > > | | | | | | > > > > | | | > > > > | > > > > | | | | > > > > | | | | > > > > | | < < < > > > > > < < < > > > > > > > > > | | | | | > > > > | > > > > | | | < < < > > > > > < < < > > > | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 32502 32503 32504 32505 32506 32507 32508 32509 32510 32511 32512 32513 32514 32515 32516 32517 32518 32519 32520 32521 32522 32523 32524 32525 32526 32527 32528 32529 32530 32531 32532 32533 32534 32535 32536 32537 32538 32539 32540 32541 32542 32543 32544 32545 32546 32547 32548 32549 32550 32551 32552 32553 32554 32555 32556 32557 32558 32559 32560 32561 32562 32563 32564 32565 32566 32567 32568 32569 32570 32571 32572 32573 32574 32575 32576 32577 32578 32579 32580 32581 32582 32583 32584 32585 32586 32587 32588 32589 32590 32591 32592 32593 32594 32595 32596 32597 32598 32599 32600 32601 32602 32603 32604 32605 32606 32607 32608 32609 32610 32611 32612 32613 32614 32615 32616 32617 32618 32619 32620 32621 32622 32623 32624 32625 32626 32627 32628 32629 32630 32631 32632 32633 32634 32635 32636 32637 32638 32639 32640 32641 32642 32643 32644 32645 32646 32647 32648 32649 32650 32651 32652 32653 32654 32655 32656 32657 32658 32659 32660 32661 32662 32663 32664 32665 32666 32667 32668 32669 32670 32671 32672 32673 32674 32675 32676 32677 32678 32679 32680 32681 32682 32683 32684 32685 32686 32687 32688 32689 32690 32691 32692 32693 32694 32695 32696 32697 32698 32699 32700 32701 32702 32703 32704 32705 32706 32707 32708 32709 32710 32711 32712 32713 32714 32715 32716 32717 32718 32719 32720 32721 32722 32723 32724 32725 32726 32727 32728 32729 32730 32731 32732 32733 32734 32735 32736 32737 32738 32739 32740 32741 32742 32743 32744 32745 32746 32747 32748 32749 32750 32751 32752 32753 32754 32755 32756 32757 32758 32759 32760 32761 32762 32763 32764 32765 32766 32767 32768 32769 32770 32771 32772 32773 32774 32775 32776 32777 32778 32779 32780 32781 32782 32783 32784 32785 32786 32787 32788 32789 32790 32791 32792 32793 32794 32795 32796 32797 32798 32799 32800 32801 32802 32803 32804 32805 32806 32807 32808 32809 32810 32811 32812 32813 32814 32815 32816 32817 32818 32819 32820 32821 32822 32823 32824 32825 32826 32827 32828 32829 32830 32831 32832 32833 32834 32835 32836 32837 32838 32839 32840 32841 32842 32843 32844 32845 32846 32847 32848 32849 32850 32851 32852 32853 32854 32855 32856 32857 32858 32859 32860 32861 32862 32863 32864 32865 32866 32867 32868 32869 32870 32871 32872 32873 32874 32875 32876 32877 32878 32879 32880 32881 32882 32883 32884 32885 32886 32887 32888 32889 32890 32891 32892 32893 32894 32895 32896 32897 32898 32899 32900 32901 32902 32903 32904 32905 32906 32907 32908 32909 32910 32911 32912 32913 32914 32915 32916 32917 32918 32919 32920 32921 32922 32923 32924 32925 32926 32927 32928 32929 32930 32931 32932 32933 32934 32935 32936 32937 32938 32939 32940 32941 32942 32943 32944 32945 32946 32947 32948 32949 32950 32951 32952 32953 32954 32955 32956 32957 32958 32959 32960 32961 32962 32963 32964 32965 32966 32967 32968 32969 32970 32971 32972 32973 32974 32975 32976 32977 32978 32979 32980 32981 32982 32983 32984 32985 32986 32987 32988 32989 32990 32991 32992 32993 32994 32995 32996 32997 32998 32999 33000 33001 33002 33003 33004 33005 33006 33007 33008 33009 33010 33011 33012 33013 33014 33015 33016 33017 33018 33019 33020 33021 33022 33023 33024 33025 33026 33027 33028 33029 33030 33031 33032 33033 33034 33035 33036 33037 |
#else
{ "CreateFileA", (SYSCALL)0, 0 },
#endif
#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "CreateFileW", (SYSCALL)CreateFileW, 0 },
#else
{ "CreateFileW", (SYSCALL)0, 0 },
#endif
#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 },
#else
{ "CreateFileMappingW", (SYSCALL)0, 0 },
#endif
#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
DWORD,DWORD,DWORD,LPCWSTR))aSyscall[6].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "CreateMutexW", (SYSCALL)CreateMutexW, 0 },
#else
{ "CreateMutexW", (SYSCALL)0, 0 },
#endif
#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
LPCWSTR))aSyscall[7].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "DeleteFileA", (SYSCALL)DeleteFileA, 0 },
#else
{ "DeleteFileA", (SYSCALL)0, 0 },
#endif
#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[8].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "DeleteFileW", (SYSCALL)DeleteFileW, 0 },
#else
{ "DeleteFileW", (SYSCALL)0, 0 },
#endif
#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[9].pCurrent)
#if SQLITE_OS_WINCE
{ "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
#else
{ "FileTimeToLocalFileTime", (SYSCALL)0, 0 },
#endif
#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
LPFILETIME))aSyscall[10].pCurrent)
#if SQLITE_OS_WINCE
{ "FileTimeToSystemTime", (SYSCALL)FileTimeToSystemTime, 0 },
#else
{ "FileTimeToSystemTime", (SYSCALL)0, 0 },
#endif
#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
LPSYSTEMTIME))aSyscall[11].pCurrent)
{ "FlushFileBuffers", (SYSCALL)FlushFileBuffers, 0 },
#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[12].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "FormatMessageA", (SYSCALL)FormatMessageA, 0 },
#else
{ "FormatMessageA", (SYSCALL)0, 0 },
#endif
#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
DWORD,va_list*))aSyscall[13].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "FormatMessageW", (SYSCALL)FormatMessageW, 0 },
#else
{ "FormatMessageW", (SYSCALL)0, 0 },
#endif
#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
DWORD,va_list*))aSyscall[14].pCurrent)
{ "FreeLibrary", (SYSCALL)FreeLibrary, 0 },
#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[15].pCurrent)
{ "GetCurrentProcessId", (SYSCALL)GetCurrentProcessId, 0 },
#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[16].pCurrent)
#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
{ "GetDiskFreeSpaceA", (SYSCALL)GetDiskFreeSpaceA, 0 },
#else
{ "GetDiskFreeSpaceA", (SYSCALL)0, 0 },
#endif
#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
LPDWORD))aSyscall[17].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetDiskFreeSpaceW", (SYSCALL)GetDiskFreeSpaceW, 0 },
#else
{ "GetDiskFreeSpaceW", (SYSCALL)0, 0 },
#endif
#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
LPDWORD))aSyscall[18].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetFileAttributesA", (SYSCALL)GetFileAttributesA, 0 },
#else
{ "GetFileAttributesA", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[19].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFileAttributesW", (SYSCALL)GetFileAttributesW, 0 },
#else
{ "GetFileAttributesW", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[20].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFileAttributesExW", (SYSCALL)GetFileAttributesExW, 0 },
#else
{ "GetFileAttributesExW", (SYSCALL)0, 0 },
#endif
#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
LPVOID))aSyscall[21].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetFileSize", (SYSCALL)GetFileSize, 0 },
#else
{ "GetFileSize", (SYSCALL)0, 0 },
#endif
#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[22].pCurrent)
#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
{ "GetFullPathNameA", (SYSCALL)GetFullPathNameA, 0 },
#else
{ "GetFullPathNameA", (SYSCALL)0, 0 },
#endif
#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
LPSTR*))aSyscall[23].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetFullPathNameW", (SYSCALL)GetFullPathNameW, 0 },
#else
{ "GetFullPathNameW", (SYSCALL)0, 0 },
#endif
#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
LPWSTR*))aSyscall[24].pCurrent)
{ "GetLastError", (SYSCALL)GetLastError, 0 },
#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[25].pCurrent)
#if SQLITE_OS_WINCE
/* The GetProcAddressA() routine is only available on Windows CE. */
{ "GetProcAddressA", (SYSCALL)GetProcAddressA, 0 },
#else
/* All other Windows platforms expect GetProcAddress() to take
** an ANSI string regardless of the _UNICODE setting */
{ "GetProcAddressA", (SYSCALL)GetProcAddress, 0 },
#endif
#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
LPCSTR))aSyscall[26].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetSystemInfo", (SYSCALL)GetSystemInfo, 0 },
#else
{ "GetSystemInfo", (SYSCALL)0, 0 },
#endif
#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[27].pCurrent)
{ "GetSystemTime", (SYSCALL)GetSystemTime, 0 },
#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[28].pCurrent)
#if !SQLITE_OS_WINCE
{ "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
#else
{ "GetSystemTimeAsFileTime", (SYSCALL)0, 0 },
#endif
#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
LPFILETIME))aSyscall[29].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetTempPathA", (SYSCALL)GetTempPathA, 0 },
#else
{ "GetTempPathA", (SYSCALL)0, 0 },
#endif
#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[30].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "GetTempPathW", (SYSCALL)GetTempPathW, 0 },
#else
{ "GetTempPathW", (SYSCALL)0, 0 },
#endif
#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[31].pCurrent)
#if !SQLITE_OS_WINRT
{ "GetTickCount", (SYSCALL)GetTickCount, 0 },
#else
{ "GetTickCount", (SYSCALL)0, 0 },
#endif
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[32].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
#else
{ "GetVersionExA", (SYSCALL)0, 0 },
#endif
#define osGetVersionExA ((BOOL(WINAPI*)( \
LPOSVERSIONINFOA))aSyscall[33].pCurrent)
{ "HeapAlloc", (SYSCALL)HeapAlloc, 0 },
#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
SIZE_T))aSyscall[34].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapCreate", (SYSCALL)HeapCreate, 0 },
#else
{ "HeapCreate", (SYSCALL)0, 0 },
#endif
#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
SIZE_T))aSyscall[35].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapDestroy", (SYSCALL)HeapDestroy, 0 },
#else
{ "HeapDestroy", (SYSCALL)0, 0 },
#endif
#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[36].pCurrent)
{ "HeapFree", (SYSCALL)HeapFree, 0 },
#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[37].pCurrent)
{ "HeapReAlloc", (SYSCALL)HeapReAlloc, 0 },
#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
SIZE_T))aSyscall[38].pCurrent)
{ "HeapSize", (SYSCALL)HeapSize, 0 },
#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[39].pCurrent)
#if !SQLITE_OS_WINRT
{ "HeapValidate", (SYSCALL)HeapValidate, 0 },
#else
{ "HeapValidate", (SYSCALL)0, 0 },
#endif
#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
LPCVOID))aSyscall[40].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "LoadLibraryA", (SYSCALL)LoadLibraryA, 0 },
#else
{ "LoadLibraryA", (SYSCALL)0, 0 },
#endif
#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[41].pCurrent)
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
{ "LoadLibraryW", (SYSCALL)LoadLibraryW, 0 },
#else
{ "LoadLibraryW", (SYSCALL)0, 0 },
#endif
#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[42].pCurrent)
#if !SQLITE_OS_WINRT
{ "LocalFree", (SYSCALL)LocalFree, 0 },
#else
{ "LocalFree", (SYSCALL)0, 0 },
#endif
#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[43].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "LockFile", (SYSCALL)LockFile, 0 },
#else
{ "LockFile", (SYSCALL)0, 0 },
#endif
#ifndef osLockFile
#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
DWORD))aSyscall[44].pCurrent)
#endif
#if !SQLITE_OS_WINCE
{ "LockFileEx", (SYSCALL)LockFileEx, 0 },
#else
{ "LockFileEx", (SYSCALL)0, 0 },
#endif
#ifndef osLockFileEx
#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[45].pCurrent)
#endif
#if !SQLITE_OS_WINRT
{ "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 },
#else
{ "MapViewOfFile", (SYSCALL)0, 0 },
#endif
#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
SIZE_T))aSyscall[46].pCurrent)
{ "MultiByteToWideChar", (SYSCALL)MultiByteToWideChar, 0 },
#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
int))aSyscall[47].pCurrent)
{ "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
LARGE_INTEGER*))aSyscall[48].pCurrent)
{ "ReadFile", (SYSCALL)ReadFile, 0 },
#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
LPOVERLAPPED))aSyscall[49].pCurrent)
{ "SetEndOfFile", (SYSCALL)SetEndOfFile, 0 },
#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[50].pCurrent)
#if !SQLITE_OS_WINRT
{ "SetFilePointer", (SYSCALL)SetFilePointer, 0 },
#else
{ "SetFilePointer", (SYSCALL)0, 0 },
#endif
#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
DWORD))aSyscall[51].pCurrent)
#if !SQLITE_OS_WINRT
{ "Sleep", (SYSCALL)Sleep, 0 },
#else
{ "Sleep", (SYSCALL)0, 0 },
#endif
#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[52].pCurrent)
{ "SystemTimeToFileTime", (SYSCALL)SystemTimeToFileTime, 0 },
#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
LPFILETIME))aSyscall[53].pCurrent)
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
{ "UnlockFile", (SYSCALL)UnlockFile, 0 },
#else
{ "UnlockFile", (SYSCALL)0, 0 },
#endif
#ifndef osUnlockFile
#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
DWORD))aSyscall[54].pCurrent)
#endif
#if !SQLITE_OS_WINCE
{ "UnlockFileEx", (SYSCALL)UnlockFileEx, 0 },
#else
{ "UnlockFileEx", (SYSCALL)0, 0 },
#endif
#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
LPOVERLAPPED))aSyscall[55].pCurrent)
{ "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 },
#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent)
{ "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 },
#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
LPCSTR,LPBOOL))aSyscall[57].pCurrent)
{ "WriteFile", (SYSCALL)WriteFile, 0 },
#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
LPOVERLAPPED))aSyscall[58].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateEventExW", (SYSCALL)CreateEventExW, 0 },
#else
{ "CreateEventExW", (SYSCALL)0, 0 },
#endif
#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
DWORD,DWORD))aSyscall[59].pCurrent)
#if !SQLITE_OS_WINRT
{ "WaitForSingleObject", (SYSCALL)WaitForSingleObject, 0 },
#else
{ "WaitForSingleObject", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
DWORD))aSyscall[60].pCurrent)
#if !SQLITE_OS_WINCE
{ "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 },
#else
{ "WaitForSingleObjectEx", (SYSCALL)0, 0 },
#endif
#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
BOOL))aSyscall[61].pCurrent)
#if !SQLITE_OS_WINCE
{ "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 },
#else
{ "SetFilePointerEx", (SYSCALL)0, 0 },
#endif
#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
PLARGE_INTEGER,DWORD))aSyscall[62].pCurrent)
#if SQLITE_OS_WINRT
{ "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
#else
{ "GetFileInformationByHandleEx", (SYSCALL)0, 0 },
#endif
#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent)
#if SQLITE_OS_WINRT
{ "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 },
#else
{ "MapViewOfFileFromApp", (SYSCALL)0, 0 },
#endif
#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
SIZE_T))aSyscall[64].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFile2", (SYSCALL)CreateFile2, 0 },
#else
{ "CreateFile2", (SYSCALL)0, 0 },
#endif
#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[65].pCurrent)
#if SQLITE_OS_WINRT
{ "LoadPackagedLibrary", (SYSCALL)LoadPackagedLibrary, 0 },
#else
{ "LoadPackagedLibrary", (SYSCALL)0, 0 },
#endif
#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
DWORD))aSyscall[66].pCurrent)
#if SQLITE_OS_WINRT
{ "GetTickCount64", (SYSCALL)GetTickCount64, 0 },
#else
{ "GetTickCount64", (SYSCALL)0, 0 },
#endif
#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[67].pCurrent)
#if SQLITE_OS_WINRT
{ "GetNativeSystemInfo", (SYSCALL)GetNativeSystemInfo, 0 },
#else
{ "GetNativeSystemInfo", (SYSCALL)0, 0 },
#endif
#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
LPSYSTEM_INFO))aSyscall[68].pCurrent)
#if defined(SQLITE_WIN32_HAS_ANSI)
{ "OutputDebugStringA", (SYSCALL)OutputDebugStringA, 0 },
#else
{ "OutputDebugStringA", (SYSCALL)0, 0 },
#endif
#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[69].pCurrent)
#if defined(SQLITE_WIN32_HAS_WIDE)
{ "OutputDebugStringW", (SYSCALL)OutputDebugStringW, 0 },
#else
{ "OutputDebugStringW", (SYSCALL)0, 0 },
#endif
#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[70].pCurrent)
{ "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 },
#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent)
#if SQLITE_OS_WINRT
{ "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
#else
{ "CreateFileMappingFromApp", (SYSCALL)0, 0 },
#endif
#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[72].pCurrent)
}; /* End of the overrideable system calls */
/*
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
** "win32" VFSes. Return SQLITE_OK opon successfully updating the
** system call pointer, or SQLITE_NOTFOUND if there is no configurable
|
| ︙ | ︙ | |||
32831 32832 32833 32834 32835 32836 32837 32838 32839 32840 32841 32842 32843 32844 32845 32846 32847 32848 32849 |
}
}
for(i++; i<ArraySize(aSyscall); i++){
if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
}
return 0;
}
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation: Win95, Win98, and WinME lack
** the LockFileEx() API. But we can still statically link against that
** API as long as we don't call it when running Win95/98/ME. A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 33109 33110 33111 33112 33113 33114 33115 33116 33117 33118 33119 33120 33121 33122 33123 33124 33125 33126 33127 33128 33129 33130 33131 33132 33133 33134 33135 33136 33137 33138 33139 33140 33141 33142 33143 33144 33145 33146 33147 33148 33149 33150 33151 33152 33153 33154 33155 33156 33157 33158 33159 33160 33161 33162 33163 33164 33165 33166 33167 33168 33169 33170 33171 33172 33173 33174 33175 33176 33177 33178 33179 33180 33181 33182 33183 33184 33185 33186 33187 33188 33189 33190 33191 33192 33193 |
}
}
for(i++; i<ArraySize(aSyscall); i++){
if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
}
return 0;
}
/*
** This function outputs the specified (ANSI) string to the Win32 debugger
** (if available).
*/
SQLITE_API void sqlite3_win32_write_debug(char *zBuf, int nBuf){
char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
#if defined(SQLITE_WIN32_HAS_ANSI)
if( nMin>0 ){
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
memcpy(zDbgBuf, zBuf, nMin);
osOutputDebugStringA(zDbgBuf);
}else{
osOutputDebugStringA(zBuf);
}
#elif defined(SQLITE_WIN32_HAS_WIDE)
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
if ( osMultiByteToWideChar(
osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf,
nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){
return;
}
osOutputDebugStringW((LPCWSTR)zDbgBuf);
#else
if( nMin>0 ){
memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
memcpy(zDbgBuf, zBuf, nMin);
fprintf(stderr, "%s", zDbgBuf);
}else{
fprintf(stderr, "%s", zBuf);
}
#endif
}
/*
** The following routine suspends the current thread for at least ms
** milliseconds. This is equivalent to the Win32 Sleep() interface.
*/
#if SQLITE_OS_WINRT
static HANDLE sleepObj = NULL;
#endif
SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
#if SQLITE_OS_WINRT
if ( sleepObj==NULL ){
sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
SYNCHRONIZE);
}
assert( sleepObj!=NULL );
osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
#else
osSleep(milliseconds);
#endif
}
/*
** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
** or WinCE. Return false (zero) for Win95, Win98, or WinME.
**
** Here is an interesting observation: Win95, Win98, and WinME lack
** the LockFileEx() API. But we can still statically link against that
** API as long as we don't call it when running Win95/98/ME. A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
#if SQLITE_OS_WINCE || SQLITE_OS_WINRT
# define isNT() (1)
#else
static int isNT(void){
if( sqlite3_os_type==0 ){
OSVERSIONINFOA sInfo;
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
osGetVersionExA(&sInfo);
|
| ︙ | ︙ | |||
32869 32870 32871 32872 32873 32874 32875 | HANDLE hHeap; void *p; winMemAssertMagic(); hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); | | | 33205 33206 33207 33208 33209 33210 33211 33212 33213 33214 33215 33216 33217 33218 33219 |
HANDLE hHeap;
void *p;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
assert( nBytes>=0 );
p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
if( !p ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
nBytes, osGetLastError(), (void*)hHeap);
|
| ︙ | ︙ | |||
32891 32892 32893 32894 32895 32896 32897 |
static void winMemFree(void *pPrior){
HANDLE hHeap;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
| | | | 33227 33228 33229 33230 33231 33232 33233 33234 33235 33236 33237 33238 33239 33240 33241 33242 33243 33244 33245 33246 33247 33248 33249 33250 33251 33252 33253 33254 33255 33256 33257 33258 33259 33260 33261 33262 |
static void winMemFree(void *pPrior){
HANDLE hHeap;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
pPrior, osGetLastError(), (void*)hHeap);
}
}
/*
** Change the size of an existing memory allocation
*/
static void *winMemRealloc(void *pPrior, int nBytes){
HANDLE hHeap;
void *p;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
#endif
assert( nBytes>=0 );
if( !pPrior ){
p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
}else{
p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
|
| ︙ | ︙ | |||
32940 32941 32942 32943 32944 32945 32946 | HANDLE hHeap; SIZE_T n; winMemAssertMagic(); hHeap = winMemGetHeap(); assert( hHeap!=0 ); assert( hHeap!=INVALID_HANDLE_VALUE ); | | | 33276 33277 33278 33279 33280 33281 33282 33283 33284 33285 33286 33287 33288 33289 33290 |
HANDLE hHeap;
SIZE_T n;
winMemAssertMagic();
hHeap = winMemGetHeap();
assert( hHeap!=0 );
assert( hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert ( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
if( !p ) return 0;
n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
if( n==(SIZE_T)-1 ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
p, osGetLastError(), (void*)hHeap);
|
| ︙ | ︙ | |||
32968 32969 32970 32971 32972 32973 32974 32975 32976 32977 32978 32979 32980 32981 32982 32983 32984 32985 32986 32987 32988 32989 |
** Initialize this module.
*/
static int winMemInit(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return SQLITE_ERROR;
assert( pWinMemData->magic==WINMEM_MAGIC );
if( !pWinMemData->hHeap ){
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE,
SQLITE_WIN32_HEAP_MAX_SIZE);
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
return SQLITE_NOMEM;
}
pWinMemData->bOwned = TRUE;
}
assert( pWinMemData->hHeap!=0 );
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
| > > > > > > > > > > > > > | | | 33304 33305 33306 33307 33308 33309 33310 33311 33312 33313 33314 33315 33316 33317 33318 33319 33320 33321 33322 33323 33324 33325 33326 33327 33328 33329 33330 33331 33332 33333 33334 33335 33336 33337 33338 33339 33340 33341 33342 33343 33344 33345 33346 33347 33348 33349 33350 33351 33352 33353 33354 33355 33356 33357 33358 33359 33360 33361 |
** Initialize this module.
*/
static int winMemInit(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return SQLITE_ERROR;
assert( pWinMemData->magic==WINMEM_MAGIC );
#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
if( !pWinMemData->hHeap ){
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE,
SQLITE_WIN32_HEAP_MAX_SIZE);
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to HeapCreate (%d), flags=%u, initSize=%u, maxSize=%u",
osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
return SQLITE_NOMEM;
}
pWinMemData->bOwned = TRUE;
assert( pWinMemData->bOwned );
}
#else
pWinMemData->hHeap = osGetProcessHeap();
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
"failed to GetProcessHeap (%d)", osGetLastError());
return SQLITE_NOMEM;
}
pWinMemData->bOwned = FALSE;
assert( !pWinMemData->bOwned );
#endif
assert( pWinMemData->hHeap!=0 );
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
return SQLITE_OK;
}
/*
** Deinitialize this module.
*/
static void winMemShutdown(void *pAppData){
winMemData *pWinMemData = (winMemData *)pAppData;
if( !pWinMemData ) return;
if( pWinMemData->hHeap ){
assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
#endif
if( pWinMemData->bOwned ){
if( !osHeapDestroy(pWinMemData->hHeap) ){
sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
osGetLastError(), (void*)pWinMemData->hHeap);
}
|
| ︙ | ︙ | |||
33198 33199 33200 33201 33202 33203 33204 33205 33206 33207 33208 33209 33210 33211 33212 33213 33214 33215 33216 33217 33218 33219 33220 33221 33222 |
** returns the number of TCHARs written to the output
** buffer, excluding the terminating null char.
*/
DWORD dwLen = 0;
char *zOut = 0;
if( isNT() ){
LPWSTR zTempWide = NULL;
dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
(LPWSTR) &zTempWide,
0,
0);
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
zOut = unicodeToUtf8(zTempWide);
sqlite3EndBenignMalloc();
/* free the system buffer allocated by FormatMessage */
osLocalFree(zTempWide);
}
| > > > > > > > > > > > > > > < < < < > | | < > | 33547 33548 33549 33550 33551 33552 33553 33554 33555 33556 33557 33558 33559 33560 33561 33562 33563 33564 33565 33566 33567 33568 33569 33570 33571 33572 33573 33574 33575 33576 33577 33578 33579 33580 33581 33582 33583 33584 33585 33586 33587 33588 33589 33590 33591 33592 33593 33594 33595 33596 33597 33598 33599 33600 33601 33602 33603 33604 33605 33606 33607 33608 33609 33610 33611 33612 33613 33614 33615 |
** returns the number of TCHARs written to the output
** buffer, excluding the terminating null char.
*/
DWORD dwLen = 0;
char *zOut = 0;
if( isNT() ){
#if SQLITE_OS_WINRT
WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */
dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
zTempWide,
MAX_PATH,
0);
#else
LPWSTR zTempWide = NULL;
dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
(LPWSTR) &zTempWide,
0,
0);
#endif
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
zOut = unicodeToUtf8(zTempWide);
sqlite3EndBenignMalloc();
#if !SQLITE_OS_WINRT
/* free the system buffer allocated by FormatMessage */
osLocalFree(zTempWide);
#endif
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zTemp = NULL;
dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
lastErrno,
0,
(LPSTR) &zTemp,
0,
0);
if( dwLen > 0 ){
/* allocate a buffer and convert to UTF8 */
sqlite3BeginBenignMalloc();
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
sqlite3EndBenignMalloc();
/* free the system buffer allocated by FormatMessage */
osLocalFree(zTemp);
}
}
#endif
if( 0 == dwLen ){
sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno);
}else{
/* copy a maximum of nBuf chars to output buffer */
sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
/* free the UTF8 buffer */
sqlite3_free(zOut);
|
| ︙ | ︙ | |||
33324 33325 33326 33327 33328 33329 33330 |
*pError = e;
}
return 0;
}
if( e==ERROR_ACCESS_DENIED ||
e==ERROR_LOCK_VIOLATION ||
e==ERROR_SHARING_VIOLATION ){
| | | 33684 33685 33686 33687 33688 33689 33690 33691 33692 33693 33694 33695 33696 33697 33698 |
*pError = e;
}
return 0;
}
if( e==ERROR_ACCESS_DENIED ||
e==ERROR_LOCK_VIOLATION ||
e==ERROR_SHARING_VIOLATION ){
sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry));
++*pnRetry;
return 1;
}
if( pError ){
*pError = e;
}
return 0;
|
| ︙ | ︙ | |||
33385 33386 33387 33388 33389 33390 33391 |
/*
** Acquire a lock on the handle h
*/
static void winceMutexAcquire(HANDLE h){
DWORD dwErr;
do {
| | | 33745 33746 33747 33748 33749 33750 33751 33752 33753 33754 33755 33756 33757 33758 33759 |
/*
** Acquire a lock on the handle h
*/
static void winceMutexAcquire(HANDLE h){
DWORD dwErr;
do {
dwErr = osWaitForSingleObject(h, INFINITE);
} while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
}
/*
** Release a lock acquired by winceMutexAcquire()
*/
#define winceMutexRelease(h) ReleaseMutex(h)
|
| ︙ | ︙ | |||
33516 33517 33518 33519 33520 33521 33522 | } } /* ** An implementation of the LockFile() API of Windows for CE */ static BOOL winceLockFile( | | | 33876 33877 33878 33879 33880 33881 33882 33883 33884 33885 33886 33887 33888 33889 33890 |
}
}
/*
** An implementation of the LockFile() API of Windows for CE
*/
static BOOL winceLockFile(
LPHANDLE phFile,
DWORD dwFileOffsetLow,
DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh
){
winFile *pFile = HANDLE_TO_WINFILE(phFile);
BOOL bReturn = FALSE;
|
| ︙ | ︙ | |||
33580 33581 33582 33583 33584 33585 33586 | return bReturn; } /* ** An implementation of the UnlockFile API of Windows for CE */ static BOOL winceUnlockFile( | | | 33940 33941 33942 33943 33944 33945 33946 33947 33948 33949 33950 33951 33952 33953 33954 |
return bReturn;
}
/*
** An implementation of the UnlockFile API of Windows for CE
*/
static BOOL winceUnlockFile(
LPHANDLE phFile,
DWORD dwFileOffsetLow,
DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow,
DWORD nNumberOfBytesToUnlockHigh
){
winFile *pFile = HANDLE_TO_WINFILE(phFile);
BOOL bReturn = FALSE;
|
| ︙ | ︙ | |||
33637 33638 33639 33640 33641 33642 33643 |
bReturn = TRUE;
}
}
winceMutexRelease(pFile->hMutex);
return bReturn;
}
| < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 33997 33998 33999 34000 34001 34002 34003 34004 34005 34006 34007 34008 34009 34010 34011 34012 34013 34014 34015 34016 34017 34018 34019 34020 34021 34022 34023 34024 34025 34026 34027 34028 34029 34030 34031 34032 34033 34034 34035 34036 34037 34038 34039 34040 34041 34042 34043 34044 34045 34046 34047 34048 34049 34050 34051 34052 34053 34054 34055 34056 34057 34058 34059 34060 34061 34062 34063 34064 34065 34066 34067 34068 34069 34070 34071 34072 34073 34074 34075 34076 34077 34078 34079 34080 34081 34082 34083 34084 34085 34086 34087 34088 34089 34090 34091 34092 34093 34094 34095 34096 34097 |
bReturn = TRUE;
}
}
winceMutexRelease(pFile->hMutex);
return bReturn;
}
/*
** End of the special code for wince
*****************************************************************************/
#endif /* SQLITE_OS_WINCE */
/*
** Lock a file region.
*/
static BOOL winLockFile(
LPHANDLE phFile,
DWORD flags,
DWORD offsetLow,
DWORD offsetHigh,
DWORD numBytesLow,
DWORD numBytesHigh
){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
** API LockFile.
*/
return winceLockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
if( isNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
ovlp.OffsetHigh = offsetHigh;
return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
}else{
return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
numBytesHigh);
}
#endif
}
/*
** Unlock a file region.
*/
static BOOL winUnlockFile(
LPHANDLE phFile,
DWORD offsetLow,
DWORD offsetHigh,
DWORD numBytesLow,
DWORD numBytesHigh
){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
** API UnlockFile.
*/
return winceUnlockFile(phFile, offsetLow, offsetHigh,
numBytesLow, numBytesHigh);
#else
if( isNT() ){
OVERLAPPED ovlp;
memset(&ovlp, 0, sizeof(OVERLAPPED));
ovlp.Offset = offsetLow;
ovlp.OffsetHigh = offsetHigh;
return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
}else{
return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
numBytesHigh);
}
#endif
}
/*****************************************************************************
** The next group of routines implement the I/O methods specified
** by the sqlite3_io_methods object.
******************************************************************************/
/*
** Some Microsoft compilers lack this definition.
*/
#ifndef INVALID_SET_FILE_POINTER
# define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
/*
** Move the current position of the file handle passed as the first
** argument to offset iOffset within the file. If successful, return 0.
** Otherwise, set pFile->lastErrno and return non-zero.
*/
static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){
#if !SQLITE_OS_WINRT
LONG upperBits; /* Most sig. 32 bits of new offset */
LONG lowerBits; /* Least sig. 32 bits of new offset */
DWORD dwRet; /* Value returned by SetFilePointer() */
DWORD lastErrno; /* Value returned by GetLastError() */
upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
lowerBits = (LONG)(iOffset & 0xffffffff);
|
| ︙ | ︙ | |||
33710 33711 33712 33713 33714 33715 33716 33717 33718 33719 33720 33721 33722 33723 |
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
"seekWinFile", pFile->zPath);
return 1;
}
return 0;
}
/*
** Close a file.
**
** It is reported that an attempt to close a handle might sometimes
** fail. This is a very unreasonable result, but Windows is notorious
| > > > > > > > > > > > > > > > > > > > > | 34110 34111 34112 34113 34114 34115 34116 34117 34118 34119 34120 34121 34122 34123 34124 34125 34126 34127 34128 34129 34130 34131 34132 34133 34134 34135 34136 34137 34138 34139 34140 34141 34142 34143 |
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
"seekWinFile", pFile->zPath);
return 1;
}
return 0;
#else
/*
** Same as above, except that this implementation works for WinRT.
*/
LARGE_INTEGER x; /* The new offset */
BOOL bRet; /* Value returned by SetFilePointerEx() */
x.QuadPart = iOffset;
bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
if(!bRet){
pFile->lastErrno = osGetLastError();
winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
"seekWinFile", pFile->zPath);
return 1;
}
return 0;
#endif
}
/*
** Close a file.
**
** It is reported that an attempt to close a handle might sometimes
** fail. This is a very unreasonable result, but Windows is notorious
|
| ︙ | ︙ | |||
33733 33734 33735 33736 33737 33738 33739 |
assert( id!=0 );
assert( pFile->pShm==0 );
OSTRACE(("CLOSE %d\n", pFile->h));
do{
rc = osCloseHandle(pFile->h);
/* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
| | | | 34153 34154 34155 34156 34157 34158 34159 34160 34161 34162 34163 34164 34165 34166 34167 34168 34169 34170 34171 34172 34173 34174 34175 34176 34177 34178 |
assert( id!=0 );
assert( pFile->pShm==0 );
OSTRACE(("CLOSE %d\n", pFile->h));
do{
rc = osCloseHandle(pFile->h);
/* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
}while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
#if SQLITE_OS_WINCE
#define WINCE_DELETION_ATTEMPTS 3
winceDestroyLock(pFile);
if( pFile->zDeleteOnClose ){
int cnt = 0;
while(
osDeleteFileW(pFile->zDeleteOnClose)==0
&& osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
&& cnt++ < WINCE_DELETION_ATTEMPTS
){
sqlite3_win32_sleep(100); /* Wait a little before trying again */
}
sqlite3_free(pFile->zDeleteOnClose);
}
#endif
OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed"));
if( rc ){
pFile->h = NULL;
|
| ︙ | ︙ | |||
33999 34000 34001 34002 34003 34004 34005 |
#endif
}
/*
** Determine the current size of a file in bytes
*/
static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
| < < < > > > > > > > > > > > > > > > > > > > | > | | < | | | < > > | > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < | > > > | > > > > > > | | > | < > | < < > | | | < > | 34419 34420 34421 34422 34423 34424 34425 34426 34427 34428 34429 34430 34431 34432 34433 34434 34435 34436 34437 34438 34439 34440 34441 34442 34443 34444 34445 34446 34447 34448 34449 34450 34451 34452 34453 34454 34455 34456 34457 34458 34459 34460 34461 34462 34463 34464 34465 34466 34467 34468 34469 34470 34471 34472 34473 34474 34475 34476 34477 34478 34479 34480 34481 34482 34483 34484 34485 34486 34487 34488 34489 34490 34491 34492 34493 34494 34495 34496 34497 34498 34499 34500 34501 34502 34503 34504 34505 34506 34507 34508 34509 34510 34511 34512 34513 34514 34515 34516 34517 34518 34519 34520 34521 34522 34523 34524 34525 34526 34527 34528 34529 34530 34531 34532 34533 34534 34535 34536 34537 34538 34539 34540 34541 34542 34543 34544 34545 34546 34547 34548 |
#endif
}
/*
** Determine the current size of a file in bytes
*/
static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
winFile *pFile = (winFile*)id;
int rc = SQLITE_OK;
assert( id!=0 );
SimulateIOError(return SQLITE_IOERR_FSTAT);
#if SQLITE_OS_WINRT
{
FILE_STANDARD_INFO info;
if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo,
&info, sizeof(info)) ){
*pSize = info.EndOfFile.QuadPart;
}else{
pFile->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
"winFileSize", pFile->zPath);
}
}
#else
{
DWORD upperBits;
DWORD lowerBits;
DWORD lastErrno;
lowerBits = osGetFileSize(pFile->h, &upperBits);
*pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
if( (lowerBits == INVALID_FILE_SIZE)
&& ((lastErrno = osGetLastError())!=NO_ERROR) ){
pFile->lastErrno = lastErrno;
rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
"winFileSize", pFile->zPath);
}
}
#endif
return rc;
}
/*
** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
*/
#ifndef LOCKFILE_FAIL_IMMEDIATELY
# define LOCKFILE_FAIL_IMMEDIATELY 1
#endif
#ifndef LOCKFILE_EXCLUSIVE_LOCK
# define LOCKFILE_EXCLUSIVE_LOCK 2
#endif
/*
** Historically, SQLite has used both the LockFile and LockFileEx functions.
** When the LockFile function was used, it was always expected to fail
** immediately if the lock could not be obtained. Also, it always expected to
** obtain an exclusive lock. These flags are used with the LockFileEx function
** and reflect those expectations; therefore, they should not be changed.
*/
#ifndef SQLITE_LOCKFILE_FLAGS
# define SQLITE_LOCKFILE_FLAGS (LOCKFILE_FAIL_IMMEDIATELY | \
LOCKFILE_EXCLUSIVE_LOCK)
#endif
/*
** Currently, SQLite never calls the LockFileEx function without wanting the
** call to fail immediately if the lock cannot be obtained.
*/
#ifndef SQLITE_LOCKFILEEX_FLAGS
# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
#endif
/*
** Acquire a reader lock.
** Different API routines are called depending on whether or not this
** is Win9x or WinNT.
*/
static int getReadLock(winFile *pFile){
int res;
if( isNT() ){
#if SQLITE_OS_WINCE
/*
** NOTE: Windows CE is handled differently here due its lack of the Win32
** API LockFileEx.
*/
res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
#else
res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
SHARED_SIZE, 0);
#endif
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
int lk;
sqlite3_randomness(sizeof(lk), &lk);
pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
}
#endif
if( res == 0 ){
pFile->lastErrno = osGetLastError();
/* No need to log a failure to lock */
}
return res;
}
/*
** Undo a readlock
*/
static int unlockReadLock(winFile *pFile){
int res;
DWORD lastErrno;
if( isNT() ){
res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
}
#endif
if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
pFile->lastErrno = lastErrno;
winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
"unlockReadLock", pFile->zPath);
}
return res;
}
|
| ︙ | ︙ | |||
34141 34142 34143 34144 34145 34146 34147 |
*/
newLocktype = pFile->locktype;
if( (pFile->locktype==NO_LOCK)
|| ( (locktype==EXCLUSIVE_LOCK)
&& (pFile->locktype==RESERVED_LOCK))
){
int cnt = 3;
| > | | | 34605 34606 34607 34608 34609 34610 34611 34612 34613 34614 34615 34616 34617 34618 34619 34620 34621 34622 34623 34624 34625 34626 34627 34628 |
*/
newLocktype = pFile->locktype;
if( (pFile->locktype==NO_LOCK)
|| ( (locktype==EXCLUSIVE_LOCK)
&& (pFile->locktype==RESERVED_LOCK))
){
int cnt = 3;
while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
PENDING_BYTE, 0, 1, 0))==0 ){
/* Try 3 times to get the pending lock. This is needed to work
** around problems caused by indexing and/or anti-virus software on
** Windows systems.
** If you are using this code as a model for alternative VFSes, do not
** copy this retry logic. It is a hack intended for Windows only.
*/
OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt));
if( cnt ) sqlite3_win32_sleep(1);
}
gotPendingLock = res;
if( !res ){
lastErrno = osGetLastError();
}
}
|
| ︙ | ︙ | |||
34173 34174 34175 34176 34177 34178 34179 |
}
}
/* Acquire a RESERVED lock
*/
if( locktype==RESERVED_LOCK && res ){
assert( pFile->locktype==SHARED_LOCK );
| | > | | | 34638 34639 34640 34641 34642 34643 34644 34645 34646 34647 34648 34649 34650 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 |
}
}
/* Acquire a RESERVED lock
*/
if( locktype==RESERVED_LOCK && res ){
assert( pFile->locktype==SHARED_LOCK );
res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
if( res ){
newLocktype = RESERVED_LOCK;
}else{
lastErrno = osGetLastError();
}
}
/* Acquire a PENDING lock
*/
if( locktype==EXCLUSIVE_LOCK && res ){
newLocktype = PENDING_LOCK;
gotPendingLock = 0;
}
/* Acquire an EXCLUSIVE lock
*/
if( locktype==EXCLUSIVE_LOCK && res ){
assert( pFile->locktype>=SHARED_LOCK );
res = unlockReadLock(pFile);
OSTRACE(("unreadlock = %d\n", res));
res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
SHARED_SIZE, 0);
if( res ){
newLocktype = EXCLUSIVE_LOCK;
}else{
lastErrno = osGetLastError();
OSTRACE(("error-code = %d\n", lastErrno));
getReadLock(pFile);
}
}
/* If we are holding a PENDING lock that ought to be released, then
** release it now.
*/
if( gotPendingLock && locktype==SHARED_LOCK ){
winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
}
/* Update the state of the lock has held in the file descriptor then
** return the appropriate result code.
*/
if( res ){
rc = SQLITE_OK;
|
| ︙ | ︙ | |||
34242 34243 34244 34245 34246 34247 34248 |
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( id!=0 );
if( pFile->locktype>=RESERVED_LOCK ){
rc = 1;
OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
}else{
| | | | 34708 34709 34710 34711 34712 34713 34714 34715 34716 34717 34718 34719 34720 34721 34722 34723 34724 |
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
assert( id!=0 );
if( pFile->locktype>=RESERVED_LOCK ){
rc = 1;
OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
}else{
rc = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
if( rc ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
rc = !rc;
OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc));
}
*pResOut = rc;
return SQLITE_OK;
}
|
| ︙ | ︙ | |||
34274 34275 34276 34277 34278 34279 34280 |
int rc = SQLITE_OK;
assert( pFile!=0 );
assert( locktype<=SHARED_LOCK );
OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
pFile->locktype, pFile->sharedLockByte));
type = pFile->locktype;
if( type>=EXCLUSIVE_LOCK ){
| | | | | 34740 34741 34742 34743 34744 34745 34746 34747 34748 34749 34750 34751 34752 34753 34754 34755 34756 34757 34758 34759 34760 34761 34762 34763 34764 34765 34766 34767 34768 34769 |
int rc = SQLITE_OK;
assert( pFile!=0 );
assert( locktype<=SHARED_LOCK );
OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype,
pFile->locktype, pFile->sharedLockByte));
type = pFile->locktype;
if( type>=EXCLUSIVE_LOCK ){
winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
if( locktype==SHARED_LOCK && !getReadLock(pFile) ){
/* This should never happen. We should always be able to
** reacquire the read lock */
rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
"winUnlock", pFile->zPath);
}
}
if( type>=RESERVED_LOCK ){
winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
}
if( locktype==NO_LOCK && type>=SHARED_LOCK ){
unlockReadLock(pFile);
}
if( type>=PENDING_LOCK ){
winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
}
pFile->locktype = (u8)locktype;
return rc;
}
/*
** If *pArg is inititially negative then this is a query. Set *pArg to
|
| ︙ | ︙ | |||
34527 34528 34529 34530 34531 34532 34533 |
#define _SHM_WRLCK 3
static int winShmSystemLock(
winShmNode *pFile, /* Apply locks to this open shared-memory segment */
int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
int ofst, /* Offset to first byte to be locked/unlocked */
int nByte /* Number of bytes to lock or unlock */
){
| < < < < < < < < < | > > > | | 34993 34994 34995 34996 34997 34998 34999 35000 35001 35002 35003 35004 35005 35006 35007 35008 35009 35010 35011 35012 35013 35014 35015 35016 35017 35018 35019 |
#define _SHM_WRLCK 3
static int winShmSystemLock(
winShmNode *pFile, /* Apply locks to this open shared-memory segment */
int lockType, /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
int ofst, /* Offset to first byte to be locked/unlocked */
int nByte /* Number of bytes to lock or unlock */
){
int rc = 0; /* Result code form Lock/UnlockFileEx() */
/* Access to the winShmNode object is serialized by the caller */
assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
/* Release/Acquire the system-level lock */
if( lockType==_SHM_UNLCK ){
rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
}else{
/* Initialize the locking parameters */
DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
}
if( rc!= 0 ){
rc = SQLITE_OK;
}else{
pFile->lastErrno = osGetLastError();
rc = SQLITE_BUSY;
|
| ︙ | ︙ | |||
34983 34984 34985 34986 34987 34988 34989 |
}
pShmNode->aRegion = apNew;
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
| > > > > > | > > > > > > > | 35443 35444 35445 35446 35447 35448 35449 35450 35451 35452 35453 35454 35455 35456 35457 35458 35459 35460 35461 35462 35463 35464 35465 35466 35467 35468 35469 35470 35471 35472 35473 35474 35475 35476 35477 35478 35479 35480 |
}
pShmNode->aRegion = apNew;
while( pShmNode->nRegion<=iRegion ){
HANDLE hMap; /* file-mapping handle */
void *pMap = 0; /* Mapped memory region */
#if SQLITE_OS_WINRT
hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
NULL, PAGE_READWRITE, nByte, NULL
);
#else
hMap = osCreateFileMappingW(pShmNode->hFile.h,
NULL, PAGE_READWRITE, 0, nByte, NULL
);
#endif
OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n",
(int)osGetCurrentProcessId(), pShmNode->nRegion, nByte,
hMap ? "ok" : "failed"));
if( hMap ){
int iOffset = pShmNode->nRegion*szRegion;
int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
#if SQLITE_OS_WINRT
pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
iOffset - iOffsetShift, szRegion + iOffsetShift
);
#else
pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
0, iOffset - iOffsetShift, szRegion + iOffsetShift
);
#endif
OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n",
(int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
szRegion, pMap ? "ok" : "failed"));
}
if( !pMap ){
pShmNode->lastErrno = osGetLastError();
rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
|
| ︙ | ︙ | |||
35080 35081 35082 35083 35084 35085 35086 |
** is obtained from malloc and must be freed by the calling
** function.
*/
static void *convertUtf8Filename(const char *zFilename){
void *zConverted = 0;
if( isNT() ){
zConverted = utf8ToUnicode(zFilename);
| < < > | | < > > > > > > | < < < < > | | < > > > > | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 35552 35553 35554 35555 35556 35557 35558 35559 35560 35561 35562 35563 35564 35565 35566 35567 35568 35569 35570 35571 35572 35573 35574 35575 35576 35577 35578 35579 35580 35581 35582 35583 35584 35585 35586 35587 35588 35589 35590 35591 35592 35593 35594 35595 35596 35597 35598 35599 35600 35601 35602 35603 35604 35605 35606 35607 35608 35609 35610 35611 35612 35613 35614 35615 35616 35617 35618 35619 35620 35621 35622 35623 35624 35625 35626 35627 35628 35629 35630 35631 35632 35633 35634 35635 35636 35637 35638 35639 35640 35641 35642 35643 35644 35645 35646 35647 35648 35649 35650 35651 35652 35653 35654 35655 35656 35657 35658 35659 35660 35661 35662 35663 35664 35665 35666 35667 35668 35669 35670 35671 35672 35673 35674 35675 35676 35677 35678 35679 35680 35681 35682 35683 |
** is obtained from malloc and must be freed by the calling
** function.
*/
static void *convertUtf8Filename(const char *zFilename){
void *zConverted = 0;
if( isNT() ){
zConverted = utf8ToUnicode(zFilename);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
}
#endif
/* caller will handle out of memory */
return zConverted;
}
/*
** Create a temporary file name in zBuf. zBuf must be big enough to
** hold at pVfs->mxPathname characters.
*/
static int getTempname(int nBuf, char *zBuf){
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
int nTempPath;
char zTempPath[MAX_PATH+2];
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing.
*/
SimulateIOError( return SQLITE_IOERR );
memset(zTempPath, 0, MAX_PATH+2);
if( sqlite3_temp_directory ){
sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
}
#if !SQLITE_OS_WINRT
else if( isNT() ){
char *zMulti;
WCHAR zWidePath[MAX_PATH];
osGetTempPathW(MAX_PATH-30, zWidePath);
zMulti = unicodeToUtf8(zWidePath);
if( zMulti ){
sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
sqlite3_free(zMulti);
}else{
return SQLITE_IOERR_NOMEM;
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zUtf8;
char zMbcsPath[MAX_PATH];
osGetTempPathA(MAX_PATH-30, zMbcsPath);
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
if( zUtf8 ){
sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
sqlite3_free(zUtf8);
}else{
return SQLITE_IOERR_NOMEM;
}
}
#endif
#endif
/* Check that the output buffer is large enough for the temporary file
** name. If it is not, return SQLITE_ERROR.
*/
nTempPath = sqlite3Strlen30(zTempPath);
if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){
return SQLITE_ERROR;
}
for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){}
zTempPath[i] = 0;
sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ?
"%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX,
zTempPath);
j = sqlite3Strlen30(zBuf);
sqlite3_randomness(15, &zBuf[j]);
for(i=0; i<15; i++, j++){
zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
}
zBuf[j] = 0;
zBuf[j+1] = 0;
OSTRACE(("TEMP FILENAME: %s\n", zBuf));
return SQLITE_OK;
}
/*
** Return TRUE if the named file is really a directory. Return false if
** it is something other than a directory, or if there is any kind of memory
** allocation failure.
*/
static int winIsDir(const void *zConverted){
DWORD attr;
int rc = 0;
DWORD lastErrno;
if( isNT() ){
int cnt = 0;
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
GetFileExInfoStandard,
&sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
if( !rc ){
return 0; /* Invalid name? */
}
attr = sAttrData.dwFileAttributes;
#if SQLITE_OS_WINCE==0
}else{
attr = osGetFileAttributesA((char*)zConverted);
#endif
}
return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
}
/*
** Open a file.
*/
static int winOpen(
sqlite3_vfs *pVfs, /* Not used */
const char *zName, /* Name of the file (UTF-8) */
|
| ︙ | ︙ | |||
35270 35271 35272 35273 35274 35275 35276 35277 35278 35279 35280 35281 35282 35283 |
zUtf8Name[strlen(zUtf8Name)+1]==0 );
/* Convert the filename to the system encoding. */
zConverted = convertUtf8Filename(zUtf8Name);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( isReadWrite ){
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
}else{
dwDesiredAccess = GENERIC_READ;
}
| > > > > > | 35776 35777 35778 35779 35780 35781 35782 35783 35784 35785 35786 35787 35788 35789 35790 35791 35792 35793 35794 |
zUtf8Name[strlen(zUtf8Name)+1]==0 );
/* Convert the filename to the system encoding. */
zConverted = convertUtf8Filename(zUtf8Name);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( winIsDir(zConverted) ){
sqlite3_free(zConverted);
return SQLITE_CANTOPEN_ISDIR;
}
if( isReadWrite ){
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
}else{
dwDesiredAccess = GENERIC_READ;
}
|
| ︙ | ︙ | |||
35314 35315 35316 35317 35318 35319 35320 35321 35322 35323 35324 35325 35326 |
/* Reports from the internet are that performance is always
** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
#if SQLITE_OS_WINCE
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif
if( isNT() ){
while( (h = osCreateFileW((LPCWSTR)zConverted,
dwDesiredAccess,
dwShareMode, NULL,
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
| > > > > > > > > > > > > > > > > > > | < < < | > > > | | | < > | | > | 35825 35826 35827 35828 35829 35830 35831 35832 35833 35834 35835 35836 35837 35838 35839 35840 35841 35842 35843 35844 35845 35846 35847 35848 35849 35850 35851 35852 35853 35854 35855 35856 35857 35858 35859 35860 35861 35862 35863 35864 35865 35866 35867 35868 35869 35870 35871 35872 35873 35874 35875 35876 35877 35878 35879 35880 |
/* Reports from the internet are that performance is always
** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */
#if SQLITE_OS_WINCE
dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
#endif
if( isNT() ){
#if SQLITE_OS_WINRT
CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
extendedParameters.dwFileAttributes =
dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extendedParameters.lpSecurityAttributes = NULL;
extendedParameters.hTemplateFile = NULL;
while( (h = osCreateFile2((LPCWSTR)zConverted,
dwDesiredAccess,
dwShareMode,
dwCreationDisposition,
&extendedParameters))==INVALID_HANDLE_VALUE &&
retryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#else
while( (h = osCreateFileW((LPCWSTR)zConverted,
dwDesiredAccess,
dwShareMode, NULL,
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
retryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
#endif
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
while( (h = osCreateFileA((LPCSTR)zConverted,
dwDesiredAccess,
dwShareMode, NULL,
dwCreationDisposition,
dwFlagsAndAttributes,
NULL))==INVALID_HANDLE_VALUE &&
retryIoerr(&cnt, &lastErrno) ){
/* Noop */
}
}
#endif
logIoerr(cnt);
OSTRACE(("OPEN %d %s 0x%lx %s\n",
h, zName, dwDesiredAccess,
h==INVALID_HANDLE_VALUE ? "failed" : "ok"));
if( h==INVALID_HANDLE_VALUE ){
|
| ︙ | ︙ | |||
35413 35414 35415 35416 35417 35418 35419 35420 35421 35422 35423 35424 35425 35426 35427 35428 35429 35430 |
static int winDelete(
sqlite3_vfs *pVfs, /* Not used on win32 */
const char *zFilename, /* Name of file to delete */
int syncDir /* Not used on win32 */
){
int cnt = 0;
int rc;
DWORD lastErrno;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
SimulateIOError(return SQLITE_IOERR_DELETE);
zConverted = convertUtf8Filename(zFilename);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( isNT() ){
| > > > > > > > > > | > > > | > > > > > > > > > > > > > | | < < < < > > > > | | | | > > > > > > > > > > > > | | | | > > > | 35943 35944 35945 35946 35947 35948 35949 35950 35951 35952 35953 35954 35955 35956 35957 35958 35959 35960 35961 35962 35963 35964 35965 35966 35967 35968 35969 35970 35971 35972 35973 35974 35975 35976 35977 35978 35979 35980 35981 35982 35983 35984 35985 35986 35987 35988 35989 35990 35991 35992 35993 35994 35995 35996 35997 35998 35999 36000 36001 36002 36003 36004 36005 36006 36007 36008 36009 36010 36011 36012 36013 36014 36015 36016 36017 36018 36019 36020 36021 36022 36023 |
static int winDelete(
sqlite3_vfs *pVfs, /* Not used on win32 */
const char *zFilename, /* Name of file to delete */
int syncDir /* Not used on win32 */
){
int cnt = 0;
int rc;
DWORD attr;
DWORD lastErrno;
void *zConverted;
UNUSED_PARAMETER(pVfs);
UNUSED_PARAMETER(syncDir);
SimulateIOError(return SQLITE_IOERR_DELETE);
zConverted = convertUtf8Filename(zFilename);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( isNT() ){
do {
#if SQLITE_OS_WINRT
WIN32_FILE_ATTRIBUTE_DATA sAttrData;
memset(&sAttrData, 0, sizeof(sAttrData));
if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
&sAttrData) ){
attr = sAttrData.dwFileAttributes;
}else{
rc = SQLITE_OK; /* Already gone? */
break;
}
#else
attr = osGetFileAttributesW(zConverted);
#endif
if ( attr==INVALID_FILE_ATTRIBUTES ){
rc = SQLITE_OK; /* Already gone? */
break;
}
if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
rc = SQLITE_ERROR; /* Files only. */
break;
}
if ( osDeleteFileW(zConverted) ){
rc = SQLITE_OK; /* Deleted OK. */
break;
}
if ( !retryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
} while(1);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
do {
attr = osGetFileAttributesA(zConverted);
if ( attr==INVALID_FILE_ATTRIBUTES ){
rc = SQLITE_OK; /* Already gone? */
break;
}
if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
rc = SQLITE_ERROR; /* Files only. */
break;
}
if ( osDeleteFileA(zConverted) ){
rc = SQLITE_OK; /* Deleted OK. */
break;
}
if ( !retryIoerr(&cnt, &lastErrno) ){
rc = SQLITE_ERROR; /* No more retries. */
break;
}
} while(1);
}
#endif
if( rc ){
rc = winLogError(SQLITE_IOERR_DELETE, lastErrno,
"winDelete", zFilename);
}else{
logIoerr(cnt);
}
sqlite3_free(zConverted);
|
| ︙ | ︙ | |||
35499 35500 35501 35502 35503 35504 35505 |
winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
sqlite3_free(zConverted);
return SQLITE_IOERR_ACCESS;
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
}
| < < < < > | | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | < > > > > > > > > > > > | > | > > > > > > > | > > > < < < < > | | < > | | 36069 36070 36071 36072 36073 36074 36075 36076 36077 36078 36079 36080 36081 36082 36083 36084 36085 36086 36087 36088 36089 36090 36091 36092 36093 36094 36095 36096 36097 36098 36099 36100 36101 36102 36103 36104 36105 36106 36107 36108 36109 36110 36111 36112 36113 36114 36115 36116 36117 36118 36119 36120 36121 36122 36123 36124 36125 36126 36127 36128 36129 36130 36131 36132 36133 36134 36135 36136 36137 36138 36139 36140 36141 36142 36143 36144 36145 36146 36147 36148 36149 36150 36151 36152 36153 36154 36155 36156 36157 36158 36159 36160 36161 36162 36163 36164 36165 36166 36167 36168 36169 36170 36171 36172 36173 36174 36175 36176 36177 36178 36179 36180 36181 36182 36183 36184 36185 36186 36187 36188 36189 36190 36191 36192 36193 36194 36195 36196 36197 36198 36199 36200 36201 36202 36203 36204 36205 36206 36207 36208 36209 36210 36211 36212 36213 36214 36215 36216 36217 36218 36219 36220 36221 36222 36223 36224 36225 36226 36227 36228 36229 36230 36231 36232 36233 36234 36235 36236 36237 36238 36239 36240 36241 36242 36243 36244 36245 36246 36247 36248 36249 36250 36251 36252 36253 36254 36255 36256 36257 36258 36259 36260 36261 36262 36263 36264 36265 |
winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename);
sqlite3_free(zConverted);
return SQLITE_IOERR_ACCESS;
}else{
attr = INVALID_FILE_ATTRIBUTES;
}
}
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
attr = osGetFileAttributesA((char*)zConverted);
}
#endif
sqlite3_free(zConverted);
switch( flags ){
case SQLITE_ACCESS_READ:
case SQLITE_ACCESS_EXISTS:
rc = attr!=INVALID_FILE_ATTRIBUTES;
break;
case SQLITE_ACCESS_READWRITE:
rc = attr!=INVALID_FILE_ATTRIBUTES &&
(attr & FILE_ATTRIBUTE_READONLY)==0;
break;
default:
assert(!"Invalid flags argument");
}
*pResOut = rc;
return SQLITE_OK;
}
/*
** Returns non-zero if the specified path name should be used verbatim. If
** non-zero is returned from this function, the calling function must simply
** use the provided path name verbatim -OR- resolve it into a full path name
** using the GetFullPathName Win32 API function (if available).
*/
static BOOL winIsVerbatimPathname(
const char *zPathname
){
/*
** If the path name starts with a forward slash or a backslash, it is either
** a legal UNC name, a volume relative path, or an absolute path name in the
** "Unix" format on Windows. There is no easy way to differentiate between
** the final two cases; therefore, we return the safer return value of TRUE
** so that callers of this function will simply use it verbatim.
*/
if ( zPathname[0]=='/' || zPathname[0]=='\\' ){
return TRUE;
}
/*
** If the path name starts with a letter and a colon it is either a volume
** relative path or an absolute path. Callers of this function must not
** attempt to treat it as a relative path name (i.e. they should simply use
** it verbatim).
*/
if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){
return TRUE;
}
/*
** If we get to this point, the path name should almost certainly be a purely
** relative one (i.e. not a UNC name, not absolute, and not volume relative).
*/
return FALSE;
}
/*
** Turn a relative pathname into a full pathname. Write the full
** pathname into zOut[]. zOut[] will be at least pVfs->mxPathname
** bytes in size.
*/
static int winFullPathname(
sqlite3_vfs *pVfs, /* Pointer to vfs object */
const char *zRelative, /* Possibly relative input path */
int nFull, /* Size of output buffer in bytes */
char *zFull /* Output buffer */
){
#if defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
UNUSED_PARAMETER(nFull);
assert( pVfs->mxPathname>=MAX_PATH );
assert( nFull>=pVfs->mxPathname );
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a slash.
*/
char zOut[MAX_PATH+1];
memset(zOut, 0, MAX_PATH+1);
cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
sqlite3_data_directory, zOut);
}else{
/*
** NOTE: The Cygwin docs state that the maximum length needed
** for the buffer passed to cygwin_conv_to_full_win32_path
** is MAX_PATH.
*/
cygwin_conv_to_full_win32_path(zRelative, zFull);
}
return SQLITE_OK;
#endif
#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
SimulateIOError( return SQLITE_ERROR );
/* WinCE has no concept of a relative pathname, or so I am told. */
/* WinRT has no way to convert a relative path to an absolute one. */
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
sqlite3_data_directory, zRelative);
}else{
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
}
return SQLITE_OK;
#endif
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
int nByte;
void *zConverted;
char *zOut;
/* If this path name begins with "/X:", where "X" is any alphabetic
** character, discard the initial "/" from the pathname.
*/
if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){
zRelative++;
}
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing. This function could fail if, for example, the
** current working directory has been unlinked.
*/
SimulateIOError( return SQLITE_ERROR );
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
sqlite3_data_directory, zRelative);
return SQLITE_OK;
}
zConverted = convertUtf8Filename(zRelative);
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( isNT() ){
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0) + 3;
zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM;
}
osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
sqlite3_free(zConverted);
zOut = unicodeToUtf8(zTemp);
sqlite3_free(zTemp);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zTemp;
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0) + 3;
zTemp = sqlite3_malloc( nByte*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM;
}
osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
sqlite3_free(zConverted);
zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
sqlite3_free(zTemp);
}
#endif
if( zOut ){
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut);
sqlite3_free(zOut);
return SQLITE_OK;
}else{
return SQLITE_IOERR_NOMEM;
}
#endif
}
|
| ︙ | ︙ | |||
35634 35635 35636 35637 35638 35639 35640 35641 |
HANDLE h;
void *zConverted = convertUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
if( zConverted==0 ){
return 0;
}
if( isNT() ){
h = osLoadLibraryW((LPCWSTR)zConverted);
| > > > < < < < > > | | < > | 36277 36278 36279 36280 36281 36282 36283 36284 36285 36286 36287 36288 36289 36290 36291 36292 36293 36294 36295 36296 36297 36298 36299 36300 36301 |
HANDLE h;
void *zConverted = convertUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
if( zConverted==0 ){
return 0;
}
if( isNT() ){
#if SQLITE_OS_WINRT
h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
#else
h = osLoadLibraryW((LPCWSTR)zConverted);
#endif
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
h = osLoadLibraryA((char*)zConverted);
}
#endif
sqlite3_free(zConverted);
return (void*)h;
}
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
UNUSED_PARAMETER(pVfs);
getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
|
| ︙ | ︙ | |||
35688 35689 35690 35691 35692 35693 35694 35695 35696 35697 35698 35699 35700 35701 35702 35703 35704 35705 35706 35707 35708 35709 35710 35711 35712 35713 35714 |
n += sizeof(x);
}
if( sizeof(DWORD)<=nBuf-n ){
DWORD pid = osGetCurrentProcessId();
memcpy(&zBuf[n], &pid, sizeof(pid));
n += sizeof(pid);
}
if( sizeof(DWORD)<=nBuf-n ){
DWORD cnt = osGetTickCount();
memcpy(&zBuf[n], &cnt, sizeof(cnt));
n += sizeof(cnt);
}
if( sizeof(LARGE_INTEGER)<=nBuf-n ){
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
#endif
return n;
}
/*
** Sleep for a little while. Return the amount of time slept.
*/
static int winSleep(sqlite3_vfs *pVfs, int microsec){
| > > > > > > > > | | 36332 36333 36334 36335 36336 36337 36338 36339 36340 36341 36342 36343 36344 36345 36346 36347 36348 36349 36350 36351 36352 36353 36354 36355 36356 36357 36358 36359 36360 36361 36362 36363 36364 36365 36366 36367 36368 36369 36370 36371 36372 36373 36374 |
n += sizeof(x);
}
if( sizeof(DWORD)<=nBuf-n ){
DWORD pid = osGetCurrentProcessId();
memcpy(&zBuf[n], &pid, sizeof(pid));
n += sizeof(pid);
}
#if SQLITE_OS_WINRT
if( sizeof(ULONGLONG)<=nBuf-n ){
ULONGLONG cnt = osGetTickCount64();
memcpy(&zBuf[n], &cnt, sizeof(cnt));
n += sizeof(cnt);
}
#else
if( sizeof(DWORD)<=nBuf-n ){
DWORD cnt = osGetTickCount();
memcpy(&zBuf[n], &cnt, sizeof(cnt));
n += sizeof(cnt);
}
#endif
if( sizeof(LARGE_INTEGER)<=nBuf-n ){
LARGE_INTEGER i;
osQueryPerformanceCounter(&i);
memcpy(&zBuf[n], &i, sizeof(i));
n += sizeof(i);
}
#endif
return n;
}
/*
** Sleep for a little while. Return the amount of time slept.
*/
static int winSleep(sqlite3_vfs *pVfs, int microsec){
sqlite3_win32_sleep((microsec+999)/1000);
UNUSED_PARAMETER(pVfs);
return ((microsec+999)/1000)*1000;
}
/*
** The following variable, if set to a non-zero value, is interpreted as
** the number of seconds since 1970 and is used to set the result of
|
| ︙ | ︙ | |||
35850 35851 35852 35853 35854 35855 35856 |
winSetSystemCall, /* xSetSystemCall */
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
| | > > > > > > > > > > | 36502 36503 36504 36505 36506 36507 36508 36509 36510 36511 36512 36513 36514 36515 36516 36517 36518 36519 36520 36521 36522 36523 36524 36525 36526 36527 36528 36529 36530 36531 36532 36533 36534 36535 36536 36537 36538 36539 |
winSetSystemCall, /* xSetSystemCall */
winGetSystemCall, /* xGetSystemCall */
winNextSystemCall, /* xNextSystemCall */
};
/* Double-check that the aSyscall[] array has been constructed
** correctly. See ticket [bb3a86e890c8e96ab] */
assert( ArraySize(aSyscall)==73 );
#ifndef SQLITE_OMIT_WAL
/* get memory map allocation granularity */
memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
#if SQLITE_OS_WINRT
osGetNativeSystemInfo(&winSysInfo);
#else
osGetSystemInfo(&winSysInfo);
#endif
assert(winSysInfo.dwAllocationGranularity > 0);
#endif
sqlite3_vfs_register(&winVfs, 1);
return SQLITE_OK;
}
SQLITE_API int sqlite3_os_end(void){
#if SQLITE_OS_WINRT
if( sleepObj != NULL ){
osCloseHandle(sleepObj);
sleepObj = NULL;
}
#endif
return SQLITE_OK;
}
#endif /* SQLITE_OS_WIN */
/************** End of os_win.c **********************************************/
/************** Begin file bitvec.c ******************************************/
|
| ︙ | ︙ | |||
37115 37116 37117 37118 37119 37120 37121 37122 37123 37124 37125 37126 37127 37128 37129 37130 37131 37132 37133 37134 |
sqlite3_mutex_leave(pcache1.mutex);
}
if( p==0 ){
/* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get
** it from sqlite3Malloc instead.
*/
p = sqlite3Malloc(nByte);
if( p ){
int sz = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
sqlite3_mutex_leave(pcache1.mutex);
}
sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
}
return p;
}
/*
** Free an allocated buffer obtained from pcache1Alloc().
| > > | 37777 37778 37779 37780 37781 37782 37783 37784 37785 37786 37787 37788 37789 37790 37791 37792 37793 37794 37795 37796 37797 37798 |
sqlite3_mutex_leave(pcache1.mutex);
}
if( p==0 ){
/* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get
** it from sqlite3Malloc instead.
*/
p = sqlite3Malloc(nByte);
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
if( p ){
int sz = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
sqlite3_mutex_leave(pcache1.mutex);
}
#endif
sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
}
return p;
}
/*
** Free an allocated buffer obtained from pcache1Alloc().
|
| ︙ | ︙ | |||
37147 37148 37149 37150 37151 37152 37153 37154 37155 37156 37157 37158 37159 37160 37161 37162 37163 |
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
assert( pcache1.nFreeSlot<=pcache1.nSlot );
sqlite3_mutex_leave(pcache1.mutex);
}else{
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
nFreed = sqlite3MallocSize(p);
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
sqlite3_mutex_leave(pcache1.mutex);
sqlite3_free(p);
}
return nFreed;
}
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
| > > | 37811 37812 37813 37814 37815 37816 37817 37818 37819 37820 37821 37822 37823 37824 37825 37826 37827 37828 37829 |
pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
assert( pcache1.nFreeSlot<=pcache1.nSlot );
sqlite3_mutex_leave(pcache1.mutex);
}else{
assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
nFreed = sqlite3MallocSize(p);
#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
sqlite3_mutex_enter(pcache1.mutex);
sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
sqlite3_mutex_leave(pcache1.mutex);
#endif
sqlite3_free(p);
}
return nFreed;
}
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
|
| ︙ | ︙ | |||
37999 38000 38001 38002 38003 38004 38005 38006 38007 38008 38009 38010 38011 38012 |
** The number of rowset entries per allocation chunk.
*/
#define ROWSET_ENTRY_PER_CHUNK \
((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
/*
** Each entry in a RowSet is an instance of the following object.
*/
struct RowSetEntry {
i64 v; /* ROWID value for this entry */
struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */
struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */
};
| > > > > > | 38665 38666 38667 38668 38669 38670 38671 38672 38673 38674 38675 38676 38677 38678 38679 38680 38681 38682 38683 |
** The number of rowset entries per allocation chunk.
*/
#define ROWSET_ENTRY_PER_CHUNK \
((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
/*
** Each entry in a RowSet is an instance of the following object.
**
** This same object is reused to store a linked list of trees of RowSetEntry
** objects. In that alternative use, pRight points to the next entry
** in the list, pLeft points to the tree, and v is unused. The
** RowSet.pForest value points to the head of this forest list.
*/
struct RowSetEntry {
i64 v; /* ROWID value for this entry */
struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */
struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */
};
|
| ︙ | ︙ | |||
38028 38029 38030 38031 38032 38033 38034 |
*/
struct RowSet {
struct RowSetChunk *pChunk; /* List of all chunk allocations */
sqlite3 *db; /* The database connection */
struct RowSetEntry *pEntry; /* List of entries using pRight */
struct RowSetEntry *pLast; /* Last entry on the pEntry list */
struct RowSetEntry *pFresh; /* Source of new entry objects */
| | | > > > > > > | | | > > | > > > > > > > > > > > > > > > > > > > > > > > < < < < < < | < < < > | | | | | | < | | 38699 38700 38701 38702 38703 38704 38705 38706 38707 38708 38709 38710 38711 38712 38713 38714 38715 38716 38717 38718 38719 38720 38721 38722 38723 38724 38725 38726 38727 38728 38729 38730 38731 38732 38733 38734 38735 38736 38737 38738 38739 38740 38741 38742 38743 38744 38745 38746 38747 38748 38749 38750 38751 38752 38753 38754 38755 38756 38757 38758 38759 38760 38761 38762 38763 38764 38765 38766 38767 38768 38769 38770 38771 38772 38773 38774 38775 38776 38777 38778 38779 38780 38781 38782 38783 38784 38785 38786 38787 38788 38789 38790 38791 38792 38793 38794 38795 38796 38797 38798 38799 38800 38801 38802 38803 38804 38805 38806 38807 38808 38809 38810 38811 38812 38813 38814 38815 38816 38817 38818 38819 38820 38821 38822 38823 38824 38825 38826 38827 38828 38829 38830 38831 38832 |
*/
struct RowSet {
struct RowSetChunk *pChunk; /* List of all chunk allocations */
sqlite3 *db; /* The database connection */
struct RowSetEntry *pEntry; /* List of entries using pRight */
struct RowSetEntry *pLast; /* Last entry on the pEntry list */
struct RowSetEntry *pFresh; /* Source of new entry objects */
struct RowSetEntry *pForest; /* List of binary trees of entries */
u16 nFresh; /* Number of objects on pFresh */
u8 rsFlags; /* Various flags */
u8 iBatch; /* Current insert batch */
};
/*
** Allowed values for RowSet.rsFlags
*/
#define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */
#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */
/*
** Turn bulk memory into a RowSet object. N bytes of memory
** are available at pSpace. The db pointer is used as a memory context
** for any subsequent allocations that need to occur.
** Return a pointer to the new RowSet object.
**
** It must be the case that N is sufficient to make a Rowset. If not
** an assertion fault occurs.
**
** If N is larger than the minimum, use the surplus as an initial
** allocation of entries available to be filled.
*/
SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
RowSet *p;
assert( N >= ROUND8(sizeof(*p)) );
p = pSpace;
p->pChunk = 0;
p->db = db;
p->pEntry = 0;
p->pLast = 0;
p->pForest = 0;
p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
p->rsFlags = ROWSET_SORTED;
p->iBatch = 0;
return p;
}
/*
** Deallocate all chunks from a RowSet. This frees all memory that
** the RowSet has allocated over its lifetime. This routine is
** the destructor for the RowSet.
*/
SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
struct RowSetChunk *pChunk, *pNextChunk;
for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
pNextChunk = pChunk->pNextChunk;
sqlite3DbFree(p->db, pChunk);
}
p->pChunk = 0;
p->nFresh = 0;
p->pEntry = 0;
p->pLast = 0;
p->pForest = 0;
p->rsFlags = ROWSET_SORTED;
}
/*
** Allocate a new RowSetEntry object that is associated with the
** given RowSet. Return a pointer to the new and completely uninitialized
** objected.
**
** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
** routine returns NULL.
*/
static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
assert( p!=0 );
if( p->nFresh==0 ){
struct RowSetChunk *pNew;
pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
if( pNew==0 ){
return 0;
}
pNew->pNextChunk = p->pChunk;
p->pChunk = pNew;
p->pFresh = pNew->aEntry;
p->nFresh = ROWSET_ENTRY_PER_CHUNK;
}
p->nFresh--;
return p->pFresh++;
}
/*
** Insert a new value into a RowSet.
**
** The mallocFailed flag of the database connection is set if a
** memory allocation fails.
*/
SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
struct RowSetEntry *pEntry; /* The new entry */
struct RowSetEntry *pLast; /* The last prior entry */
/* This routine is never called after sqlite3RowSetNext() */
assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
pEntry = rowSetEntryAlloc(p);
if( pEntry==0 ) return;
pEntry->v = rowid;
pEntry->pRight = 0;
pLast = p->pLast;
if( pLast ){
if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
p->rsFlags &= ~ROWSET_SORTED;
}
pLast->pRight = pEntry;
}else{
p->pEntry = pEntry;
}
p->pLast = pEntry;
}
/*
** Merge two lists of RowSetEntry objects. Remove duplicates.
**
** The input lists are connected via pRight pointers and are
** assumed to each already be in sorted order.
*/
static struct RowSetEntry *rowSetEntryMerge(
struct RowSetEntry *pA, /* First sorted list to be merged */
struct RowSetEntry *pB /* Second sorted list to be merged */
){
struct RowSetEntry head;
struct RowSetEntry *pTail;
pTail = &head;
|
| ︙ | ︙ | |||
38159 38160 38161 38162 38163 38164 38165 |
assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
pTail->pRight = pB;
}
return head.pRight;
}
/*
| | > | | < < | < | | | | > | | | < < | 38852 38853 38854 38855 38856 38857 38858 38859 38860 38861 38862 38863 38864 38865 38866 38867 38868 38869 38870 38871 38872 38873 38874 38875 38876 38877 38878 38879 38880 38881 38882 38883 38884 38885 38886 38887 38888 |
assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
pTail->pRight = pB;
}
return head.pRight;
}
/*
** Sort all elements on the list of RowSetEntry objects into order of
** increasing v.
*/
static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
unsigned int i;
struct RowSetEntry *pNext, *aBucket[40];
memset(aBucket, 0, sizeof(aBucket));
while( pIn ){
pNext = pIn->pRight;
pIn->pRight = 0;
for(i=0; aBucket[i]; i++){
pIn = rowSetEntryMerge(aBucket[i], pIn);
aBucket[i] = 0;
}
aBucket[i] = pIn;
pIn = pNext;
}
pIn = 0;
for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
pIn = rowSetEntryMerge(pIn, aBucket[i]);
}
return pIn;
}
/*
** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
** Convert this tree into a linked list connected by the pRight pointers
** and return pointers to the first and last elements of the new list.
|
| ︙ | ︙ | |||
38278 38279 38280 38281 38282 38283 38284 |
p->pLeft = pLeft;
p->pRight = rowSetNDeepTree(&pList, iDepth);
}
return p;
}
/*
| | | | > | > > | > > > > > > > > > > > | | | < | | > > > > > > > | > > > > > > | > > > > > > | > > > > > > > > > > > > > > > > > > | > > > | > > > > > > > | > | | | | | | | > | 38968 38969 38970 38971 38972 38973 38974 38975 38976 38977 38978 38979 38980 38981 38982 38983 38984 38985 38986 38987 38988 38989 38990 38991 38992 38993 38994 38995 38996 38997 38998 38999 39000 39001 39002 39003 39004 39005 39006 39007 39008 39009 39010 39011 39012 39013 39014 39015 39016 39017 39018 39019 39020 39021 39022 39023 39024 39025 39026 39027 39028 39029 39030 39031 39032 39033 39034 39035 39036 39037 39038 39039 39040 39041 39042 39043 39044 39045 39046 39047 39048 39049 39050 39051 39052 39053 39054 39055 39056 39057 39058 39059 39060 39061 39062 39063 39064 39065 39066 39067 39068 39069 39070 39071 39072 39073 39074 39075 39076 39077 39078 39079 39080 39081 39082 39083 39084 39085 39086 39087 39088 39089 39090 39091 39092 39093 39094 39095 39096 39097 39098 39099 39100 39101 39102 39103 39104 |
p->pLeft = pLeft;
p->pRight = rowSetNDeepTree(&pList, iDepth);
}
return p;
}
/*
** Take all the entries on p->pEntry and on the trees in p->pForest and
** sort them all together into one big ordered list on p->pEntry.
**
** This routine should only be called once in the life of a RowSet.
*/
static void rowSetToList(RowSet *p){
/* This routine is called only once */
assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
if( (p->rsFlags & ROWSET_SORTED)==0 ){
p->pEntry = rowSetEntrySort(p->pEntry);
}
/* While this module could theoretically support it, sqlite3RowSetNext()
** is never called after sqlite3RowSetText() for the same RowSet. So
** there is never a forest to deal with. Should this change, simply
** remove the assert() and the #if 0. */
assert( p->pForest==0 );
#if 0
while( p->pForest ){
struct RowSetEntry *pTree = p->pForest->pLeft;
if( pTree ){
struct RowSetEntry *pHead, *pTail;
rowSetTreeToList(pTree, &pHead, &pTail);
p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
}
p->pForest = p->pForest->pRight;
}
#endif
p->rsFlags |= ROWSET_NEXT; /* Verify this routine is never called again */
}
/*
** Extract the smallest element from the RowSet.
** Write the element into *pRowid. Return 1 on success. Return
** 0 if the RowSet is already empty.
**
** After this routine has been called, the sqlite3RowSetInsert()
** routine may not be called again.
*/
SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
assert( p!=0 );
/* Merge the forest into a single sorted list on first call */
if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
/* Return the next entry on the list */
if( p->pEntry ){
*pRowid = p->pEntry->v;
p->pEntry = p->pEntry->pRight;
if( p->pEntry==0 ){
sqlite3RowSetClear(p);
}
return 1;
}else{
return 0;
}
}
/*
** Check to see if element iRowid was inserted into the the rowset as
** part of any insert batch prior to iBatch. Return 1 or 0.
**
** If this is the first test of a new batch and if there exist entires
** on pRowSet->pEntry, then sort those entires into the forest at
** pRowSet->pForest so that they can be tested.
*/
SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 iRowid){
struct RowSetEntry *p, *pTree;
/* This routine is never called after sqlite3RowSetNext() */
assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
/* Sort entries into the forest on the first test of a new batch
*/
if( iBatch!=pRowSet->iBatch ){
p = pRowSet->pEntry;
if( p ){
struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
p = rowSetEntrySort(p);
}
for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
ppPrevTree = &pTree->pRight;
if( pTree->pLeft==0 ){
pTree->pLeft = rowSetListToTree(p);
break;
}else{
struct RowSetEntry *pAux, *pTail;
rowSetTreeToList(pTree->pLeft, &pAux, &pTail);
pTree->pLeft = 0;
p = rowSetEntryMerge(pAux, p);
}
}
if( pTree==0 ){
*ppPrevTree = pTree = rowSetEntryAlloc(pRowSet);
if( pTree ){
pTree->v = 0;
pTree->pRight = 0;
pTree->pLeft = rowSetListToTree(p);
}
}
pRowSet->pEntry = 0;
pRowSet->pLast = 0;
pRowSet->rsFlags |= ROWSET_SORTED;
}
pRowSet->iBatch = iBatch;
}
/* Test to see if the iRowid value appears anywhere in the forest.
** Return 1 if it does and 0 if not.
*/
for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
p = pTree->pLeft;
while( p ){
if( p->v<iRowid ){
p = p->pRight;
}else if( p->v>iRowid ){
p = p->pLeft;
}else{
return 1;
}
}
}
return 0;
}
/************** End of rowset.c **********************************************/
/************** Begin file pager.c *******************************************/
|
| ︙ | ︙ | |||
41489 41490 41491 41492 41493 41494 41495 |
/* If a WAL transaction is being committed, there is no point in writing
** any pages with page numbers greater than nTruncate into the WAL file.
** They will never be read by any client. So remove them from the pDirty
** list here. */
PgHdr *p;
PgHdr **ppNext = &pList;
nList = 0;
| | | 42241 42242 42243 42244 42245 42246 42247 42248 42249 42250 42251 42252 42253 42254 42255 |
/* If a WAL transaction is being committed, there is no point in writing
** any pages with page numbers greater than nTruncate into the WAL file.
** They will never be read by any client. So remove them from the pDirty
** list here. */
PgHdr *p;
PgHdr **ppNext = &pList;
nList = 0;
for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
if( p->pgno<=nTruncate ){
ppNext = &p->pDirty;
nList++;
}
}
assert( pList );
}else{
|
| ︙ | ︙ | |||
42846 42847 42848 42849 42850 42851 42852 |
/* Set the output variable to NULL in case an error occurs. */
*ppPager = 0;
#ifndef SQLITE_OMIT_MEMORYDB
if( flags & PAGER_MEMORY ){
memDb = 1;
| > > > > | > | | 43598 43599 43600 43601 43602 43603 43604 43605 43606 43607 43608 43609 43610 43611 43612 43613 43614 43615 43616 43617 43618 43619 43620 43621 43622 43623 43624 43625 43626 43627 43628 |
/* Set the output variable to NULL in case an error occurs. */
*ppPager = 0;
#ifndef SQLITE_OMIT_MEMORYDB
if( flags & PAGER_MEMORY ){
memDb = 1;
if( zFilename && zFilename[0] ){
zPathname = sqlite3DbStrDup(0, zFilename);
if( zPathname==0 ) return SQLITE_NOMEM;
nPathname = sqlite3Strlen30(zPathname);
zFilename = 0;
}
}
#endif
/* Compute and store the full pathname in an allocated buffer pointed
** to by zPathname, length nPathname. Or, if this is a temporary file,
** leave both nPathname and zPathname set to 0.
*/
if( zFilename && zFilename[0] ){
const char *z;
nPathname = pVfs->mxPathname+1;
zPathname = sqlite3DbMallocRaw(0, nPathname*2);
if( zPathname==0 ){
return SQLITE_NOMEM;
}
zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
nPathname = sqlite3Strlen30(zPathname);
z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
|
| ︙ | ︙ | |||
42881 42882 42883 42884 42885 42886 42887 |
** bytes in length. This means the database cannot be opened,
** as it will not be possible to open the journal file or even
** check for a hot-journal before reading.
*/
rc = SQLITE_CANTOPEN_BKPT;
}
if( rc!=SQLITE_OK ){
| | | 43638 43639 43640 43641 43642 43643 43644 43645 43646 43647 43648 43649 43650 43651 43652 |
** bytes in length. This means the database cannot be opened,
** as it will not be possible to open the journal file or even
** check for a hot-journal before reading.
*/
rc = SQLITE_CANTOPEN_BKPT;
}
if( rc!=SQLITE_OK ){
sqlite3DbFree(0, zPathname);
return rc;
}
}
/* Allocate memory for the Pager structure, PCache object, the
** three file descriptors, the database file name and the journal
** file name. The layout in memory is as follows:
|
| ︙ | ︙ | |||
42911 42912 42913 42914 42915 42916 42917 |
nPathname + 8 + 2 /* zJournal */
#ifndef SQLITE_OMIT_WAL
+ nPathname + 4 + 2 /* zWal */
#endif
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
| | | | | 43668 43669 43670 43671 43672 43673 43674 43675 43676 43677 43678 43679 43680 43681 43682 43683 43684 43685 43686 43687 43688 43689 43690 43691 43692 43693 43694 43695 43696 43697 43698 43699 43700 43701 43702 43703 43704 43705 43706 43707 43708 |
nPathname + 8 + 2 /* zJournal */
#ifndef SQLITE_OMIT_WAL
+ nPathname + 4 + 2 /* zWal */
#endif
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
return SQLITE_NOMEM;
}
pPager = (Pager*)(pPtr);
pPager->pPCache = (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
pPager->fd = (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
pPager->jfd = (sqlite3_file*)(pPtr += journalFileSize);
pPager->zFilename = (char*)(pPtr += journalFileSize);
assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
/* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
if( zPathname ){
assert( nPathname>0 );
pPager->zJournal = (char*)(pPtr += nPathname + 1 + nUri);
memcpy(pPager->zFilename, zPathname, nPathname);
if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
memcpy(pPager->zJournal, zPathname, nPathname);
memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1);
sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
#ifndef SQLITE_OMIT_WAL
pPager->zWal = &pPager->zJournal[nPathname+8+1];
memcpy(pPager->zWal, zPathname, nPathname);
memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
#endif
sqlite3DbFree(0, zPathname);
}
pPager->pVfs = pVfs;
pPager->vfsFlags = vfsFlags;
/* Open the pager file.
*/
if( zFilename && zFilename[0] ){
|
| ︙ | ︙ | |||
44782 44783 44784 44785 44786 44787 44788 44789 | } return rc; } /* ** Return the full pathname of the database file. */ | > > > > > > > | | | 45539 45540 45541 45542 45543 45544 45545 45546 45547 45548 45549 45550 45551 45552 45553 45554 45555 45556 45557 45558 45559 45560 45561 45562 |
}
return rc;
}
/*
** Return the full pathname of the database file.
**
** Except, if the pager is in-memory only, then return an empty string if
** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when
** used to report the filename to the user, for compatibility with legacy
** behavior. But when the Btree needs to know the filename for matching to
** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
** participate in shared-cache.
*/
SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
}
/*
** Return the VFS structure for the pager.
*/
SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
return pPager->pVfs;
|
| ︙ | ︙ | |||
49146 49147 49148 49149 49150 49151 49152 49153 49154 49155 49156 49157 |
#define ISAUTOVACUUM 0
#endif
/*
** This structure is passed around through all the sanity checking routines
** in order to keep track of some global state information.
*/
typedef struct IntegrityCk IntegrityCk;
struct IntegrityCk {
BtShared *pBt; /* The tree being checked out */
Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
| > > > > > > | | 49910 49911 49912 49913 49914 49915 49916 49917 49918 49919 49920 49921 49922 49923 49924 49925 49926 49927 49928 49929 49930 49931 49932 49933 49934 49935 |
#define ISAUTOVACUUM 0
#endif
/*
** This structure is passed around through all the sanity checking routines
** in order to keep track of some global state information.
**
** The aRef[] array is allocated so that there is 1 bit for each page in
** the database. As the integrity-check proceeds, for each page used in
** the database the corresponding bit is set. This allows integrity-check to
** detect pages that are used twice and orphaned pages (both of which
** indicate corruption).
*/
typedef struct IntegrityCk IntegrityCk;
struct IntegrityCk {
BtShared *pBt; /* The tree being checked out */
Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
u8 *aPgRef; /* 1 bit per page in the db (see above) */
Pgno nPage; /* Number of pages in the database */
int mxErr; /* Stop accumulating errors when this reaches zero */
int nErr; /* Number of messages written to zErrMsg so far */
int mallocFailed; /* A memory allocation error has occurred */
StrAccum errMsg; /* Accumulate the error message text here */
};
|
| ︙ | ︙ | |||
51163 51164 51165 51166 51167 51168 51169 | /* Set the variable isMemdb to true for an in-memory database, or ** false for a file-based database. */ #ifdef SQLITE_OMIT_MEMORYDB const int isMemdb = 0; #else const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) | | > | 51933 51934 51935 51936 51937 51938 51939 51940 51941 51942 51943 51944 51945 51946 51947 51948 |
/* Set the variable isMemdb to true for an in-memory database, or
** false for a file-based database.
*/
#ifdef SQLITE_OMIT_MEMORYDB
const int isMemdb = 0;
#else
const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0)
|| (isTempDb && sqlite3TempInMemory(db))
|| (vfsFlags & SQLITE_OPEN_MEMORY)!=0;
#endif
assert( db!=0 );
assert( pVfs!=0 );
assert( sqlite3_mutex_held(db->mutex) );
assert( (flags&0xff)==flags ); /* flags fit in 8 bits */
|
| ︙ | ︙ | |||
51199 51200 51201 51202 51203 51204 51205 | #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* ** If this Btree is a candidate for shared cache, try to find an ** existing BtShared object that we can share with */ | | > > > | > | | | | > | | 51970 51971 51972 51973 51974 51975 51976 51977 51978 51979 51980 51981 51982 51983 51984 51985 51986 51987 51988 51989 51990 51991 51992 51993 51994 51995 51996 51997 51998 51999 52000 52001 52002 52003 52004 52005 52006 52007 52008 52009 52010 52011 52012 52013 |
#endif
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
/*
** If this Btree is a candidate for shared cache, try to find an
** existing BtShared object that we can share with
*/
if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=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;
}
if( isMemdb ){
memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
}else{
rc = sqlite3OsFullPathname(pVfs, zFilename,
nFullPathname, zFullPathname);
if( rc ){
sqlite3_free(zFullPathname);
sqlite3_free(p);
return rc;
}
}
#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, 0))
&& sqlite3PagerVfs(pBt->pPager)==pVfs ){
int iDb;
for(iDb=db->nDb-1; iDb>=0; iDb--){
Btree *pExisting = db->aDb[iDb].pBt;
if( pExisting && pExisting->pBt==pBt ){
sqlite3_mutex_leave(mutexShared);
sqlite3_mutex_leave(mutexOpen);
|
| ︙ | ︙ | |||
56996 56997 56998 56999 57000 57001 57002 57003 57004 57005 57006 57007 57008 57009 57010 57011 57012 57013 57014 57015 57016 |
if( pCheck->errMsg.mallocFailed ){
pCheck->mallocFailed = 1;
}
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Add 1 to the reference count for page iPage. If this is the second
** reference to the page, add an error message to pCheck->zErrMsg.
** Return 1 if there are 2 ore more references to the page and 0 if
** if this is the first reference to the page.
**
** Also check that the page number is in bounds.
*/
static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
if( iPage==0 ) return 1;
if( iPage>pCheck->nPage ){
checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
return 1;
}
| > > > > > > > > > > > > > > > > > > > | > | | 57772 57773 57774 57775 57776 57777 57778 57779 57780 57781 57782 57783 57784 57785 57786 57787 57788 57789 57790 57791 57792 57793 57794 57795 57796 57797 57798 57799 57800 57801 57802 57803 57804 57805 57806 57807 57808 57809 57810 57811 57812 57813 57814 57815 57816 57817 57818 57819 57820 57821 57822 57823 57824 |
if( pCheck->errMsg.mallocFailed ){
pCheck->mallocFailed = 1;
}
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
** Return non-zero if the bit in the IntegrityCk.aPgRef[] array that
** corresponds to page iPg is already set.
*/
static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){
assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 );
return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07)));
}
/*
** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg.
*/
static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 );
pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07));
}
/*
** Add 1 to the reference count for page iPage. If this is the second
** reference to the page, add an error message to pCheck->zErrMsg.
** Return 1 if there are 2 ore more references to the page and 0 if
** if this is the first reference to the page.
**
** Also check that the page number is in bounds.
*/
static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
if( iPage==0 ) return 1;
if( iPage>pCheck->nPage ){
checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
return 1;
}
if( getPageReferenced(pCheck, iPage) ){
checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
return 1;
}
setPageReferenced(pCheck, iPage);
return 0;
}
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** Check that the entry in the pointer-map for page iChild maps to
** page iParent, pointer type ptrType. If not, append an error message
** to pCheck.
|
| ︙ | ︙ | |||
57390 57391 57392 57393 57394 57395 57396 |
sCheck.nErr = 0;
sCheck.mallocFailed = 0;
*pnErr = 0;
if( sCheck.nPage==0 ){
sqlite3BtreeLeave(p);
return 0;
}
| | > | < | < < | 58186 58187 58188 58189 58190 58191 58192 58193 58194 58195 58196 58197 58198 58199 58200 58201 58202 58203 58204 58205 58206 58207 58208 |
sCheck.nErr = 0;
sCheck.mallocFailed = 0;
*pnErr = 0;
if( sCheck.nPage==0 ){
sqlite3BtreeLeave(p);
return 0;
}
sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
if( !sCheck.aPgRef ){
*pnErr = 1;
sqlite3BtreeLeave(p);
return 0;
}
i = PENDING_BYTE_PAGE(pBt);
if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
sCheck.errMsg.useMalloc = 2;
/* Check the integrity of the freelist
*/
checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
|
| ︙ | ︙ | |||
57425 57426 57427 57428 57429 57430 57431 |
checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
}
/* Make sure every page in the file is referenced
*/
for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
#ifdef SQLITE_OMIT_AUTOVACUUM
| | | | | | > | | 58219 58220 58221 58222 58223 58224 58225 58226 58227 58228 58229 58230 58231 58232 58233 58234 58235 58236 58237 58238 58239 58240 58241 58242 58243 58244 58245 58246 58247 58248 58249 58250 58251 58252 58253 58254 58255 58256 58257 58258 58259 58260 58261 58262 58263 58264 58265 58266 58267 58268 58269 58270 58271 58272 58273 58274 58275 58276 58277 58278 58279 58280 58281 58282 58283 58284 58285 58286 |
checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
}
/* Make sure every page in the file is referenced
*/
for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
#ifdef SQLITE_OMIT_AUTOVACUUM
if( getPageReferenced(&sCheck, i)==0 ){
checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
}
#else
/* If the database supports auto-vacuum, make sure no tables contain
** references to pointer-map pages.
*/
if( getPageReferenced(&sCheck, i)==0 &&
(PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
}
if( getPageReferenced(&sCheck, i)!=0 &&
(PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
}
#endif
}
/* Make sure this analysis did not leave any unref() pages.
** This is an internal consistency check; an integrity check
** of the integrity check.
*/
if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
checkAppendMsg(&sCheck, 0,
"Outstanding page count goes from %d to %d during this analysis",
nRef, sqlite3PagerRefcount(pBt->pPager)
);
}
/* Clean up and report errors.
*/
sqlite3BtreeLeave(p);
sqlite3_free(sCheck.aPgRef);
if( sCheck.mallocFailed ){
sqlite3StrAccumReset(&sCheck.errMsg);
*pnErr = sCheck.nErr+1;
return 0;
}
*pnErr = sCheck.nErr;
if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
return sqlite3StrAccumFinish(&sCheck.errMsg);
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/*
** Return the full pathname of the underlying database file. Return
** an empty string if the database is in-memory or a TEMP database.
**
** The pager filename is invariant as long as the pager is
** open so it is safe to access without the BtShared mutex.
*/
SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){
assert( p->pBt->pPager!=0 );
return sqlite3PagerFilename(p->pBt->pPager, 1);
}
/*
** Return the pathname of the journal file for this database. The return
** value of this routine is the same regardless of whether the journal file
** has been created or not.
**
|
| ︙ | ︙ | |||
58128 58129 58130 58131 58132 58133 58134 |
** the case where the source and destination databases have the
** same schema version.
*/
if( rc==SQLITE_DONE ){
rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
if( rc==SQLITE_OK ){
if( p->pDestDb ){
| | | 58923 58924 58925 58926 58927 58928 58929 58930 58931 58932 58933 58934 58935 58936 58937 |
** the case where the source and destination databases have the
** same schema version.
*/
if( rc==SQLITE_DONE ){
rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1);
if( rc==SQLITE_OK ){
if( p->pDestDb ){
sqlite3ResetAllSchemasOfConnection(p->pDestDb);
}
if( destMode==PAGER_JOURNALMODE_WAL ){
rc = sqlite3BtreeSetVersion(p->pDest, 2);
}
}
if( rc==SQLITE_OK ){
int nDestTruncate;
|
| ︙ | ︙ | |||
64313 64314 64315 64316 64317 64318 64319 64320 |
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Allocate a new Explain object
*/
SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
if( pVdbe ){
sqlite3BeginBenignMalloc();
| > | | 65108 65109 65110 65111 65112 65113 65114 65115 65116 65117 65118 65119 65120 65121 65122 65123 65124 |
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
/*
** Allocate a new Explain object
*/
SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
if( pVdbe ){
Explain *p;
sqlite3BeginBenignMalloc();
p = sqlite3_malloc( sizeof(Explain) );
if( p ){
memset(p, 0, sizeof(*p));
p->pVdbe = pVdbe;
sqlite3_free(pVdbe->pExplain);
pVdbe->pExplain = p;
sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
SQLITE_MAX_LENGTH);
|
| ︙ | ︙ | |||
67712 67713 67714 67715 67716 67717 67718 |
rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
| | | 68508 68509 68510 68511 68512 68513 68514 68515 68516 68517 68518 68519 68520 68521 68522 |
rc = sqlite3BtreeSavepoint(db->aDb[u.ar.ii].pBt, u.ar.p1, u.ar.iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
if( u.ar.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
db->flags = (db->flags | SQLITE_InternChanges);
}
}
/* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
** savepoints nested inside of the savepoint being operated on. */
while( db->pSavepoint!=u.ar.pSavepoint ){
|
| ︙ | ︙ | |||
68026 68027 68028 68029 68030 68031 68032 |
** prepared queries. If such a query is out-of-date, we do not want to
** discard the database schema, as the user code implementing the
** v-table would have to be ready for the sqlite3_vtab structure itself
** to be invalidated whenever sqlite3_step() is called from within
** a v-table method.
*/
if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){
| | | 68822 68823 68824 68825 68826 68827 68828 68829 68830 68831 68832 68833 68834 68835 68836 |
** prepared queries. If such a query is out-of-date, we do not want to
** discard the database schema, as the user code implementing the
** v-table would have to be ready for the sqlite3_vtab structure itself
** to be invalidated whenever sqlite3_step() is called from within
** a v-table method.
*/
if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.aw.iMeta ){
sqlite3ResetOneSchema(db, pOp->p1);
}
p->expired = 1;
rc = SQLITE_SCHEMA;
}
break;
}
|
| ︙ | ︙ | |||
69895 69896 69897 69898 69899 69900 69901 |
assert( !db->mallocFailed );
rc = sqlite3_exec(db, u.by.zSql, sqlite3InitCallback, &u.by.initData, 0);
if( rc==SQLITE_OK ) rc = u.by.initData.rc;
sqlite3DbFree(db, u.by.zSql);
db->init.busy = 0;
}
}
| | | 70691 70692 70693 70694 70695 70696 70697 70698 70699 70700 70701 70702 70703 70704 70705 |
assert( !db->mallocFailed );
rc = sqlite3_exec(db, u.by.zSql, sqlite3InitCallback, &u.by.initData, 0);
if( rc==SQLITE_OK ) rc = u.by.initData.rc;
sqlite3DbFree(db, u.by.zSql);
db->init.busy = 0;
}
}
if( rc ) sqlite3ResetAllSchemasOfConnection(db);
if( rc==SQLITE_NOMEM ){
goto no_mem;
}
break;
}
#if !defined(SQLITE_OMIT_ANALYZE)
|
| ︙ | ︙ | |||
70562 70563 70564 70565 70566 70567 70568 | u.ci.pBt = db->aDb[pOp->p1].pBt; u.ci.pPager = sqlite3BtreePager(u.ci.pBt); u.ci.eOld = sqlite3PagerGetJournalMode(u.ci.pPager); if( u.ci.eNew==PAGER_JOURNALMODE_QUERY ) u.ci.eNew = u.ci.eOld; if( !sqlite3PagerOkToChangeJournalMode(u.ci.pPager) ) u.ci.eNew = u.ci.eOld; #ifndef SQLITE_OMIT_WAL | | | 71358 71359 71360 71361 71362 71363 71364 71365 71366 71367 71368 71369 71370 71371 71372 |
u.ci.pBt = db->aDb[pOp->p1].pBt;
u.ci.pPager = sqlite3BtreePager(u.ci.pBt);
u.ci.eOld = sqlite3PagerGetJournalMode(u.ci.pPager);
if( u.ci.eNew==PAGER_JOURNALMODE_QUERY ) u.ci.eNew = u.ci.eOld;
if( !sqlite3PagerOkToChangeJournalMode(u.ci.pPager) ) u.ci.eNew = u.ci.eOld;
#ifndef SQLITE_OMIT_WAL
u.ci.zFilename = sqlite3PagerFilename(u.ci.pPager, 1);
/* Do not allow a transition to journal_mode=WAL for a database
** in temporary storage or if the VFS does not support shared memory
*/
if( u.ci.eNew==PAGER_JOURNALMODE_WAL
&& (sqlite3Strlen30(u.ci.zFilename)==0 /* Temp file */
|| !sqlite3PagerWalSupported(u.ci.pPager)) /* No shared-memory support */
|
| ︙ | ︙ | |||
71228 71229 71230 71231 71232 71233 71234 |
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
pc, p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
if( resetSchemaOnFault>0 ){
| | | 72024 72025 72026 72027 72028 72029 72030 72031 72032 72033 72034 72035 72036 72037 72038 |
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
pc, p->zSql, p->zErrMsg);
sqlite3VdbeHalt(p);
if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
rc = SQLITE_ERROR;
if( resetSchemaOnFault>0 ){
sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
}
/* This is the only way out of this procedure. We have to
** release the mutexes on btrees that were acquired at the
** top. */
vdbe_return:
db->lastRowid = lastRowid;
|
| ︙ | ︙ | |||
73583 73584 73585 73586 73587 73588 73589 |
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
| | | 74379 74380 74381 74382 74383 74384 74385 74386 74387 74388 74389 74390 74391 74392 74393 |
char *zAs = pEList->a[j].zName;
if( zAs!=0 && sqlite3StrICmp(zAs, zCol)==0 ){
Expr *pOrig;
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr;
if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
resolveAlias(pParse, pEList, j, pExpr, "");
cnt = 1;
pMatch = 0;
assert( zTab==0 && zDb==0 );
|
| ︙ | ︙ | |||
73805 73806 73807 73808 73809 73810 73811 |
testcase( pExpr->op==TK_CONST_FUNC );
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
| | | 74601 74602 74603 74604 74605 74606 74607 74608 74609 74610 74611 74612 74613 74614 74615 |
testcase( pExpr->op==TK_CONST_FUNC );
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
zId = pExpr->u.zToken;
nId = sqlite3Strlen30(zId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
if( pDef==0 ){
pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
if( pDef==0 ){
no_such_func = 1;
}else{
wrong_num_args = 1;
}
}else{
is_agg = pDef->xFunc==0;
|
| ︙ | ︙ | |||
73828 73829 73830 73831 73832 73833 73834 |
pNC->nErr++;
}
pExpr->op = TK_NULL;
return WRC_Prune;
}
}
#endif
| | | | | | | | 74624 74625 74626 74627 74628 74629 74630 74631 74632 74633 74634 74635 74636 74637 74638 74639 74640 74641 74642 74643 74644 74645 74646 74647 74648 74649 74650 74651 74652 74653 74654 74655 74656 74657 74658 74659 74660 74661 74662 74663 74664 74665 74666 74667 74668 74669 74670 74671 74672 74673 74674 74675 74676 74677 74678 74679 74680 74681 74682 74683 74684 74685 |
pNC->nErr++;
}
pExpr->op = TK_NULL;
return WRC_Prune;
}
}
#endif
if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
pNC->nErr++;
is_agg = 0;
}else if( no_such_func ){
sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
pNC->nErr++;
}else if( wrong_num_args ){
sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
nId, zId);
pNC->nErr++;
}
if( is_agg ){
pExpr->op = TK_AGG_FUNCTION;
pNC->ncFlags |= NC_HasAgg;
}
if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
sqlite3WalkExprList(pWalker, pList);
if( is_agg ) pNC->ncFlags |= NC_AllowAgg;
/* FIX ME: Compute pExpr->affinity based on the expected return
** type of the function
*/
return WRC_Prune;
}
#ifndef SQLITE_OMIT_SUBQUERY
case TK_SELECT:
case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
#endif
case TK_IN: {
testcase( pExpr->op==TK_IN );
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef;
#ifndef SQLITE_OMIT_CHECK
if( (pNC->ncFlags & NC_IsCheck)!=0 ){
sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
}
#endif
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
assert( pNC->nRef>=nRef );
if( nRef!=pNC->nRef ){
ExprSetProperty(pExpr, EP_VarSelect);
}
}
break;
}
#ifndef SQLITE_OMIT_CHECK
case TK_VARIABLE: {
if( (pNC->ncFlags & NC_IsCheck)!=0 ){
sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
}
break;
}
#endif
}
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
|
| ︙ | ︙ | |||
73957 73958 73959 73960 73961 73962 73963 | /* Resolve all names in the ORDER BY term expression */ memset(&nc, 0, sizeof(nc)); nc.pParse = pParse; nc.pSrcList = pSelect->pSrc; nc.pEList = pEList; | | | 74753 74754 74755 74756 74757 74758 74759 74760 74761 74762 74763 74764 74765 74766 74767 | /* Resolve all names in the ORDER BY term expression */ memset(&nc, 0, sizeof(nc)); nc.pParse = pParse; nc.pSrcList = pSelect->pSrc; nc.pEList = pEList; nc.ncFlags = NC_AllowAgg; nc.nErr = 0; db = pParse->db; savedSuppErr = db->suppressErr; db->suppressErr = 1; rc = sqlite3ResolveExprNames(&nc, pE); db->suppressErr = savedSuppErr; if( rc ) return 0; |
| ︙ | ︙ | |||
74155 74156 74157 74158 74159 74160 74161 |
*/
static int resolveOrderGroupBy(
NameContext *pNC, /* The name context of the SELECT statement */
Select *pSelect, /* The SELECT statement holding pOrderBy */
ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */
const char *zType /* Either "ORDER" or "GROUP", as appropriate */
){
| | | 74951 74952 74953 74954 74955 74956 74957 74958 74959 74960 74961 74962 74963 74964 74965 |
*/
static int resolveOrderGroupBy(
NameContext *pNC, /* The name context of the SELECT statement */
Select *pSelect, /* The SELECT statement holding pOrderBy */
ExprList *pOrderBy, /* An ORDER BY or GROUP BY clause to resolve */
const char *zType /* Either "ORDER" or "GROUP", as appropriate */
){
int i, j; /* Loop counters */
int iCol; /* Column number */
struct ExprList_item *pItem; /* A term of the ORDER BY clause */
Parse *pParse; /* Parsing context */
int nResult; /* Number of terms in the result set */
if( pOrderBy==0 ) return 0;
nResult = pSelect->pEList->nExpr;
|
| ︙ | ︙ | |||
74191 74192 74193 74194 74195 74196 74197 74198 74199 74200 74201 74202 74203 74204 |
continue;
}
/* Otherwise, treat the ORDER BY term as an ordinary expression */
pItem->iOrderByCol = 0;
if( sqlite3ResolveExprNames(pNC, pE) ){
return 1;
}
}
return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}
/*
** Resolve names in the SELECT statement p and all of its descendents.
| > > > > > | 74987 74988 74989 74990 74991 74992 74993 74994 74995 74996 74997 74998 74999 75000 75001 75002 75003 75004 75005 |
continue;
}
/* Otherwise, treat the ORDER BY term as an ordinary expression */
pItem->iOrderByCol = 0;
if( sqlite3ResolveExprNames(pNC, pE) ){
return 1;
}
for(j=0; j<pSelect->pEList->nExpr; j++){
if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){
pItem->iOrderByCol = j+1;
}
}
}
return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
}
/*
** Resolve names in the SELECT statement p and all of its descendents.
|
| ︙ | ︙ | |||
74254 74255 74256 74257 74258 74259 74260 |
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
return WRC_Abort;
}
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
*/
| | | 75055 75056 75057 75058 75059 75060 75061 75062 75063 75064 75065 75066 75067 75068 75069 |
sqlite3ResolveExprNames(&sNC, p->pOffset) ){
return WRC_Abort;
}
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list.
*/
sNC.ncFlags = NC_AllowAgg;
sNC.pSrcList = p->pSrc;
sNC.pNext = pOuterNC;
/* Resolve names in the result set. */
pEList = p->pEList;
assert( pEList!=0 );
for(i=0; i<pEList->nExpr; i++){
|
| ︙ | ︙ | |||
74300 74301 74302 74303 74304 74305 74306 |
}
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
*/
assert( (p->selFlags & SF_Aggregate)==0 );
pGroupBy = p->pGroupBy;
| | | | 75101 75102 75103 75104 75105 75106 75107 75108 75109 75110 75111 75112 75113 75114 75115 75116 75117 75118 |
}
/* If there are no aggregate functions in the result-set, and no GROUP BY
** expression, do not allow aggregates in any of the other expressions.
*/
assert( (p->selFlags & SF_Aggregate)==0 );
pGroupBy = p->pGroupBy;
if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
p->selFlags |= SF_Aggregate;
}else{
sNC.ncFlags &= ~NC_AllowAgg;
}
/* If a HAVING clause is present, then there must be a GROUP BY clause.
*/
if( p->pHaving && !pGroupBy ){
sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
return WRC_Abort;
|
| ︙ | ︙ | |||
74332 74333 74334 74335 74336 74337 74338 |
return WRC_Abort;
}
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
sNC.pNext = 0;
| | | 75133 75134 75135 75136 75137 75138 75139 75140 75141 75142 75143 75144 75145 75146 75147 |
return WRC_Abort;
}
/* The ORDER BY and GROUP BY clauses may not refer to terms in
** outer queries
*/
sNC.pNext = 0;
sNC.ncFlags |= NC_AllowAgg;
/* Process the ORDER BY clause for singleton SELECT statements.
** The ORDER BY clause for compounds SELECT statements is handled
** below, after all of the result-sets for all of the elements of
** the compound have been resolved.
*/
if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
|
| ︙ | ︙ | |||
74420 74421 74422 74423 74424 74425 74426 | ** ** The "x" term of the order by is replaced by "a+b" to render: ** ** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; ** ** Function calls are checked to make sure that the function is ** defined and that the correct number of arguments are specified. | | | | | | | | 75221 75222 75223 75224 75225 75226 75227 75228 75229 75230 75231 75232 75233 75234 75235 75236 75237 75238 75239 75240 75241 75242 75243 75244 75245 75246 75247 75248 75249 75250 75251 75252 75253 75254 75255 75256 75257 75258 75259 75260 75261 75262 75263 75264 75265 75266 75267 75268 75269 75270 75271 75272 75273 75274 75275 75276 |
**
** The "x" term of the order by is replaced by "a+b" to render:
**
** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b;
**
** Function calls are checked to make sure that the function is
** defined and that the correct number of arguments are specified.
** If the function is an aggregate function, then the NC_HasAgg flag is
** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION.
** If an expression contains aggregate functions then the EP_Agg
** property on the expression is set.
**
** An error message is left in pParse if anything is amiss. The number
** if errors is returned.
*/
SQLITE_PRIVATE int sqlite3ResolveExprNames(
NameContext *pNC, /* Namespace to resolve expressions in. */
Expr *pExpr /* The expression to be analyzed. */
){
u8 savedHasAgg;
Walker w;
if( pExpr==0 ) return 0;
#if SQLITE_MAX_EXPR_DEPTH>0
{
Parse *pParse = pNC->pParse;
if( sqlite3ExprCheckHeight(pParse, pExpr->nHeight+pNC->pParse->nHeight) ){
return 1;
}
pParse->nHeight += pExpr->nHeight;
}
#endif
savedHasAgg = pNC->ncFlags & NC_HasAgg;
pNC->ncFlags &= ~NC_HasAgg;
w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep;
w.pParse = pNC->pParse;
w.u.pNC = pNC;
sqlite3WalkExpr(&w, pExpr);
#if SQLITE_MAX_EXPR_DEPTH>0
pNC->pParse->nHeight -= pExpr->nHeight;
#endif
if( pNC->nErr>0 || w.pParse->nErr>0 ){
ExprSetProperty(pExpr, EP_Error);
}
if( pNC->ncFlags & NC_HasAgg ){
ExprSetProperty(pExpr, EP_Agg);
}else if( savedHasAgg ){
pNC->ncFlags |= NC_HasAgg;
}
return ExprHasProperty(pExpr, EP_Error);
}
/*
** Resolve all names in all expressions of a SELECT and in all
|
| ︙ | ︙ | |||
78275 78276 78277 78278 78279 78280 78281 |
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
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;
}
| | | 79076 79077 79078 79079 79080 79081 79082 79083 79084 79085 79086 79087 79088 79089 79090 |
if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
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 && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2;
}
}
if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
|
| ︙ | ︙ | |||
78311 78312 78313 78314 78315 78316 78317 78318 78319 78320 78321 78322 78323 78324 |
Expr *pExprA = pA->a[i].pExpr;
Expr *pExprB = pB->a[i].pExpr;
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
}
return 0;
}
/*
** Add a new element to the pAggInfo->aCol[] array. Return the index of
** the new element. Return a negative number if malloc fails.
*/
static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
int i;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 79112 79113 79114 79115 79116 79117 79118 79119 79120 79121 79122 79123 79124 79125 79126 79127 79128 79129 79130 79131 79132 79133 79134 79135 79136 79137 79138 79139 79140 79141 79142 79143 79144 79145 79146 79147 79148 79149 79150 79151 79152 79153 79154 79155 79156 79157 79158 79159 79160 |
Expr *pExprA = pA->a[i].pExpr;
Expr *pExprB = pB->a[i].pExpr;
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
}
return 0;
}
/*
** This is the expression callback for sqlite3FunctionUsesOtherSrc().
**
** Determine if an expression references any table other than one of the
** tables in pWalker->u.pSrcList and abort if it does.
*/
static int exprUsesOtherSrc(Walker *pWalker, Expr *pExpr){
if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
int i;
SrcList *pSrc = pWalker->u.pSrcList;
for(i=0; i<pSrc->nSrc; i++){
if( pExpr->iTable==pSrc->a[i].iCursor ) return WRC_Continue;
}
return WRC_Abort;
}else{
return WRC_Continue;
}
}
/*
** Determine if any of the arguments to the pExpr Function references
** any SrcList other than pSrcList. Return true if they do. Return
** false if pExpr has no argument or has only constant arguments or
** only references tables named in pSrcList.
*/
static int sqlite3FunctionUsesOtherSrc(Expr *pExpr, SrcList *pSrcList){
Walker w;
assert( pExpr->op==TK_AGG_FUNCTION );
memset(&w, 0, sizeof(w));
w.xExprCallback = exprUsesOtherSrc;
w.u.pSrcList = pSrcList;
if( sqlite3WalkExprList(&w, pExpr->x.pList)!=WRC_Continue ) return 1;
return 0;
}
/*
** Add a new element to the pAggInfo->aCol[] array. Return the index of
** the new element. Return a negative number if malloc fails.
*/
static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){
int i;
|
| ︙ | ︙ | |||
78427 78428 78429 78430 78431 78432 78433 |
break;
} /* endif pExpr->iTable==pItem->iCursor */
} /* end loop over pSrcList */
}
return WRC_Prune;
}
case TK_AGG_FUNCTION: {
| | | | | 79263 79264 79265 79266 79267 79268 79269 79270 79271 79272 79273 79274 79275 79276 79277 79278 79279 |
break;
} /* endif pExpr->iTable==pItem->iCursor */
} /* end loop over pSrcList */
}
return WRC_Prune;
}
case TK_AGG_FUNCTION: {
if( (pNC->ncFlags & NC_InAggFunc)==0
&& !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList)
){
/* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure
*/
struct AggInfo_func *pItem = pAggInfo->aFunc;
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
break;
|
| ︙ | ︙ | |||
78466 78467 78468 78469 78470 78471 78472 |
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(pExpr);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
| < > | < < | < < < | < > | 79302 79303 79304 79305 79306 79307 79308 79309 79310 79311 79312 79313 79314 79315 79316 79317 79318 79319 79320 79321 79322 79323 79324 79325 79326 79327 79328 79329 79330 79331 79332 79333 79334 79335 79336 79337 79338 |
}
/* Make pExpr point to the appropriate pAggInfo->aFunc[] entry
*/
assert( !ExprHasAnyProperty(pExpr, EP_TokenOnly|EP_Reduced) );
ExprSetIrreducible(pExpr);
pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo;
}
return WRC_Prune;
}
}
return WRC_Continue;
}
static int analyzeAggregatesInSelect(Walker *pWalker, Select *pSelect){
UNUSED_PARAMETER(pWalker);
UNUSED_PARAMETER(pSelect);
return WRC_Continue;
}
/*
** Analyze the given expression looking for aggregate functions and
** for variables that need to be added to the pParse->aAgg[] array.
** Make additional entries to the pParse->aAgg[] array as necessary.
**
** This routine should only be called after the expression has been
** analyzed by sqlite3ResolveExprNames().
*/
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){
Walker w;
memset(&w, 0, sizeof(w));
w.xExprCallback = analyzeAggregate;
w.xSelectCallback = analyzeAggregatesInSelect;
w.u.pNC = pNC;
assert( pNC->pSrcList!=0 );
sqlite3WalkExpr(&w, pExpr);
}
|
| ︙ | ︙ | |||
80756 80757 80758 80759 80760 80761 80762 |
int iDb = db->nDb - 1;
assert( iDb>=2 );
if( db->aDb[iDb].pBt ){
sqlite3BtreeClose(db->aDb[iDb].pBt);
db->aDb[iDb].pBt = 0;
db->aDb[iDb].pSchema = 0;
}
| | | 81587 81588 81589 81590 81591 81592 81593 81594 81595 81596 81597 81598 81599 81600 81601 |
int iDb = db->nDb - 1;
assert( iDb>=2 );
if( db->aDb[iDb].pBt ){
sqlite3BtreeClose(db->aDb[iDb].pBt);
db->aDb[iDb].pBt = 0;
db->aDb[iDb].pSchema = 0;
}
sqlite3ResetAllSchemasOfConnection(db);
db->nDb = iDb;
if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
db->mallocFailed = 1;
sqlite3DbFree(db, zErrDyn);
zErrDyn = sqlite3MPrintf(db, "out of memory");
}else if( zErrDyn==0 ){
zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
|
| ︙ | ︙ | |||
80828 80829 80830 80831 80832 80833 80834 |
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
| | | 81659 81660 81661 81662 81663 81664 81665 81666 81667 81668 81669 81670 81671 81672 81673 |
sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
goto detach_error;
}
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
sqlite3ResetAllSchemasOfConnection(db);
return;
detach_error:
sqlite3_result_error(context, zErr, -1);
}
/*
|
| ︙ | ︙ | |||
81744 81745 81746 81747 81748 81749 81750 |
}
freeIndex(db, pIndex);
}
db->flags |= SQLITE_InternChanges;
}
/*
| > | < | < < | < < > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 82575 82576 82577 82578 82579 82580 82581 82582 82583 82584 82585 82586 82587 82588 82589 82590 82591 82592 82593 82594 82595 82596 82597 82598 82599 82600 82601 82602 82603 82604 82605 82606 82607 82608 82609 82610 82611 82612 82613 82614 82615 82616 82617 82618 82619 82620 82621 82622 82623 82624 82625 82626 82627 82628 82629 82630 82631 82632 82633 82634 82635 82636 82637 82638 82639 82640 82641 82642 82643 82644 82645 82646 82647 82648 82649 82650 82651 82652 82653 82654 82655 82656 82657 82658 82659 82660 82661 82662 |
}
freeIndex(db, pIndex);
}
db->flags |= SQLITE_InternChanges;
}
/*
** Look through the list of open database files in db->aDb[] and if
** any have been closed, remove them from the list. Reallocate the
** db->aDb[] structure to a smaller size, if possible.
**
** Entry 0 (the "main" database) and entry 1 (the "temp" database)
** are never candidates for being collapsed.
*/
SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){
int i, j;
for(i=j=2; i<db->nDb; i++){
struct Db *pDb = &db->aDb[i];
if( pDb->pBt==0 ){
sqlite3DbFree(db, pDb->zName);
pDb->zName = 0;
continue;
}
if( j<i ){
db->aDb[j] = db->aDb[i];
}
j++;
}
memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
db->nDb = j;
if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
sqlite3DbFree(db, db->aDb);
db->aDb = db->aDbStatic;
}
}
/*
** Reset the schema for the database at index iDb. Also reset the
** TEMP schema.
*/
SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
Db *pDb;
assert( iDb<db->nDb );
/* Case 1: Reset the single schema identified by iDb */
pDb = &db->aDb[iDb];
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
assert( pDb->pSchema!=0 );
sqlite3SchemaClear(pDb->pSchema);
/* If any database other than TEMP is reset, then also reset TEMP
** since TEMP might be holding triggers that reference tables in the
** other database.
*/
if( iDb!=1 ){
pDb = &db->aDb[1];
assert( pDb->pSchema!=0 );
sqlite3SchemaClear(pDb->pSchema);
}
return;
}
/*
** Erase all schema information from all attached databases (including
** "main" and "temp") for a single database connection.
*/
SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
int i;
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pSchema ){
sqlite3SchemaClear(pDb->pSchema);
}
}
db->flags &= ~SQLITE_InternChanges;
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
sqlite3CollapseDatabaseArray(db);
}
/*
** This routine is called when a commit occurs.
*/
SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){
db->flags &= ~SQLITE_InternChanges;
}
|
| ︙ | ︙ | |||
81852 81853 81854 81855 81856 81857 81858 81859 81860 81861 81862 81863 81864 81865 81866 81867 81868 81869 81870 81871 81872 81873 81874 |
** Remove the memory data structures associated with the given
** Table. No changes are made to disk by this routine.
**
** This routine just deletes the data structure. It does not unlink
** the table data structure from the hash table. But it does destroy
** memory structures of the indices and foreign keys associated with
** the table.
*/
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
Index *pIndex, *pNext;
assert( !pTable || pTable->nRef>0 );
/* Do not delete the table until the reference count reaches zero. */
if( !pTable ) return;
if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
| > > > > > > > > > > > > > | 82685 82686 82687 82688 82689 82690 82691 82692 82693 82694 82695 82696 82697 82698 82699 82700 82701 82702 82703 82704 82705 82706 82707 82708 82709 82710 82711 82712 82713 82714 82715 82716 82717 82718 82719 82720 |
** Remove the memory data structures associated with the given
** Table. No changes are made to disk by this routine.
**
** This routine just deletes the data structure. It does not unlink
** the table data structure from the hash table. But it does destroy
** memory structures of the indices and foreign keys associated with
** the table.
**
** The db parameter is optional. It is needed if the Table object
** contains lookaside memory. (Table objects in the schema do not use
** lookaside memory, but some ephemeral Table objects do.) Or the
** db parameter can be used with db->pnBytesFreed to measure the memory
** used by the Table object.
*/
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
Index *pIndex, *pNext;
TESTONLY( int nLookaside; ) /* Used to verify lookaside not used for schema */
assert( !pTable || pTable->nRef>0 );
/* Do not delete the table until the reference count reaches zero. */
if( !pTable ) return;
if( ((!db || db->pnBytesFreed==0) && (--pTable->nRef)>0) ) return;
/* Record the number of outstanding lookaside allocations in schema Tables
** prior to doing any free() operations. Since schema Tables do not use
** lookaside, this number should not change. */
TESTONLY( nLookaside = (db && (pTable->tabFlags & TF_Ephemeral)==0) ?
db->lookaside.nOut : 0 );
/* Delete all indices associated with this table. */
for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
pNext = pIndex->pNext;
assert( pIndex->pSchema==pTable->pSchema );
if( !db || db->pnBytesFreed==0 ){
char *zName = pIndex->zName;
|
| ︙ | ︙ | |||
81893 81894 81895 81896 81897 81898 81899 81900 81901 81902 81903 81904 81905 81906 |
#ifndef SQLITE_OMIT_CHECK
sqlite3ExprListDelete(db, pTable->pCheck);
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3VtabClear(db, pTable);
#endif
sqlite3DbFree(db, pTable);
}
/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
| > > > | 82739 82740 82741 82742 82743 82744 82745 82746 82747 82748 82749 82750 82751 82752 82753 82754 82755 |
#ifndef SQLITE_OMIT_CHECK
sqlite3ExprListDelete(db, pTable->pCheck);
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
sqlite3VtabClear(db, pTable);
#endif
sqlite3DbFree(db, pTable);
/* Verify that no lookaside memory was used by schema tables */
assert( nLookaside==0 || nLookaside==db->lookaside.nOut );
}
/*
** Unlink the given table from the hash tables and the delete the
** table structure with all its indices and foreign keys.
*/
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
|
| ︙ | ︙ | |||
82841 82842 82843 82844 82845 82846 82847 |
memset(&sSrc, 0, sizeof(sSrc));
sSrc.nSrc = 1;
sSrc.a[0].zName = p->zName;
sSrc.a[0].pTab = p;
sSrc.a[0].iCursor = -1;
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
| | | 83690 83691 83692 83693 83694 83695 83696 83697 83698 83699 83700 83701 83702 83703 83704 |
memset(&sSrc, 0, sizeof(sSrc));
sSrc.nSrc = 1;
sSrc.a[0].zName = p->zName;
sSrc.a[0].pTab = p;
sSrc.a[0].iCursor = -1;
sNC.pParse = pParse;
sNC.pSrcList = &sSrc;
sNC.ncFlags = NC_IsCheck;
pList = p->pCheck;
for(i=0; i<pList->nExpr; i++){
if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
return;
}
}
}
|
| ︙ | ︙ | |||
84097 84098 84099 84100 84101 84102 84103 |
memcpy(zExtra, zColl, nColl);
zColl = zExtra;
zExtra += nColl;
nExtra -= nColl;
}else{
zColl = pTab->aCol[j].zColl;
if( !zColl ){
| | | 84946 84947 84948 84949 84950 84951 84952 84953 84954 84955 84956 84957 84958 84959 84960 |
memcpy(zExtra, zColl, nColl);
zColl = zExtra;
zExtra += nColl;
nExtra -= nColl;
}else{
zColl = pTab->aCol[j].zColl;
if( !zColl ){
zColl = "BINARY";
}
}
if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){
goto exit_create_index;
}
pIndex->azColl[i] = zColl;
requestedSortOrder = pListItem->sortOrder & sortOrderMask;
|
| ︙ | ︙ | |||
85397 85398 85399 85400 85401 85402 85403 85404 85405 85406 | } /* During the search for the best function definition, this procedure ** is called to test how well the function passed as the first argument ** matches the request for a function with nArg arguments in a system ** that uses encoding enc. The value returned indicates how well the ** request is matched. A higher value indicates a better match. ** ** The returned value is always between 0 and 6, as follows: ** | > > > > > > > > | | < | < | | < | < | > > > > | > > > > | | > > | > > | > > > > > < < | > > | | < < | | | | | 86246 86247 86248 86249 86250 86251 86252 86253 86254 86255 86256 86257 86258 86259 86260 86261 86262 86263 86264 86265 86266 86267 86268 86269 86270 86271 86272 86273 86274 86275 86276 86277 86278 86279 86280 86281 86282 86283 86284 86285 86286 86287 86288 86289 86290 86291 86292 86293 86294 86295 86296 86297 86298 86299 86300 86301 86302 86303 86304 86305 86306 86307 86308 86309 86310 86311 |
}
/* During the search for the best function definition, this procedure
** is called to test how well the function passed as the first argument
** matches the request for a function with nArg arguments in a system
** that uses encoding enc. The value returned indicates how well the
** request is matched. A higher value indicates a better match.
**
** If nArg is -1 that means to only return a match (non-zero) if p->nArg
** is also -1. In other words, we are searching for a function that
** takes a variable number of arguments.
**
** If nArg is -2 that means that we are searching for any function
** regardless of the number of arguments it uses, so return a positive
** match score for any
**
** The returned value is always between 0 and 6, as follows:
**
** 0: Not a match.
** 1: UTF8/16 conversion required and function takes any number of arguments.
** 2: UTF16 byte order change required and function takes any number of args.
** 3: encoding matches and function takes any number of arguments
** 4: UTF8/16 conversion required - argument count matches exactly
** 5: UTF16 byte order conversion required - argument count matches exactly
** 6: Perfect match: encoding and argument count match exactly.
**
** If nArg==(-2) then any function with a non-null xStep or xFunc is
** a perfect match and any function with both xStep and xFunc NULL is
** a non-match.
*/
#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
static int matchQuality(
FuncDef *p, /* The function we are evaluating for match quality */
int nArg, /* Desired number of arguments. (-1)==any */
u8 enc /* Desired text encoding */
){
int match;
/* nArg of -2 is a special case */
if( nArg==(-2) ) return (p->xFunc==0 && p->xStep==0) ? 0 : FUNC_PERFECT_MATCH;
/* Wrong number of arguments means "no match" */
if( p->nArg!=nArg && p->nArg>=0 ) return 0;
/* Give a better score to a function with a specific number of arguments
** than to function that accepts any number of arguments. */
if( p->nArg==nArg ){
match = 4;
}else{
match = 1;
}
/* Bonus points if the text encoding matches */
if( enc==p->iPrefEnc ){
match += 2; /* Exact encoding match */
}else if( (enc & p->iPrefEnc & 2)!=0 ){
match += 1; /* Both are UTF16, but with different byte orders */
}
return match;
}
/*
** Search a FuncDefHash for a function with the given name. Return
** a pointer to the matching FuncDef if found, or 0 if there is no match.
*/
|
| ︙ | ︙ | |||
85485 85486 85487 85488 85489 85490 85491 | ** Locate a user function given a name, a number of arguments and a flag ** indicating whether the function prefers UTF-16 over UTF-8. Return a ** pointer to the FuncDef structure that defines that function, or return ** NULL if the function does not exist. ** ** If the createFlag argument is true, then a new (blank) FuncDef ** structure is created and liked into the "db" structure if a | | < < | | > | | | > | 86353 86354 86355 86356 86357 86358 86359 86360 86361 86362 86363 86364 86365 86366 86367 86368 86369 86370 86371 86372 86373 86374 86375 86376 86377 86378 86379 86380 86381 86382 86383 86384 86385 86386 86387 86388 86389 86390 86391 86392 |
** Locate a user function given a name, a number of arguments and a flag
** indicating whether the function prefers UTF-16 over UTF-8. Return a
** pointer to the FuncDef structure that defines that function, or return
** NULL if the function does not exist.
**
** If the createFlag argument is true, then a new (blank) FuncDef
** structure is created and liked into the "db" structure if a
** no matching function previously existed.
**
** If nArg is -2, then the first valid function found is returned. A
** function is valid if either xFunc or xStep is non-zero. The nArg==(-2)
** case is used to see if zName is a valid function name for some number
** of arguments. If nArg is -2, then createFlag must be 0.
**
** If createFlag is false, then a function with the required name and
** number of arguments may be returned even if the eTextRep flag does not
** match that requested.
*/
SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
sqlite3 *db, /* An open database */
const char *zName, /* Name of the function. Not null-terminated */
int nName, /* Number of characters in the name */
int nArg, /* Number of arguments. -1 means any number */
u8 enc, /* Preferred text encoding */
u8 createFlag /* Create new entry if true and does not otherwise exist */
){
FuncDef *p; /* Iterator variable */
FuncDef *pBest = 0; /* Best match found so far */
int bestScore = 0; /* Score of best match */
int h; /* Hash value */
assert( nArg>=(-2) );
assert( nArg>=(-1) || createFlag==0 );
assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
/* First search for a match amongst the application-defined functions.
*/
p = functionSearch(&db->aFunc, h, zName, nName);
while( p ){
|
| ︙ | ︙ | |||
85556 85557 85558 85559 85560 85561 85562 |
}
}
/* If the createFlag parameter is true and the search did not reveal an
** exact match for the name, number of arguments and encoding, then add a
** new entry to the hash table and return it.
*/
| | | 86424 86425 86426 86427 86428 86429 86430 86431 86432 86433 86434 86435 86436 86437 86438 |
}
}
/* If the createFlag parameter is true and the search did not reveal an
** exact match for the name, number of arguments and encoding, then add a
** new entry to the hash table and return it.
*/
if( createFlag && bestScore<FUNC_PERFECT_MATCH &&
(pBest = sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){
pBest->zName = (char *)&pBest[1];
pBest->nArg = (u16)nArg;
pBest->iPrefEnc = enc;
memcpy(pBest->zName, zName, nName);
pBest->zName[nName] = 0;
sqlite3FuncDefInsert(&db->aFunc, pBest);
|
| ︙ | ︙ | |||
92353 92354 92355 92356 92357 92358 92359 |
if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
"from within a transaction");
return SQLITE_ERROR;
}
sqlite3BtreeClose(db->aDb[1].pBt);
db->aDb[1].pBt = 0;
| | | 93221 93222 93223 93224 93225 93226 93227 93228 93229 93230 93231 93232 93233 93234 93235 |
if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
"from within a transaction");
return SQLITE_ERROR;
}
sqlite3BtreeClose(db->aDb[1].pBt);
db->aDb[1].pBt = 0;
sqlite3ResetAllSchemasOfConnection(db);
}
return SQLITE_OK;
}
#endif /* SQLITE_PAGER_PRAGMAS */
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
/*
|
| ︙ | ︙ | |||
93038 93039 93040 93041 93042 93043 93044 93045 93046 93047 93048 93049 93050 93051 |
sqlite3_temp_directory = sqlite3_mprintf("%s", zRight);
}else{
sqlite3_temp_directory = 0;
}
#endif /* SQLITE_OMIT_WSD */
}
}else
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
# if defined(__APPLE__)
# define SQLITE_ENABLE_LOCKING_STYLE 1
# else
# define SQLITE_ENABLE_LOCKING_STYLE 0
# endif
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 93906 93907 93908 93909 93910 93911 93912 93913 93914 93915 93916 93917 93918 93919 93920 93921 93922 93923 93924 93925 93926 93927 93928 93929 93930 93931 93932 93933 93934 93935 93936 93937 93938 93939 93940 93941 93942 93943 93944 93945 93946 93947 93948 93949 93950 93951 93952 93953 93954 93955 93956 93957 93958 93959 93960 93961 93962 93963 |
sqlite3_temp_directory = sqlite3_mprintf("%s", zRight);
}else{
sqlite3_temp_directory = 0;
}
#endif /* SQLITE_OMIT_WSD */
}
}else
#if SQLITE_OS_WIN
/*
** PRAGMA data_store_directory
** PRAGMA data_store_directory = ""|"directory_name"
**
** Return or set the local value of the data_store_directory flag. Changing
** the value sets a specific directory to be used for database files that
** were specified with a relative pathname. Setting to a null string reverts
** to the default database directory, which for database files specified with
** a relative path will probably be based on the current directory for the
** process. Database file specified with an absolute path are not impacted
** by this setting, regardless of its value.
**
*/
if( sqlite3StrICmp(zLeft, "data_store_directory")==0 ){
if( !zRight ){
if( sqlite3_data_directory ){
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME,
"data_store_directory", SQLITE_STATIC);
sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, sqlite3_data_directory, 0);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
}
}else{
#ifndef SQLITE_OMIT_WSD
if( zRight[0] ){
int res;
rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
if( rc!=SQLITE_OK || res==0 ){
sqlite3ErrorMsg(pParse, "not a writable directory");
goto pragma_out;
}
}
sqlite3_free(sqlite3_data_directory);
if( zRight[0] ){
sqlite3_data_directory = sqlite3_mprintf("%s", zRight);
}else{
sqlite3_data_directory = 0;
}
#endif /* SQLITE_OMIT_WSD */
}
}else
#endif
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
# if defined(__APPLE__)
# define SQLITE_ENABLE_LOCKING_STYLE 1
# else
# define SQLITE_ENABLE_LOCKING_STYLE 0
# endif
|
| ︙ | ︙ | |||
94071 94072 94073 94074 94075 94076 94077 |
if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
if( iDb==0 ){
u8 encoding;
/* If opening the main database, set ENC(db). */
encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
if( encoding==0 ) encoding = SQLITE_UTF8;
ENC(db) = encoding;
| < | 94983 94984 94985 94986 94987 94988 94989 94990 94991 94992 94993 94994 94995 94996 |
if( meta[BTREE_TEXT_ENCODING-1] ){ /* text encoding */
if( iDb==0 ){
u8 encoding;
/* If opening the main database, set ENC(db). */
encoding = (u8)meta[BTREE_TEXT_ENCODING-1] & 3;
if( encoding==0 ) encoding = SQLITE_UTF8;
ENC(db) = encoding;
}else{
/* If opening an attached database, the encoding much match ENC(db) */
if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){
sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
" text encoding as main database");
rc = SQLITE_ERROR;
goto initone_error_out;
|
| ︙ | ︙ | |||
94151 94152 94153 94154 94155 94156 94157 |
if( rc==SQLITE_OK ){
sqlite3AnalysisLoad(db, iDb);
}
#endif
}
if( db->mallocFailed ){
rc = SQLITE_NOMEM;
| | | 95062 95063 95064 95065 95066 95067 95068 95069 95070 95071 95072 95073 95074 95075 95076 |
if( rc==SQLITE_OK ){
sqlite3AnalysisLoad(db, iDb);
}
#endif
}
if( db->mallocFailed ){
rc = SQLITE_NOMEM;
sqlite3ResetAllSchemasOfConnection(db);
}
if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
/* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
** the schema loaded, even if errors occurred. In this situation the
** current sqlite3_prepare() operation will fail, but the following one
** will attempt to compile the supplied statement against whatever subset
** of the schema was loaded before the error occurred. The primary
|
| ︙ | ︙ | |||
94204 94205 94206 94207 94208 94209 94210 |
assert( sqlite3_mutex_held(db->mutex) );
rc = SQLITE_OK;
db->init.busy = 1;
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
rc = sqlite3InitOne(db, i, pzErrMsg);
if( rc ){
| | | | 95115 95116 95117 95118 95119 95120 95121 95122 95123 95124 95125 95126 95127 95128 95129 95130 95131 95132 95133 95134 95135 95136 95137 95138 95139 95140 95141 95142 |
assert( sqlite3_mutex_held(db->mutex) );
rc = SQLITE_OK;
db->init.busy = 1;
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
rc = sqlite3InitOne(db, i, pzErrMsg);
if( rc ){
sqlite3ResetOneSchema(db, i);
}
}
/* Once all the other databases have been initialised, load the schema
** for the TEMP database. This is loaded last, as the TEMP database
** schema may contain references to objects in other databases.
*/
#ifndef SQLITE_OMIT_TEMPDB
if( rc==SQLITE_OK && ALWAYS(db->nDb>1)
&& !DbHasProperty(db, 1, DB_SchemaLoaded) ){
rc = sqlite3InitOne(db, 1, pzErrMsg);
if( rc ){
sqlite3ResetOneSchema(db, 1);
}
}
#endif
db->init.busy = 0;
if( rc==SQLITE_OK && commit_internal ){
sqlite3CommitInternalChanges(db);
|
| ︙ | ︙ | |||
94285 94286 94287 94288 94289 94290 94291 |
/* Read the schema cookie from the database. If it does not match the
** value stored as part of the in-memory schema representation,
** set Parse.rc to SQLITE_SCHEMA. */
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
| | | 95196 95197 95198 95199 95200 95201 95202 95203 95204 95205 95206 95207 95208 95209 95210 |
/* Read the schema cookie from the database. If it does not match the
** value stored as part of the in-memory schema representation,
** set Parse.rc to SQLITE_SCHEMA. */
sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
sqlite3ResetOneSchema(db, iDb);
pParse->rc = SQLITE_SCHEMA;
}
/* Close the transaction, if one was opened. */
if( openedTransaction ){
sqlite3BtreeCommit(pBt);
}
|
| ︙ | ︙ | |||
94515 94516 94517 94518 94519 94520 94521 94522 94523 94524 94525 94526 94527 94528 |
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
if( rc==SQLITE_SCHEMA ){
sqlite3_finalize(*ppStmt);
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
}
sqlite3BtreeLeaveAll(db);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** Rerun the compilation of a statement after a schema change.
**
** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
| > | 95426 95427 95428 95429 95430 95431 95432 95433 95434 95435 95436 95437 95438 95439 95440 |
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
if( rc==SQLITE_SCHEMA ){
sqlite3_finalize(*ppStmt);
rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, pOld, ppStmt, pzTail);
}
sqlite3BtreeLeaveAll(db);
sqlite3_mutex_leave(db->mutex);
assert( rc==SQLITE_OK || *ppStmt==0 );
return rc;
}
/*
** Rerun the compilation of a statement after a schema change.
**
** If the statement is successfully recompiled, return SQLITE_OK. Otherwise,
|
| ︙ | ︙ | |||
97524 97525 97526 97527 97528 97529 97530 |
}
}
/***** If we reach this point, flattening is permitted. *****/
/* Authorize the subquery */
pParse->zAuthContext = pSubitem->zName;
| | > | 98436 98437 98438 98439 98440 98441 98442 98443 98444 98445 98446 98447 98448 98449 98450 98451 |
}
}
/***** If we reach this point, flattening is permitted. *****/
/* Authorize the subquery */
pParse->zAuthContext = pSubitem->zName;
TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
testcase( i==SQLITE_DENY );
pParse->zAuthContext = zSavedAuthContext;
/* If the sub-query is a compound SELECT statement, then (by restrictions
** 17 and 18 above) it must be a UNION ALL and the parent query must
** be of the form:
**
** SELECT <expr-list> FROM (<sub-query>) <where-clause>
|
| ︙ | ︙ | |||
97821 97822 97823 97824 97825 97826 97827 97828 97829 97830 97831 97832 97833 97834 | } pTab = p->pSrc->a[0].pTab; pExpr = p->pEList->a[0].pExpr; assert( pTab && !pTab->pSelect && pExpr ); if( IsVirtual(pTab) ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; if( pExpr->flags&EP_Distinct ) return 0; return pTab; } /* | > | 98734 98735 98736 98737 98738 98739 98740 98741 98742 98743 98744 98745 98746 98747 98748 | } pTab = p->pSrc->a[0].pTab; pExpr = p->pEList->a[0].pExpr; assert( pTab && !pTab->pSelect && pExpr ); if( IsVirtual(pTab) ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; if( pAggInfo->nFunc==0 ) return 0; if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; if( pExpr->flags&EP_Distinct ) return 0; return pTab; } /* |
| ︙ | ︙ | |||
98811 98812 98813 98814 98815 98816 98817 98818 98819 98820 98821 98822 98823 98824 98825 |
sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
if( pHaving ){
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; i<sAggInfo.nFunc; i++){
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
}
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
** much more complex than aggregates without a GROUP BY.
*/
if( pGroupBy ){
| > > | 99725 99726 99727 99728 99729 99730 99731 99732 99733 99734 99735 99736 99737 99738 99739 99740 99741 |
sqlite3ExprAnalyzeAggList(&sNC, pOrderBy);
if( pHaving ){
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; i<sAggInfo.nFunc; i++){
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
sNC.ncFlags |= NC_InAggFunc;
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
sNC.ncFlags &= ~NC_InAggFunc;
}
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
** much more complex than aggregates without a GROUP BY.
*/
if( pGroupBy ){
|
| ︙ | ︙ | |||
101633 101634 101635 101636 101637 101638 101639 |
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
}
/* This both clears the schemas and reduces the size of the db->aDb[]
** array. */
| | | 102549 102550 102551 102552 102553 102554 102555 102556 102557 102558 102559 102560 102561 102562 102563 |
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
pDb->pSchema = 0;
}
/* This both clears the schemas and reduces the size of the db->aDb[]
** array. */
sqlite3ResetAllSchemasOfConnection(db);
return rc;
}
#endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */
/************** End of vacuum.c **********************************************/
|
| ︙ | ︙ | |||
101665 101666 101667 101668 101669 101670 101671 |
** Before a virtual table xCreate() or xConnect() method is invoked, the
** sqlite3.pVtabCtx member variable is set to point to an instance of
** this struct allocated on the stack. It is used by the implementation of
** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
** are invoked only from within xCreate and xConnect methods.
*/
struct VtabCtx {
| < | > > | < > > > > | | | | | | | | | | | < < < < | | > | < < | > | > > | 102581 102582 102583 102584 102585 102586 102587 102588 102589 102590 102591 102592 102593 102594 102595 102596 102597 102598 102599 102600 102601 102602 102603 102604 102605 102606 102607 102608 102609 102610 102611 102612 102613 102614 102615 102616 102617 102618 102619 102620 102621 102622 102623 102624 102625 102626 102627 102628 102629 102630 102631 102632 102633 102634 102635 102636 102637 102638 102639 |
** Before a virtual table xCreate() or xConnect() method is invoked, the
** sqlite3.pVtabCtx member variable is set to point to an instance of
** this struct allocated on the stack. It is used by the implementation of
** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
** are invoked only from within xCreate and xConnect methods.
*/
struct VtabCtx {
VTable *pVTable; /* The virtual table being constructed */
Table *pTab; /* The Table object to which the virtual table belongs */
};
/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
** sqlite3_create_module_v2() interfaces.
*/
static int createModule(
sqlite3 *db, /* Database in which module is registered */
const char *zName, /* Name assigned to this module */
const sqlite3_module *pModule, /* The definition of the module */
void *pAux, /* Context pointer for xCreate/xConnect */
void (*xDestroy)(void *) /* Module destructor function */
){
int rc = SQLITE_OK;
int nName;
sqlite3_mutex_enter(db->mutex);
nName = sqlite3Strlen30(zName);
if( sqlite3HashFind(&db->aModule, zName, nName) ){
rc = SQLITE_MISUSE_BKPT;
}else{
Module *pMod;
pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
if( pMod ){
Module *pDel;
char *zCopy = (char *)(&pMod[1]);
memcpy(zCopy, zName, nName+1);
pMod->zName = zCopy;
pMod->pModule = pModule;
pMod->pAux = pAux;
pMod->xDestroy = xDestroy;
pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod);
assert( pDel==0 || pDel==pMod );
if( pDel ){
db->mallocFailed = 1;
sqlite3DbFree(db, pDel);
}
}
}
rc = sqlite3ApiExit(db, rc);
if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** External API function used to create a new virtual-table module.
|
| ︙ | ︙ | |||
101822 101823 101824 101825 101826 101827 101828 101829 101830 101831 101832 101833 101834 101835 |
}
pVTable = pNext;
}
assert( !db || pRet );
return pRet;
}
/*
** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
**
** This function may only be called when the mutexes associated with all
** shared b-tree databases opened using connection db are held by the
| > > > > > > > > > > > > > > > > > > > > > > > > > | 102740 102741 102742 102743 102744 102745 102746 102747 102748 102749 102750 102751 102752 102753 102754 102755 102756 102757 102758 102759 102760 102761 102762 102763 102764 102765 102766 102767 102768 102769 102770 102771 102772 102773 102774 102775 102776 102777 102778 |
}
pVTable = pNext;
}
assert( !db || pRet );
return pRet;
}
/*
** Table *p is a virtual table. This function removes the VTable object
** for table *p associated with database connection db from the linked
** list in p->pVTab. It also decrements the VTable ref count. This is
** used when closing database connection db to free all of its VTable
** objects without disturbing the rest of the Schema object (which may
** be being used by other shared-cache connections).
*/
SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){
VTable **ppVTab;
assert( IsVirtual(p) );
assert( sqlite3BtreeHoldsAllMutexes(db) );
assert( sqlite3_mutex_held(db->mutex) );
for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){
if( (*ppVTab)->db==db ){
VTable *pVTab = *ppVTab;
*ppVTab = pVTab->pNext;
sqlite3VtabUnlock(pVTab);
break;
}
}
}
/*
** Disconnect all the virtual table objects in the sqlite3.pDisconnect list.
**
** This function may only be called when the mutexes associated with all
** shared b-tree databases opened using connection db are held by the
|
| ︙ | ︙ | |||
102090 102091 102092 102093 102094 102095 102096 |
static int vtabCallConstructor(
sqlite3 *db,
Table *pTab,
Module *pMod,
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
| | | 103033 103034 103035 103036 103037 103038 103039 103040 103041 103042 103043 103044 103045 103046 103047 |
static int vtabCallConstructor(
sqlite3 *db,
Table *pTab,
Module *pMod,
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
VtabCtx sCtx, *pPriorCtx;
VTable *pVTable;
int rc;
const char *const*azArg = (const char *const*)pTab->azModuleArg;
int nArg = pTab->nModuleArg;
char *zErr = 0;
char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
|
| ︙ | ︙ | |||
102115 102116 102117 102118 102119 102120 102121 102122 102123 | pVTable->pMod = pMod; /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); assert( xConstruct ); sCtx.pTab = pTab; sCtx.pVTable = pVTable; db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); | > | | 103058 103059 103060 103061 103062 103063 103064 103065 103066 103067 103068 103069 103070 103071 103072 103073 103074 103075 |
pVTable->pMod = pMod;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
assert( xConstruct );
sCtx.pTab = pTab;
sCtx.pVTable = pVTable;
pPriorCtx = db->pVtabCtx;
db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
db->pVtabCtx = pPriorCtx;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
if( SQLITE_OK!=rc ){
if( zErr==0 ){
*pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName);
}else {
*pzErr = sqlite3MPrintf(db, "%s", zErr);
|
| ︙ | ︙ | |||
104274 104275 104276 104277 104278 104279 104280 104281 104282 104283 104284 104285 |
**
** 1. The index is itself UNIQUE, and
**
** 2. All of the columns in the index are either part of the pDistinct
** list, or else the WHERE clause contains a term of the form "col=X",
** where X is a constant value. The collation sequences of the
** comparison and select-list expressions must match those of the index.
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None ) continue;
for(i=0; i<pIdx->nColumn; i++){
int iCol = pIdx->aiColumn[i];
| > > > | | | | > | 105218 105219 105220 105221 105222 105223 105224 105225 105226 105227 105228 105229 105230 105231 105232 105233 105234 105235 105236 105237 105238 105239 105240 105241 105242 105243 105244 |
**
** 1. The index is itself UNIQUE, and
**
** 2. All of the columns in the index are either part of the pDistinct
** list, or else the WHERE clause contains a term of the form "col=X",
** where X is a constant value. The collation sequences of the
** comparison and select-list expressions must match those of the index.
**
** 3. All of those index columns for which the WHERE clause does not
** contain a "col=X" term are subject to a NOT NULL constraint.
*/
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
if( pIdx->onError==OE_None ) continue;
for(i=0; i<pIdx->nColumn; i++){
int iCol = pIdx->aiColumn[i];
if( 0==findTerm(pWC, iBase, iCol, ~(Bitmask)0, WO_EQ, pIdx) ){
int iIdxCol = findIndexCol(pParse, pDistinct, iBase, pIdx, i);
if( iIdxCol<0 || pTab->aCol[pIdx->aiColumn[i]].notNull==0 ){
break;
}
}
}
if( i==pIdx->nColumn ){
/* This index implies that the DISTINCT qualifier is redundant. */
return 1;
}
}
|
| ︙ | ︙ | |||
104430 104431 104432 104433 104434 104435 104436 |
if( j>=nTerm ){
/* All terms of the ORDER BY clause are covered by this index so
** this index can be used for sorting. */
return 1;
}
if( pIdx->onError!=OE_None && i==pIdx->nColumn
&& (wsFlags & WHERE_COLUMN_NULL)==0
| | > > > | | | > | > | > > > | > > > | | 105378 105379 105380 105381 105382 105383 105384 105385 105386 105387 105388 105389 105390 105391 105392 105393 105394 105395 105396 105397 105398 105399 105400 105401 105402 105403 105404 105405 105406 105407 105408 105409 105410 |
if( j>=nTerm ){
/* All terms of the ORDER BY clause are covered by this index so
** this index can be used for sorting. */
return 1;
}
if( pIdx->onError!=OE_None && i==pIdx->nColumn
&& (wsFlags & WHERE_COLUMN_NULL)==0
&& !referencesOtherTables(pOrderBy, pMaskSet, j, base)
){
Column *aCol = pIdx->pTable->aCol;
/* All terms of this index match some prefix of the ORDER BY clause,
** the index is UNIQUE, and no terms on the tail of the ORDER BY
** refer to other tables in a join. So, assuming that the index entries
** visited contain no NULL values, then this index delivers rows in
** the required order.
**
** It is not possible for any of the first nEqCol index fields to be
** NULL (since the corresponding "=" operator in the WHERE clause would
** not be true). So if all remaining index columns have NOT NULL
** constaints attached to them, we can be confident that the visited
** index entries are free of NULLs. */
for(i=nEqCol; i<pIdx->nColumn; i++){
if( aCol[pIdx->aiColumn[i]].notNull==0 ) break;
}
return (i==pIdx->nColumn);
}
return 0;
}
/*
** Prepare a crude estimate of the logarithm of the input value.
** The results need not be exact. This is only used for estimating
|
| ︙ | ︙ | |||
108191 108192 108193 108194 108195 108196 108197 | #define YYSTACKDEPTH 100 #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse #define YYNSTATE 627 | | | 109150 109151 109152 109153 109154 109155 109156 109157 109158 109159 109160 109161 109162 109163 109164 | #define YYSTACKDEPTH 100 #endif #define sqlite3ParserARG_SDECL Parse *pParse; #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse #define YYNSTATE 627 #define YYNRULE 327 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) #define YY_ERROR_ACTION (YYNSTATE+YYNRULE) /* The yyzerominor constant is used to initialize instances of ** YYMINORTYPE objects to zero. */ |
| ︙ | ︙ | |||
108261 108262 108263 108264 108265 108266 108267 | ** yy_action. Used to detect hash collisions. ** yy_shift_ofst[] For each state, the offset into yy_action for ** shifting terminals. ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 109220 109221 109222 109223 109224 109225 109226 109227 109228 109229 109230 109231 109232 109233 109234 109235 109236 109237 109238 109239 109240 109241 109242 109243 109244 109245 109246 109247 109248 109249 109250 109251 109252 109253 109254 109255 109256 109257 109258 109259 109260 109261 109262 109263 109264 109265 109266 109267 109268 109269 109270 109271 109272 109273 109274 109275 109276 109277 109278 109279 109280 109281 109282 109283 109284 109285 109286 109287 109288 109289 109290 109291 109292 109293 109294 109295 109296 109297 109298 109299 109300 109301 109302 109303 109304 109305 109306 109307 109308 109309 109310 109311 109312 109313 109314 109315 109316 109317 109318 109319 109320 109321 109322 109323 109324 109325 109326 109327 109328 109329 109330 109331 109332 109333 109334 109335 109336 109337 109338 109339 109340 109341 109342 109343 109344 109345 109346 109347 109348 109349 109350 109351 109352 109353 109354 109355 109356 109357 109358 109359 109360 109361 109362 109363 109364 109365 109366 109367 109368 109369 109370 109371 109372 109373 109374 109375 109376 109377 109378 109379 109380 109381 109382 109383 109384 109385 109386 109387 109388 109389 109390 109391 109392 109393 109394 109395 109396 109397 109398 109399 109400 109401 109402 109403 109404 109405 109406 109407 109408 109409 109410 109411 109412 109413 109414 109415 109416 109417 109418 109419 109420 109421 109422 109423 109424 109425 109426 109427 109428 109429 109430 109431 109432 109433 109434 109435 109436 109437 109438 109439 109440 109441 109442 109443 109444 109445 109446 109447 109448 109449 109450 109451 109452 109453 109454 109455 109456 109457 109458 109459 109460 109461 109462 109463 109464 109465 109466 109467 109468 109469 109470 109471 109472 109473 109474 109475 109476 109477 109478 109479 109480 109481 109482 109483 109484 109485 109486 109487 109488 109489 109490 109491 109492 109493 109494 109495 109496 109497 109498 109499 109500 109501 109502 109503 109504 109505 109506 109507 109508 109509 109510 109511 109512 109513 109514 109515 109516 109517 109518 109519 109520 109521 109522 109523 109524 109525 109526 109527 109528 109529 109530 109531 109532 109533 109534 109535 109536 109537 109538 109539 109540 109541 109542 109543 109544 109545 109546 109547 109548 109549 109550 109551 109552 109553 109554 109555 109556 109557 109558 109559 109560 109561 109562 109563 109564 109565 109566 109567 109568 109569 109570 109571 109572 109573 109574 109575 109576 109577 109578 109579 109580 109581 109582 109583 109584 109585 109586 109587 109588 109589 109590 109591 109592 109593 109594 109595 109596 109597 109598 109599 109600 109601 109602 109603 109604 109605 109606 109607 109608 109609 109610 109611 109612 109613 109614 109615 109616 109617 109618 109619 109620 109621 109622 109623 109624 109625 109626 109627 109628 109629 109630 109631 109632 109633 109634 109635 109636 109637 109638 109639 109640 109641 109642 109643 109644 109645 109646 109647 109648 109649 109650 109651 109652 109653 109654 109655 109656 109657 109658 109659 109660 109661 109662 109663 109664 109665 109666 109667 109668 109669 109670 109671 109672 109673 109674 109675 109676 109677 109678 109679 109680 109681 109682 109683 109684 109685 109686 109687 109688 109689 109690 109691 109692 109693 109694 109695 109696 109697 109698 109699 |
** yy_action. Used to detect hash collisions.
** yy_shift_ofst[] For each state, the offset into yy_action for
** shifting terminals.
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
#define YY_ACTTAB_COUNT (1564)
static const YYACTIONTYPE yy_action[] = {
/* 0 */ 309, 955, 184, 417, 2, 171, 624, 594, 56, 56,
/* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
/* 20 */ 52, 52, 51, 233, 620, 619, 298, 620, 619, 234,
/* 30 */ 587, 581, 56, 56, 56, 56, 19, 54, 54, 54,
/* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 605, 57,
/* 50 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
/* 60 */ 56, 56, 541, 54, 54, 54, 54, 53, 53, 52,
/* 70 */ 52, 52, 51, 233, 309, 594, 325, 196, 195, 194,
/* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 90 */ 51, 233, 617, 616, 165, 617, 616, 380, 377, 376,
/* 100 */ 407, 532, 576, 576, 587, 581, 303, 422, 375, 59,
/* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
/* 120 */ 574, 545, 65, 57, 58, 48, 579, 578, 580, 580,
/* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
/* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 223,
/* 150 */ 539, 420, 170, 176, 138, 280, 383, 275, 382, 168,
/* 160 */ 489, 551, 409, 668, 620, 619, 271, 438, 409, 438,
/* 170 */ 550, 604, 67, 482, 507, 618, 599, 412, 587, 581,
/* 180 */ 600, 483, 618, 412, 618, 598, 91, 439, 440, 439,
/* 190 */ 335, 598, 73, 669, 222, 266, 480, 57, 58, 48,
/* 200 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
/* 210 */ 670, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 220 */ 51, 233, 309, 279, 232, 231, 1, 132, 200, 385,
/* 230 */ 620, 619, 617, 616, 278, 435, 289, 563, 175, 262,
/* 240 */ 409, 264, 437, 497, 436, 166, 441, 568, 336, 568,
/* 250 */ 201, 537, 587, 581, 599, 412, 165, 594, 600, 380,
/* 260 */ 377, 376, 597, 598, 92, 523, 618, 569, 569, 592,
/* 270 */ 375, 57, 58, 48, 579, 578, 580, 580, 55, 55,
/* 280 */ 56, 56, 56, 56, 597, 54, 54, 54, 54, 53,
/* 290 */ 53, 52, 52, 52, 51, 233, 309, 463, 617, 616,
/* 300 */ 590, 590, 590, 174, 272, 396, 409, 272, 409, 548,
/* 310 */ 397, 620, 619, 68, 326, 620, 619, 620, 619, 618,
/* 320 */ 546, 412, 618, 412, 471, 594, 587, 581, 472, 598,
/* 330 */ 92, 598, 92, 52, 52, 52, 51, 233, 513, 512,
/* 340 */ 206, 322, 363, 464, 221, 57, 58, 48, 579, 578,
/* 350 */ 580, 580, 55, 55, 56, 56, 56, 56, 529, 54,
/* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 370 */ 309, 396, 409, 396, 597, 372, 386, 530, 347, 617,
/* 380 */ 616, 575, 202, 617, 616, 617, 616, 412, 620, 619,
/* 390 */ 145, 255, 346, 254, 577, 598, 74, 351, 45, 489,
/* 400 */ 587, 581, 235, 189, 464, 544, 167, 296, 187, 469,
/* 410 */ 479, 67, 62, 39, 618, 546, 597, 345, 573, 57,
/* 420 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
/* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
/* 440 */ 52, 52, 51, 233, 309, 562, 558, 407, 528, 576,
/* 450 */ 576, 344, 255, 346, 254, 182, 617, 616, 503, 504,
/* 460 */ 314, 409, 557, 235, 166, 271, 409, 352, 564, 181,
/* 470 */ 407, 546, 576, 576, 587, 581, 412, 537, 556, 561,
/* 480 */ 517, 412, 618, 249, 598, 16, 7, 36, 467, 598,
/* 490 */ 92, 516, 618, 57, 58, 48, 579, 578, 580, 580,
/* 500 */ 55, 55, 56, 56, 56, 56, 541, 54, 54, 54,
/* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 327,
/* 520 */ 572, 571, 525, 558, 560, 394, 871, 246, 409, 248,
/* 530 */ 171, 392, 594, 219, 407, 409, 576, 576, 502, 557,
/* 540 */ 364, 145, 510, 412, 407, 229, 576, 576, 587, 581,
/* 550 */ 412, 598, 92, 381, 269, 556, 166, 400, 598, 69,
/* 560 */ 501, 419, 945, 199, 945, 198, 546, 57, 58, 48,
/* 570 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
/* 580 */ 568, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 590 */ 51, 233, 309, 317, 419, 944, 508, 944, 308, 597,
/* 600 */ 594, 565, 490, 212, 173, 247, 423, 615, 614, 613,
/* 610 */ 323, 197, 143, 405, 572, 571, 489, 66, 50, 47,
/* 620 */ 146, 594, 587, 581, 232, 231, 559, 427, 67, 555,
/* 630 */ 15, 618, 186, 543, 303, 421, 35, 206, 432, 423,
/* 640 */ 552, 57, 58, 48, 579, 578, 580, 580, 55, 55,
/* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
/* 660 */ 53, 52, 52, 52, 51, 233, 309, 569, 569, 260,
/* 670 */ 268, 597, 12, 373, 568, 166, 409, 313, 409, 420,
/* 680 */ 409, 473, 473, 365, 618, 50, 47, 146, 597, 594,
/* 690 */ 468, 412, 166, 412, 351, 412, 587, 581, 32, 598,
/* 700 */ 94, 598, 97, 598, 95, 627, 625, 329, 142, 50,
/* 710 */ 47, 146, 333, 349, 358, 57, 58, 48, 579, 578,
/* 720 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
/* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 740 */ 309, 409, 388, 412, 409, 22, 565, 404, 212, 362,
/* 750 */ 389, 598, 104, 359, 409, 156, 412, 409, 603, 412,
/* 760 */ 537, 331, 569, 569, 598, 103, 493, 598, 105, 412,
/* 770 */ 587, 581, 412, 260, 549, 618, 11, 598, 106, 521,
/* 780 */ 598, 133, 169, 457, 456, 170, 35, 601, 618, 57,
/* 790 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
/* 800 */ 56, 56, 409, 54, 54, 54, 54, 53, 53, 52,
/* 810 */ 52, 52, 51, 233, 309, 409, 259, 412, 409, 50,
/* 820 */ 47, 146, 357, 318, 355, 598, 134, 527, 352, 337,
/* 830 */ 412, 409, 356, 412, 357, 409, 357, 618, 598, 98,
/* 840 */ 129, 598, 102, 618, 587, 581, 412, 21, 235, 618,
/* 850 */ 412, 618, 211, 143, 598, 101, 30, 167, 598, 93,
/* 860 */ 350, 535, 203, 57, 58, 48, 579, 578, 580, 580,
/* 870 */ 55, 55, 56, 56, 56, 56, 409, 54, 54, 54,
/* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 409,
/* 890 */ 526, 412, 409, 425, 215, 305, 597, 551, 141, 598,
/* 900 */ 100, 40, 409, 38, 412, 409, 550, 412, 409, 228,
/* 910 */ 220, 314, 598, 77, 500, 598, 96, 412, 587, 581,
/* 920 */ 412, 338, 253, 412, 218, 598, 137, 379, 598, 136,
/* 930 */ 28, 598, 135, 270, 715, 210, 481, 57, 58, 48,
/* 940 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
/* 950 */ 409, 54, 54, 54, 54, 53, 53, 52, 52, 52,
/* 960 */ 51, 233, 309, 409, 272, 412, 409, 315, 147, 597,
/* 970 */ 272, 626, 2, 598, 76, 209, 409, 127, 412, 618,
/* 980 */ 126, 412, 409, 621, 235, 618, 598, 90, 374, 598,
/* 990 */ 89, 412, 587, 581, 27, 260, 350, 412, 618, 598,
/* 1000 */ 75, 321, 541, 541, 125, 598, 88, 320, 278, 597,
/* 1010 */ 618, 57, 46, 48, 579, 578, 580, 580, 55, 55,
/* 1020 */ 56, 56, 56, 56, 409, 54, 54, 54, 54, 53,
/* 1030 */ 53, 52, 52, 52, 51, 233, 309, 409, 450, 412,
/* 1040 */ 164, 284, 282, 272, 609, 424, 304, 598, 87, 370,
/* 1050 */ 409, 477, 412, 409, 608, 409, 607, 602, 618, 618,
/* 1060 */ 598, 99, 586, 585, 122, 412, 587, 581, 412, 618,
/* 1070 */ 412, 618, 618, 598, 86, 366, 598, 17, 598, 85,
/* 1080 */ 319, 185, 519, 518, 583, 582, 58, 48, 579, 578,
/* 1090 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
/* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
/* 1110 */ 309, 584, 409, 412, 409, 260, 260, 260, 408, 591,
/* 1120 */ 474, 598, 84, 170, 409, 466, 518, 412, 121, 412,
/* 1130 */ 618, 618, 618, 618, 618, 598, 83, 598, 72, 412,
/* 1140 */ 587, 581, 51, 233, 625, 329, 470, 598, 71, 257,
/* 1150 */ 159, 120, 14, 462, 157, 158, 117, 260, 448, 447,
/* 1160 */ 446, 48, 579, 578, 580, 580, 55, 55, 56, 56,
/* 1170 */ 56, 56, 618, 54, 54, 54, 54, 53, 53, 52,
/* 1180 */ 52, 52, 51, 233, 44, 403, 260, 3, 409, 459,
/* 1190 */ 260, 413, 619, 118, 398, 10, 25, 24, 554, 348,
/* 1200 */ 217, 618, 406, 412, 409, 618, 4, 44, 403, 618,
/* 1210 */ 3, 598, 82, 618, 413, 619, 455, 542, 115, 412,
/* 1220 */ 538, 401, 536, 274, 506, 406, 251, 598, 81, 216,
/* 1230 */ 273, 563, 618, 243, 453, 618, 154, 618, 618, 618,
/* 1240 */ 449, 416, 623, 110, 401, 618, 409, 236, 64, 123,
/* 1250 */ 487, 41, 42, 531, 563, 204, 409, 267, 43, 411,
/* 1260 */ 410, 412, 265, 592, 108, 618, 107, 434, 332, 598,
/* 1270 */ 80, 412, 618, 263, 41, 42, 443, 618, 409, 598,
/* 1280 */ 70, 43, 411, 410, 433, 261, 592, 149, 618, 597,
/* 1290 */ 256, 237, 188, 412, 590, 590, 590, 589, 588, 13,
/* 1300 */ 618, 598, 18, 328, 235, 618, 44, 403, 360, 3,
/* 1310 */ 418, 461, 339, 413, 619, 227, 124, 590, 590, 590,
/* 1320 */ 589, 588, 13, 618, 406, 409, 618, 409, 139, 34,
/* 1330 */ 403, 387, 3, 148, 622, 312, 413, 619, 311, 330,
/* 1340 */ 412, 460, 412, 401, 180, 353, 412, 406, 598, 79,
/* 1350 */ 598, 78, 250, 563, 598, 9, 618, 612, 611, 610,
/* 1360 */ 618, 8, 452, 442, 242, 415, 401, 618, 239, 235,
/* 1370 */ 179, 238, 428, 41, 42, 288, 563, 618, 618, 618,
/* 1380 */ 43, 411, 410, 618, 144, 592, 618, 618, 177, 61,
/* 1390 */ 618, 596, 391, 620, 619, 287, 41, 42, 414, 618,
/* 1400 */ 293, 30, 393, 43, 411, 410, 292, 618, 592, 31,
/* 1410 */ 618, 395, 291, 60, 230, 37, 590, 590, 590, 589,
/* 1420 */ 588, 13, 214, 553, 183, 290, 172, 301, 300, 299,
/* 1430 */ 178, 297, 595, 563, 451, 29, 285, 390, 540, 590,
/* 1440 */ 590, 590, 589, 588, 13, 283, 520, 534, 150, 533,
/* 1450 */ 241, 281, 384, 192, 191, 324, 515, 514, 276, 240,
/* 1460 */ 510, 523, 307, 511, 128, 592, 509, 225, 226, 486,
/* 1470 */ 485, 224, 152, 491, 464, 306, 484, 163, 153, 371,
/* 1480 */ 478, 151, 162, 258, 369, 161, 367, 208, 475, 476,
/* 1490 */ 26, 160, 465, 140, 361, 131, 590, 590, 590, 116,
/* 1500 */ 119, 454, 343, 155, 114, 342, 113, 112, 445, 111,
/* 1510 */ 130, 109, 431, 316, 426, 430, 23, 429, 20, 606,
/* 1520 */ 190, 507, 255, 341, 244, 63, 294, 593, 310, 570,
/* 1530 */ 277, 402, 354, 235, 567, 496, 495, 492, 494, 302,
/* 1540 */ 458, 378, 286, 245, 566, 5, 252, 547, 193, 444,
/* 1550 */ 233, 340, 207, 524, 368, 505, 334, 522, 499, 399,
/* 1560 */ 295, 498, 956, 488,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
/* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
/* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
/* 30 */ 49, 50, 77, 78, 79, 80, 204, 82, 83, 84,
/* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 23, 68,
/* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 60 */ 79, 80, 166, 82, 83, 84, 85, 86, 87, 88,
/* 70 */ 89, 90, 91, 92, 19, 94, 19, 105, 106, 107,
/* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 90 */ 91, 92, 94, 95, 96, 94, 95, 99, 100, 101,
/* 100 */ 112, 205, 114, 115, 49, 50, 22, 23, 110, 54,
/* 110 */ 86, 87, 88, 89, 90, 91, 92, 221, 222, 223,
/* 120 */ 23, 120, 25, 68, 69, 70, 71, 72, 73, 74,
/* 130 */ 75, 76, 77, 78, 79, 80, 22, 82, 83, 84,
/* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 92,
/* 150 */ 23, 67, 25, 96, 97, 98, 99, 100, 101, 102,
/* 160 */ 150, 32, 150, 118, 26, 27, 109, 150, 150, 150,
/* 170 */ 41, 161, 162, 180, 181, 165, 113, 165, 49, 50,
/* 180 */ 117, 188, 165, 165, 165, 173, 174, 170, 171, 170,
/* 190 */ 171, 173, 174, 118, 184, 16, 186, 68, 69, 70,
/* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
/* 210 */ 118, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 220 */ 91, 92, 19, 98, 86, 87, 22, 24, 160, 88,
/* 230 */ 26, 27, 94, 95, 109, 97, 224, 66, 118, 60,
/* 240 */ 150, 62, 104, 23, 106, 25, 229, 230, 229, 230,
/* 250 */ 160, 150, 49, 50, 113, 165, 96, 26, 117, 99,
/* 260 */ 100, 101, 194, 173, 174, 94, 165, 129, 130, 98,
/* 270 */ 110, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 280 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86,
/* 290 */ 87, 88, 89, 90, 91, 92, 19, 11, 94, 95,
/* 300 */ 129, 130, 131, 118, 150, 215, 150, 150, 150, 25,
/* 310 */ 220, 26, 27, 22, 213, 26, 27, 26, 27, 165,
/* 320 */ 25, 165, 165, 165, 30, 94, 49, 50, 34, 173,
/* 330 */ 174, 173, 174, 88, 89, 90, 91, 92, 7, 8,
/* 340 */ 160, 187, 48, 57, 187, 68, 69, 70, 71, 72,
/* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 23, 82,
/* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
/* 370 */ 19, 215, 150, 215, 194, 19, 220, 88, 220, 94,
/* 380 */ 95, 23, 160, 94, 95, 94, 95, 165, 26, 27,
/* 390 */ 95, 105, 106, 107, 113, 173, 174, 217, 22, 150,
/* 400 */ 49, 50, 116, 119, 57, 120, 50, 158, 22, 21,
/* 410 */ 161, 162, 232, 136, 165, 120, 194, 237, 23, 68,
/* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 430 */ 79, 80, 22, 82, 83, 84, 85, 86, 87, 88,
/* 440 */ 89, 90, 91, 92, 19, 23, 12, 112, 23, 114,
/* 450 */ 115, 63, 105, 106, 107, 23, 94, 95, 97, 98,
/* 460 */ 104, 150, 28, 116, 25, 109, 150, 150, 23, 23,
/* 470 */ 112, 25, 114, 115, 49, 50, 165, 150, 44, 11,
/* 480 */ 46, 165, 165, 16, 173, 174, 76, 136, 100, 173,
/* 490 */ 174, 57, 165, 68, 69, 70, 71, 72, 73, 74,
/* 500 */ 75, 76, 77, 78, 79, 80, 166, 82, 83, 84,
/* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 169,
/* 520 */ 170, 171, 23, 12, 23, 214, 138, 60, 150, 62,
/* 530 */ 24, 215, 26, 216, 112, 150, 114, 115, 36, 28,
/* 540 */ 213, 95, 103, 165, 112, 205, 114, 115, 49, 50,
/* 550 */ 165, 173, 174, 51, 23, 44, 25, 46, 173, 174,
/* 560 */ 58, 22, 23, 22, 25, 160, 120, 68, 69, 70,
/* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
/* 580 */ 230, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 590 */ 91, 92, 19, 215, 22, 23, 23, 25, 163, 194,
/* 600 */ 94, 166, 167, 168, 25, 138, 67, 7, 8, 9,
/* 610 */ 108, 206, 207, 169, 170, 171, 150, 22, 221, 222,
/* 620 */ 223, 26, 49, 50, 86, 87, 23, 161, 162, 23,
/* 630 */ 22, 165, 24, 120, 22, 23, 25, 160, 241, 67,
/* 640 */ 176, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 650 */ 77, 78, 79, 80, 160, 82, 83, 84, 85, 86,
/* 660 */ 87, 88, 89, 90, 91, 92, 19, 129, 130, 150,
/* 670 */ 23, 194, 35, 23, 230, 25, 150, 155, 150, 67,
/* 680 */ 150, 105, 106, 107, 165, 221, 222, 223, 194, 94,
/* 690 */ 23, 165, 25, 165, 217, 165, 49, 50, 25, 173,
/* 700 */ 174, 173, 174, 173, 174, 0, 1, 2, 118, 221,
/* 710 */ 222, 223, 193, 219, 237, 68, 69, 70, 71, 72,
/* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
/* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
/* 740 */ 19, 150, 19, 165, 150, 24, 166, 167, 168, 227,
/* 750 */ 27, 173, 174, 231, 150, 25, 165, 150, 172, 165,
/* 760 */ 150, 242, 129, 130, 173, 174, 180, 173, 174, 165,
/* 770 */ 49, 50, 165, 150, 176, 165, 35, 173, 174, 165,
/* 780 */ 173, 174, 35, 23, 23, 25, 25, 173, 165, 68,
/* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88,
/* 810 */ 89, 90, 91, 92, 19, 150, 193, 165, 150, 221,
/* 820 */ 222, 223, 150, 213, 19, 173, 174, 23, 150, 97,
/* 830 */ 165, 150, 27, 165, 150, 150, 150, 165, 173, 174,
/* 840 */ 22, 173, 174, 165, 49, 50, 165, 52, 116, 165,
/* 850 */ 165, 165, 206, 207, 173, 174, 126, 50, 173, 174,
/* 860 */ 128, 27, 160, 68, 69, 70, 71, 72, 73, 74,
/* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84,
/* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150,
/* 890 */ 23, 165, 150, 23, 216, 25, 194, 32, 39, 173,
/* 900 */ 174, 135, 150, 137, 165, 150, 41, 165, 150, 52,
/* 910 */ 238, 104, 173, 174, 29, 173, 174, 165, 49, 50,
/* 920 */ 165, 219, 238, 165, 238, 173, 174, 52, 173, 174,
/* 930 */ 22, 173, 174, 23, 23, 160, 25, 68, 69, 70,
/* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
/* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90,
/* 960 */ 91, 92, 19, 150, 150, 165, 150, 245, 246, 194,
/* 970 */ 150, 144, 145, 173, 174, 160, 150, 22, 165, 165,
/* 980 */ 22, 165, 150, 150, 116, 165, 173, 174, 52, 173,
/* 990 */ 174, 165, 49, 50, 22, 150, 128, 165, 165, 173,
/* 1000 */ 174, 187, 166, 166, 22, 173, 174, 187, 109, 194,
/* 1010 */ 165, 68, 69, 70, 71, 72, 73, 74, 75, 76,
/* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86,
/* 1030 */ 87, 88, 89, 90, 91, 92, 19, 150, 193, 165,
/* 1040 */ 102, 205, 205, 150, 150, 247, 248, 173, 174, 19,
/* 1050 */ 150, 20, 165, 150, 150, 150, 150, 150, 165, 165,
/* 1060 */ 173, 174, 49, 50, 104, 165, 49, 50, 165, 165,
/* 1070 */ 165, 165, 165, 173, 174, 43, 173, 174, 173, 174,
/* 1080 */ 187, 24, 190, 191, 71, 72, 69, 70, 71, 72,
/* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82,
/* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92,
/* 1110 */ 19, 98, 150, 165, 150, 150, 150, 150, 150, 150,
/* 1120 */ 59, 173, 174, 25, 150, 190, 191, 165, 53, 165,
/* 1130 */ 165, 165, 165, 165, 165, 173, 174, 173, 174, 165,
/* 1140 */ 49, 50, 91, 92, 1, 2, 53, 173, 174, 138,
/* 1150 */ 104, 22, 5, 1, 35, 118, 127, 150, 193, 193,
/* 1160 */ 193, 70, 71, 72, 73, 74, 75, 76, 77, 78,
/* 1170 */ 79, 80, 165, 82, 83, 84, 85, 86, 87, 88,
/* 1180 */ 89, 90, 91, 92, 19, 20, 150, 22, 150, 27,
/* 1190 */ 150, 26, 27, 108, 150, 22, 76, 76, 150, 25,
/* 1200 */ 193, 165, 37, 165, 150, 165, 22, 19, 20, 165,
/* 1210 */ 22, 173, 174, 165, 26, 27, 23, 150, 119, 165,
/* 1220 */ 150, 56, 150, 150, 150, 37, 16, 173, 174, 193,
/* 1230 */ 150, 66, 165, 193, 1, 165, 121, 165, 165, 165,
/* 1240 */ 20, 146, 147, 119, 56, 165, 150, 152, 16, 154,
/* 1250 */ 150, 86, 87, 88, 66, 160, 150, 150, 93, 94,
/* 1260 */ 95, 165, 150, 98, 108, 165, 127, 23, 65, 173,
/* 1270 */ 174, 165, 165, 150, 86, 87, 128, 165, 150, 173,
/* 1280 */ 174, 93, 94, 95, 23, 150, 98, 15, 165, 194,
/* 1290 */ 150, 140, 22, 165, 129, 130, 131, 132, 133, 134,
/* 1300 */ 165, 173, 174, 3, 116, 165, 19, 20, 150, 22,
/* 1310 */ 4, 150, 217, 26, 27, 179, 179, 129, 130, 131,
/* 1320 */ 132, 133, 134, 165, 37, 150, 165, 150, 164, 19,
/* 1330 */ 20, 150, 22, 246, 149, 249, 26, 27, 249, 244,
/* 1340 */ 165, 150, 165, 56, 6, 150, 165, 37, 173, 174,
/* 1350 */ 173, 174, 150, 66, 173, 174, 165, 149, 149, 13,
/* 1360 */ 165, 25, 150, 150, 150, 149, 56, 165, 150, 116,
/* 1370 */ 151, 150, 150, 86, 87, 150, 66, 165, 165, 165,
/* 1380 */ 93, 94, 95, 165, 150, 98, 165, 165, 151, 22,
/* 1390 */ 165, 194, 150, 26, 27, 150, 86, 87, 159, 165,
/* 1400 */ 199, 126, 123, 93, 94, 95, 200, 165, 98, 124,
/* 1410 */ 165, 122, 201, 125, 225, 135, 129, 130, 131, 132,
/* 1420 */ 133, 134, 5, 157, 157, 202, 118, 10, 11, 12,
/* 1430 */ 13, 14, 203, 66, 17, 104, 210, 121, 211, 129,
/* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
/* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
/* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
/* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
/* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
/* 1490 */ 135, 156, 189, 68, 157, 218, 129, 130, 131, 22,
/* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
/* 1510 */ 218, 189, 40, 157, 38, 157, 240, 157, 240, 153,
/* 1520 */ 196, 181, 105, 106, 107, 243, 198, 166, 111, 230,
/* 1530 */ 176, 226, 239, 116, 230, 176, 166, 166, 176, 148,
/* 1540 */ 199, 177, 209, 209, 166, 196, 239, 208, 185, 199,
/* 1550 */ 92, 209, 233, 173, 234, 182, 139, 173, 182, 191,
/* 1560 */ 195, 182, 250, 186,
};
#define YY_SHIFT_USE_DFLT (-70)
#define YY_SHIFT_COUNT (416)
#define YY_SHIFT_MIN (-69)
#define YY_SHIFT_MAX (1487)
static const short yy_shift_ofst[] = {
/* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
/* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
/* 20 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 30 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 40 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1310, 1287,
/* 50 */ 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287, 1287,
/* 60 */ 1287, 1287, 286, 362, 362, 538, 538, 231, 1253, 55,
/* 70 */ 721, 647, 573, 499, 425, 351, 277, 203, 869, 869,
/* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
/* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
/* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
/* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
/* 130 */ 732, 868, 231, 1051, 1458, -70, -70, -70, 1367, 57,
/* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
/* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
/* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
/* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
/* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
/* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
/* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
/* 230 */ 766, 633, 633, 231, 284, 63, 608, 1476, 1308, 1308,
/* 240 */ 1472, 1472, 1308, 1477, 1425, 1275, 1487, 1487, 1487, 1487,
/* 250 */ 1308, 1461, 1275, 1477, 1425, 1425, 1308, 1461, 1355, 1441,
/* 260 */ 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348, 1348,
/* 270 */ 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408, 1348,
/* 280 */ 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308, 1280,
/* 290 */ 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346, 1338,
/* 300 */ 1338, 1338, 1338, -70, -70, -70, -70, -70, -70, 1013,
/* 310 */ 467, 612, 84, 179, -28, 870, 410, 761, 760, 667,
/* 320 */ 650, 531, 220, 361, 331, 125, 127, 97, 1306, 1300,
/* 330 */ 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174, 1139,
/* 340 */ 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184, 1174,
/* 350 */ 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152, 1147,
/* 360 */ 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960, 1057,
/* 370 */ 1031, 1030, 899, 938, 982, 936, 972, 958, 910, 955,
/* 380 */ 875, 885, 908, 857, 859, 867, 804, 590, 834, 747,
/* 390 */ 818, 513, 611, 741, 673, 637, 611, 606, 603, 579,
/* 400 */ 501, 541, 468, 386, 445, 395, 376, 281, 185, 120,
/* 410 */ 92, 75, 45, 114, 25, 11, 5,
};
#define YY_REDUCE_USE_DFLT (-169)
#define YY_REDUCE_COUNT (308)
#define YY_REDUCE_MIN (-168)
#define YY_REDUCE_MAX (1391)
static const short yy_reduce_ofst[] = {
/* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
/* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
/* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
/* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
/* 40 */ 800, 758, 755, 752, 742, 739, 726, 685, 681, 668,
/* 50 */ 665, 652, 607, 604, 594, 591, 578, 530, 528, 526,
/* 60 */ 385, 18, 477, 466, 519, 444, 350, 435, 405, 488,
/* 70 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 80 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 90 */ 488, 488, 488, 488, 488, 488, 488, 488, 488, 488,
/* 100 */ 488, 488, 488, 488, 488, 488, 488, 1040, 678, 1036,
/* 110 */ 1007, 967, 966, 965, 845, 686, 610, 684, 317, 672,
/* 120 */ 893, 327, 623, 522, -7, 820, 814, 157, 154, 101,
/* 130 */ 702, 494, 580, 488, 488, 488, 488, 488, 614, 586,
/* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
/* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
/* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
/* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
/* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
/* 190 */ -168, 1384, 1380, 1377, 1379, 1376, 1373, 1339, 1365, 1368,
/* 200 */ 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1320, 1319, 1365,
/* 210 */ 1365, 1339, 1378, 1349, 1391, 1350, 1342, 1334, 1307, 1341,
/* 220 */ 1293, 1364, 1363, 1371, 1362, 1370, 1359, 1340, 1354, 1333,
/* 230 */ 1305, 1304, 1299, 1361, 1328, 1324, 1366, 1282, 1360, 1358,
/* 240 */ 1278, 1276, 1356, 1292, 1322, 1309, 1317, 1315, 1314, 1312,
/* 250 */ 1345, 1347, 1302, 1277, 1311, 1303, 1337, 1335, 1252, 1248,
/* 260 */ 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301, 1295,
/* 270 */ 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274, 1281,
/* 280 */ 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266, 1189,
/* 290 */ 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219, 1216,
/* 300 */ 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
};
static const YYACTIONTYPE yy_default[] = {
/* 0 */ 632, 866, 954, 954, 866, 866, 954, 954, 954, 756,
/* 10 */ 954, 954, 954, 864, 954, 954, 784, 784, 928, 954,
/* 20 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 30 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 40 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 50 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 60 */ 954, 954, 954, 954, 954, 954, 954, 671, 760, 790,
/* 70 */ 954, 954, 954, 954, 954, 954, 954, 954, 927, 929,
/* 80 */ 798, 797, 907, 771, 795, 788, 792, 867, 860, 861,
/* 90 */ 859, 863, 868, 954, 791, 827, 844, 826, 838, 843,
/* 100 */ 850, 842, 839, 829, 828, 830, 831, 954, 954, 954,
/* 110 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 120 */ 954, 954, 954, 658, 725, 954, 954, 954, 954, 954,
/* 130 */ 954, 954, 954, 832, 833, 847, 846, 845, 954, 663,
/* 140 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 150 */ 934, 932, 954, 879, 954, 954, 954, 954, 954, 954,
/* 160 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 170 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 180 */ 638, 756, 756, 756, 632, 954, 954, 954, 946, 760,
/* 190 */ 750, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 200 */ 954, 954, 954, 800, 739, 917, 919, 954, 900, 737,
/* 210 */ 660, 758, 673, 748, 640, 794, 773, 773, 912, 794,
/* 220 */ 912, 696, 719, 954, 784, 954, 784, 693, 784, 773,
/* 230 */ 862, 954, 954, 954, 757, 748, 954, 939, 764, 764,
/* 240 */ 931, 931, 764, 806, 729, 794, 736, 736, 736, 736,
/* 250 */ 764, 655, 794, 806, 729, 729, 764, 655, 906, 904,
/* 260 */ 764, 764, 655, 764, 655, 764, 655, 872, 727, 727,
/* 270 */ 727, 711, 876, 876, 872, 727, 696, 727, 711, 727,
/* 280 */ 727, 777, 772, 777, 772, 777, 772, 764, 764, 954,
/* 290 */ 789, 778, 787, 785, 794, 954, 714, 648, 648, 637,
/* 300 */ 637, 637, 637, 951, 951, 946, 698, 698, 681, 954,
/* 310 */ 954, 954, 954, 954, 954, 954, 881, 954, 954, 954,
/* 320 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 633,
/* 330 */ 941, 954, 954, 938, 954, 954, 954, 954, 799, 954,
/* 340 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 916,
/* 350 */ 954, 954, 954, 954, 954, 954, 954, 910, 954, 954,
/* 360 */ 954, 954, 954, 954, 903, 902, 954, 954, 954, 954,
/* 370 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 380 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
/* 390 */ 954, 954, 786, 954, 779, 954, 865, 954, 954, 954,
/* 400 */ 954, 954, 954, 954, 954, 954, 954, 742, 815, 954,
/* 410 */ 814, 818, 813, 665, 954, 646, 954, 629, 634, 950,
/* 420 */ 953, 952, 949, 948, 947, 942, 940, 937, 936, 935,
/* 430 */ 933, 930, 926, 885, 883, 890, 889, 888, 887, 886,
/* 440 */ 884, 882, 880, 801, 796, 793, 925, 878, 738, 735,
/* 450 */ 734, 654, 943, 909, 918, 805, 804, 807, 915, 914,
/* 460 */ 913, 911, 908, 895, 803, 802, 730, 870, 869, 657,
/* 470 */ 899, 898, 897, 901, 905, 896, 766, 656, 653, 662,
/* 480 */ 717, 718, 726, 724, 723, 722, 721, 720, 716, 664,
/* 490 */ 672, 710, 695, 694, 875, 877, 874, 873, 703, 702,
/* 500 */ 708, 707, 706, 705, 704, 701, 700, 699, 692, 691,
/* 510 */ 697, 690, 713, 712, 709, 689, 733, 732, 731, 728,
/* 520 */ 688, 687, 686, 818, 685, 684, 824, 823, 811, 854,
/* 530 */ 753, 752, 751, 763, 762, 775, 774, 809, 808, 776,
/* 540 */ 761, 755, 754, 770, 769, 768, 767, 759, 749, 781,
/* 550 */ 783, 782, 780, 856, 765, 853, 924, 923, 922, 921,
/* 560 */ 920, 858, 857, 825, 822, 676, 677, 893, 892, 894,
/* 570 */ 891, 679, 678, 675, 674, 855, 744, 743, 851, 848,
/* 580 */ 840, 836, 852, 849, 841, 837, 835, 834, 820, 819,
/* 590 */ 817, 816, 812, 821, 667, 745, 741, 740, 810, 747,
/* 600 */ 746, 683, 682, 680, 661, 659, 652, 650, 649, 651,
/* 610 */ 647, 645, 644, 643, 642, 641, 670, 669, 668, 666,
/* 620 */ 665, 639, 636, 635, 631, 630, 628,
};
/* The next table maps tokens into fallback tokens. If a construct
** like the following:
**
|
| ︙ | ︙ | |||
108931 108932 108933 108934 108935 108936 108937 | "ecmd", "explain", "cmdx", "cmd", "transtype", "trans_opt", "nm", "savepoint_opt", "create_table", "create_table_args", "createkw", "temp", "ifnotexists", "dbnm", "columnlist", "conslist_opt", "select", "column", "columnid", "type", "carglist", "id", "ids", "typetoken", "typename", "signed", "plus_num", "minus_num", | | | | | | 109890 109891 109892 109893 109894 109895 109896 109897 109898 109899 109900 109901 109902 109903 109904 109905 109906 109907 | "ecmd", "explain", "cmdx", "cmd", "transtype", "trans_opt", "nm", "savepoint_opt", "create_table", "create_table_args", "createkw", "temp", "ifnotexists", "dbnm", "columnlist", "conslist_opt", "select", "column", "columnid", "type", "carglist", "id", "ids", "typetoken", "typename", "signed", "plus_num", "minus_num", "ccons", "term", "expr", "onconf", "sortorder", "autoinc", "idxlist_opt", "refargs", "defer_subclause", "refarg", "refact", "init_deferred_pred_opt", "conslist", "tconscomma", "tcons", "idxlist", "defer_subclause_opt", "orconf", "resolvetype", "raisetype", "ifexists", "fullname", "oneselect", "multiselect_op", "distinct", "selcollist", "from", "where_opt", "groupby_opt", "having_opt", "orderby_opt", "limit_opt", "sclp", "as", "seltablist", "stl_prefix", "joinop", "indexed_opt", "on_opt", "using_opt", "joinop2", "inscollist", "sortlist", "nexprlist", |
| ︙ | ︙ | |||
109011 109012 109013 109014 109015 109016 109017 | /* 46 */ "typetoken ::= typename", /* 47 */ "typetoken ::= typename LP signed RP", /* 48 */ "typetoken ::= typename LP signed COMMA signed RP", /* 49 */ "typename ::= ids", /* 50 */ "typename ::= typename ids", /* 51 */ "signed ::= plus_num", /* 52 */ "signed ::= minus_num", | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | > | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 109970 109971 109972 109973 109974 109975 109976 109977 109978 109979 109980 109981 109982 109983 109984 109985 109986 109987 109988 109989 109990 109991 109992 109993 109994 109995 109996 109997 109998 109999 110000 110001 110002 110003 110004 110005 110006 110007 110008 110009 110010 110011 110012 110013 110014 110015 110016 110017 110018 110019 110020 110021 110022 110023 110024 110025 110026 110027 110028 110029 110030 110031 110032 110033 110034 110035 110036 110037 110038 110039 110040 110041 110042 110043 110044 110045 110046 110047 110048 110049 110050 110051 110052 110053 110054 110055 110056 110057 110058 110059 110060 110061 110062 110063 110064 110065 110066 110067 110068 110069 110070 110071 110072 110073 110074 110075 110076 110077 110078 110079 110080 110081 110082 110083 110084 110085 110086 110087 110088 110089 110090 110091 110092 110093 110094 110095 110096 110097 110098 110099 110100 110101 110102 110103 110104 110105 110106 110107 110108 110109 110110 110111 110112 110113 110114 110115 110116 110117 110118 110119 110120 110121 110122 110123 110124 110125 110126 110127 110128 110129 110130 110131 110132 110133 110134 110135 110136 110137 110138 110139 110140 110141 110142 110143 110144 110145 110146 110147 110148 110149 110150 110151 110152 110153 110154 110155 110156 110157 110158 110159 110160 110161 110162 110163 110164 110165 110166 110167 110168 110169 110170 110171 110172 110173 110174 110175 110176 110177 110178 110179 110180 110181 110182 110183 110184 110185 110186 110187 110188 110189 110190 110191 110192 110193 110194 110195 110196 110197 110198 110199 110200 110201 110202 110203 110204 110205 110206 110207 110208 110209 110210 110211 110212 110213 110214 110215 110216 110217 110218 110219 110220 110221 110222 110223 110224 110225 110226 110227 110228 110229 110230 110231 110232 110233 110234 110235 110236 110237 110238 110239 110240 110241 110242 110243 110244 110245 110246 110247 110248 110249 110250 110251 110252 110253 110254 110255 110256 110257 | /* 46 */ "typetoken ::= typename", /* 47 */ "typetoken ::= typename LP signed RP", /* 48 */ "typetoken ::= typename LP signed COMMA signed RP", /* 49 */ "typename ::= ids", /* 50 */ "typename ::= typename ids", /* 51 */ "signed ::= plus_num", /* 52 */ "signed ::= minus_num", /* 53 */ "carglist ::= carglist ccons", /* 54 */ "carglist ::=", /* 55 */ "ccons ::= CONSTRAINT nm", /* 56 */ "ccons ::= DEFAULT term", /* 57 */ "ccons ::= DEFAULT LP expr RP", /* 58 */ "ccons ::= DEFAULT PLUS term", /* 59 */ "ccons ::= DEFAULT MINUS term", /* 60 */ "ccons ::= DEFAULT id", /* 61 */ "ccons ::= NULL onconf", /* 62 */ "ccons ::= NOT NULL onconf", /* 63 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", /* 64 */ "ccons ::= UNIQUE onconf", /* 65 */ "ccons ::= CHECK LP expr RP", /* 66 */ "ccons ::= REFERENCES nm idxlist_opt refargs", /* 67 */ "ccons ::= defer_subclause", /* 68 */ "ccons ::= COLLATE ids", /* 69 */ "autoinc ::=", /* 70 */ "autoinc ::= AUTOINCR", /* 71 */ "refargs ::=", /* 72 */ "refargs ::= refargs refarg", /* 73 */ "refarg ::= MATCH nm", /* 74 */ "refarg ::= ON INSERT refact", /* 75 */ "refarg ::= ON DELETE refact", /* 76 */ "refarg ::= ON UPDATE refact", /* 77 */ "refact ::= SET NULL", /* 78 */ "refact ::= SET DEFAULT", /* 79 */ "refact ::= CASCADE", /* 80 */ "refact ::= RESTRICT", /* 81 */ "refact ::= NO ACTION", /* 82 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", /* 83 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", /* 84 */ "init_deferred_pred_opt ::=", /* 85 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", /* 86 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", /* 87 */ "conslist_opt ::=", /* 88 */ "conslist_opt ::= COMMA conslist", /* 89 */ "conslist ::= conslist tconscomma tcons", /* 90 */ "conslist ::= tcons", /* 91 */ "tconscomma ::= COMMA", /* 92 */ "tconscomma ::=", /* 93 */ "tcons ::= CONSTRAINT nm", /* 94 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf", /* 95 */ "tcons ::= UNIQUE LP idxlist RP onconf", /* 96 */ "tcons ::= CHECK LP expr RP onconf", /* 97 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt", /* 98 */ "defer_subclause_opt ::=", /* 99 */ "defer_subclause_opt ::= defer_subclause", /* 100 */ "onconf ::=", /* 101 */ "onconf ::= ON CONFLICT resolvetype", /* 102 */ "orconf ::=", /* 103 */ "orconf ::= OR resolvetype", /* 104 */ "resolvetype ::= raisetype", /* 105 */ "resolvetype ::= IGNORE", /* 106 */ "resolvetype ::= REPLACE", /* 107 */ "cmd ::= DROP TABLE ifexists fullname", /* 108 */ "ifexists ::= IF EXISTS", /* 109 */ "ifexists ::=", /* 110 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select", /* 111 */ "cmd ::= DROP VIEW ifexists fullname", /* 112 */ "cmd ::= select", /* 113 */ "select ::= oneselect", /* 114 */ "select ::= select multiselect_op oneselect", /* 115 */ "multiselect_op ::= UNION", /* 116 */ "multiselect_op ::= UNION ALL", /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT", /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", /* 119 */ "distinct ::= DISTINCT", /* 120 */ "distinct ::= ALL", /* 121 */ "distinct ::=", /* 122 */ "sclp ::= selcollist COMMA", /* 123 */ "sclp ::=", /* 124 */ "selcollist ::= sclp expr as", /* 125 */ "selcollist ::= sclp STAR", /* 126 */ "selcollist ::= sclp nm DOT STAR", /* 127 */ "as ::= AS nm", /* 128 */ "as ::= ids", /* 129 */ "as ::=", /* 130 */ "from ::=", /* 131 */ "from ::= FROM seltablist", /* 132 */ "stl_prefix ::= seltablist joinop", /* 133 */ "stl_prefix ::=", /* 134 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", /* 135 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", /* 136 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", /* 137 */ "dbnm ::=", /* 138 */ "dbnm ::= DOT nm", /* 139 */ "fullname ::= nm dbnm", /* 140 */ "joinop ::= COMMA|JOIN", /* 141 */ "joinop ::= JOIN_KW JOIN", /* 142 */ "joinop ::= JOIN_KW nm JOIN", /* 143 */ "joinop ::= JOIN_KW nm nm JOIN", /* 144 */ "on_opt ::= ON expr", /* 145 */ "on_opt ::=", /* 146 */ "indexed_opt ::=", /* 147 */ "indexed_opt ::= INDEXED BY nm", /* 148 */ "indexed_opt ::= NOT INDEXED", /* 149 */ "using_opt ::= USING LP inscollist RP", /* 150 */ "using_opt ::=", /* 151 */ "orderby_opt ::=", /* 152 */ "orderby_opt ::= ORDER BY sortlist", /* 153 */ "sortlist ::= sortlist COMMA expr sortorder", /* 154 */ "sortlist ::= expr sortorder", /* 155 */ "sortorder ::= ASC", /* 156 */ "sortorder ::= DESC", /* 157 */ "sortorder ::=", /* 158 */ "groupby_opt ::=", /* 159 */ "groupby_opt ::= GROUP BY nexprlist", /* 160 */ "having_opt ::=", /* 161 */ "having_opt ::= HAVING expr", /* 162 */ "limit_opt ::=", /* 163 */ "limit_opt ::= LIMIT expr", /* 164 */ "limit_opt ::= LIMIT expr OFFSET expr", /* 165 */ "limit_opt ::= LIMIT expr COMMA expr", /* 166 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt", /* 167 */ "where_opt ::=", /* 168 */ "where_opt ::= WHERE expr", /* 169 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt", /* 170 */ "setlist ::= setlist COMMA nm EQ expr", /* 171 */ "setlist ::= nm EQ expr", /* 172 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist", /* 173 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select", /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES", /* 175 */ "insert_cmd ::= INSERT orconf", /* 176 */ "insert_cmd ::= REPLACE", /* 177 */ "valuelist ::= VALUES LP nexprlist RP", /* 178 */ "valuelist ::= valuelist COMMA LP exprlist RP", /* 179 */ "inscollist_opt ::=", /* 180 */ "inscollist_opt ::= LP inscollist RP", /* 181 */ "inscollist ::= inscollist COMMA nm", /* 182 */ "inscollist ::= nm", /* 183 */ "expr ::= term", /* 184 */ "expr ::= LP expr RP", /* 185 */ "term ::= NULL", /* 186 */ "expr ::= id", /* 187 */ "expr ::= JOIN_KW", /* 188 */ "expr ::= nm DOT nm", /* 189 */ "expr ::= nm DOT nm DOT nm", /* 190 */ "term ::= INTEGER|FLOAT|BLOB", /* 191 */ "term ::= STRING", /* 192 */ "expr ::= REGISTER", /* 193 */ "expr ::= VARIABLE", /* 194 */ "expr ::= expr COLLATE ids", /* 195 */ "expr ::= CAST LP expr AS typetoken RP", /* 196 */ "expr ::= ID LP distinct exprlist RP", /* 197 */ "expr ::= ID LP STAR RP", /* 198 */ "term ::= CTIME_KW", /* 199 */ "expr ::= expr AND expr", /* 200 */ "expr ::= expr OR expr", /* 201 */ "expr ::= expr LT|GT|GE|LE expr", /* 202 */ "expr ::= expr EQ|NE expr", /* 203 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", /* 204 */ "expr ::= expr PLUS|MINUS expr", /* 205 */ "expr ::= expr STAR|SLASH|REM expr", /* 206 */ "expr ::= expr CONCAT expr", /* 207 */ "likeop ::= LIKE_KW", /* 208 */ "likeop ::= NOT LIKE_KW", /* 209 */ "likeop ::= MATCH", /* 210 */ "likeop ::= NOT MATCH", /* 211 */ "expr ::= expr likeop expr", /* 212 */ "expr ::= expr likeop expr ESCAPE expr", /* 213 */ "expr ::= expr ISNULL|NOTNULL", /* 214 */ "expr ::= expr NOT NULL", /* 215 */ "expr ::= expr IS expr", /* 216 */ "expr ::= expr IS NOT expr", /* 217 */ "expr ::= NOT expr", /* 218 */ "expr ::= BITNOT expr", /* 219 */ "expr ::= MINUS expr", /* 220 */ "expr ::= PLUS expr", /* 221 */ "between_op ::= BETWEEN", /* 222 */ "between_op ::= NOT BETWEEN", /* 223 */ "expr ::= expr between_op expr AND expr", /* 224 */ "in_op ::= IN", /* 225 */ "in_op ::= NOT IN", /* 226 */ "expr ::= expr in_op LP exprlist RP", /* 227 */ "expr ::= LP select RP", /* 228 */ "expr ::= expr in_op LP select RP", /* 229 */ "expr ::= expr in_op nm dbnm", /* 230 */ "expr ::= EXISTS LP select RP", /* 231 */ "expr ::= CASE case_operand case_exprlist case_else END", /* 232 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", /* 233 */ "case_exprlist ::= WHEN expr THEN expr", /* 234 */ "case_else ::= ELSE expr", /* 235 */ "case_else ::=", /* 236 */ "case_operand ::= expr", /* 237 */ "case_operand ::=", /* 238 */ "exprlist ::= nexprlist", /* 239 */ "exprlist ::=", /* 240 */ "nexprlist ::= nexprlist COMMA expr", /* 241 */ "nexprlist ::= expr", /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP", /* 243 */ "uniqueflag ::= UNIQUE", /* 244 */ "uniqueflag ::=", /* 245 */ "idxlist_opt ::=", /* 246 */ "idxlist_opt ::= LP idxlist RP", /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder", /* 248 */ "idxlist ::= nm collate sortorder", /* 249 */ "collate ::=", /* 250 */ "collate ::= COLLATE ids", /* 251 */ "cmd ::= DROP INDEX ifexists fullname", /* 252 */ "cmd ::= VACUUM", /* 253 */ "cmd ::= VACUUM nm", /* 254 */ "cmd ::= PRAGMA nm dbnm", /* 255 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", /* 256 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", /* 257 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", /* 258 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", /* 259 */ "nmnum ::= plus_num", /* 260 */ "nmnum ::= nm", /* 261 */ "nmnum ::= ON", /* 262 */ "nmnum ::= DELETE", /* 263 */ "nmnum ::= DEFAULT", /* 264 */ "plus_num ::= PLUS number", /* 265 */ "plus_num ::= number", /* 266 */ "minus_num ::= MINUS number", /* 267 */ "number ::= INTEGER|FLOAT", /* 268 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", /* 269 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", /* 270 */ "trigger_time ::= BEFORE", /* 271 */ "trigger_time ::= AFTER", /* 272 */ "trigger_time ::= INSTEAD OF", /* 273 */ "trigger_time ::=", /* 274 */ "trigger_event ::= DELETE|INSERT", /* 275 */ "trigger_event ::= UPDATE", /* 276 */ "trigger_event ::= UPDATE OF inscollist", /* 277 */ "foreach_clause ::=", /* 278 */ "foreach_clause ::= FOR EACH ROW", /* 279 */ "when_clause ::=", /* 280 */ "when_clause ::= WHEN expr", /* 281 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", /* 282 */ "trigger_cmd_list ::= trigger_cmd SEMI", /* 283 */ "trnm ::= nm", /* 284 */ "trnm ::= nm DOT nm", /* 285 */ "tridxby ::=", /* 286 */ "tridxby ::= INDEXED BY nm", /* 287 */ "tridxby ::= NOT INDEXED", /* 288 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", /* 289 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist", /* 290 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", /* 291 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", /* 292 */ "trigger_cmd ::= select", /* 293 */ "expr ::= RAISE LP IGNORE RP", /* 294 */ "expr ::= RAISE LP raisetype COMMA nm RP", /* 295 */ "raisetype ::= ROLLBACK", /* 296 */ "raisetype ::= ABORT", /* 297 */ "raisetype ::= FAIL", /* 298 */ "cmd ::= DROP TRIGGER ifexists fullname", /* 299 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", /* 300 */ "cmd ::= DETACH database_kw_opt expr", /* 301 */ "key_opt ::=", /* 302 */ "key_opt ::= KEY expr", /* 303 */ "database_kw_opt ::= DATABASE", /* 304 */ "database_kw_opt ::=", /* 305 */ "cmd ::= REINDEX", /* 306 */ "cmd ::= REINDEX nm dbnm", /* 307 */ "cmd ::= ANALYZE", /* 308 */ "cmd ::= ANALYZE nm dbnm", /* 309 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", /* 310 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", /* 311 */ "add_column_fullname ::= fullname", /* 312 */ "kwcolumn_opt ::=", /* 313 */ "kwcolumn_opt ::= COLUMNKW", /* 314 */ "cmd ::= create_vtab", /* 315 */ "cmd ::= create_vtab LP vtabarglist RP", /* 316 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", /* 317 */ "vtabarglist ::= vtabarg", /* 318 */ "vtabarglist ::= vtabarglist COMMA vtabarg", /* 319 */ "vtabarg ::=", /* 320 */ "vtabarg ::= vtabarg vtabargtoken", /* 321 */ "vtabargtoken ::= ANY", /* 322 */ "vtabargtoken ::= lp anylist RP", /* 323 */ "lp ::= LP", /* 324 */ "anylist ::=", /* 325 */ "anylist ::= anylist LP anylist RP", /* 326 */ "anylist ::= anylist ANY", }; #endif /* NDEBUG */ #if YYSTACKDEPTH<=0 /* ** Try to increase the size of the parser stack. |
| ︙ | ︙ | |||
109367 109368 109369 109370 109371 109372 109373 |
*/
case 160: /* select */
case 194: /* oneselect */
{
sqlite3SelectDelete(pParse->db, (yypminor->yy159));
}
break;
| | | | | 110328 110329 110330 110331 110332 110333 110334 110335 110336 110337 110338 110339 110340 110341 110342 110343 110344 110345 110346 110347 110348 |
*/
case 160: /* select */
case 194: /* oneselect */
{
sqlite3SelectDelete(pParse->db, (yypminor->yy159));
}
break;
case 173: /* term */
case 174: /* expr */
{
sqlite3ExprDelete(pParse->db, (yypminor->yy342).pExpr);
}
break;
case 178: /* idxlist_opt */
case 187: /* idxlist */
case 197: /* selcollist */
case 200: /* groupby_opt */
case 202: /* orderby_opt */
case 204: /* sclp */
case 214: /* sortlist */
case 215: /* nexprlist */
|
| ︙ | ︙ | |||
109728 109729 109730 109731 109732 109733 109734 |
{ 167, 1 },
{ 167, 4 },
{ 167, 6 },
{ 168, 1 },
{ 168, 2 },
{ 169, 1 },
{ 169, 1 },
| | | < | | | | | | | | | | | | | | | | < < < < < < < < < < > > > > > > > > > > | | | > > | | > | | | 110689 110690 110691 110692 110693 110694 110695 110696 110697 110698 110699 110700 110701 110702 110703 110704 110705 110706 110707 110708 110709 110710 110711 110712 110713 110714 110715 110716 110717 110718 110719 110720 110721 110722 110723 110724 110725 110726 110727 110728 110729 110730 110731 110732 110733 110734 110735 110736 110737 110738 110739 110740 110741 110742 110743 110744 110745 110746 110747 110748 110749 110750 110751 |
{ 167, 1 },
{ 167, 4 },
{ 167, 6 },
{ 168, 1 },
{ 168, 2 },
{ 169, 1 },
{ 169, 1 },
{ 164, 2 },
{ 164, 0 },
{ 172, 2 },
{ 172, 2 },
{ 172, 4 },
{ 172, 3 },
{ 172, 3 },
{ 172, 2 },
{ 172, 2 },
{ 172, 3 },
{ 172, 5 },
{ 172, 2 },
{ 172, 4 },
{ 172, 4 },
{ 172, 1 },
{ 172, 2 },
{ 177, 0 },
{ 177, 1 },
{ 179, 0 },
{ 179, 2 },
{ 181, 2 },
{ 181, 3 },
{ 181, 3 },
{ 181, 3 },
{ 182, 2 },
{ 182, 2 },
{ 182, 1 },
{ 182, 1 },
{ 182, 2 },
{ 180, 3 },
{ 180, 2 },
{ 183, 0 },
{ 183, 2 },
{ 183, 2 },
{ 159, 0 },
{ 159, 2 },
{ 184, 3 },
{ 184, 1 },
{ 185, 1 },
{ 185, 0 },
{ 186, 2 },
{ 186, 7 },
{ 186, 5 },
{ 186, 5 },
{ 186, 10 },
{ 188, 0 },
{ 188, 1 },
{ 175, 0 },
{ 175, 3 },
{ 189, 0 },
{ 189, 2 },
{ 190, 1 },
{ 190, 1 },
{ 190, 1 },
{ 147, 4 },
{ 192, 2 },
|
| ︙ | ︙ | |||
109828 109829 109830 109831 109832 109833 109834 |
{ 209, 2 },
{ 211, 4 },
{ 211, 0 },
{ 202, 0 },
{ 202, 3 },
{ 214, 4 },
{ 214, 2 },
| | | | | 110791 110792 110793 110794 110795 110796 110797 110798 110799 110800 110801 110802 110803 110804 110805 110806 110807 |
{ 209, 2 },
{ 211, 4 },
{ 211, 0 },
{ 202, 0 },
{ 202, 3 },
{ 214, 4 },
{ 214, 2 },
{ 176, 1 },
{ 176, 1 },
{ 176, 0 },
{ 200, 0 },
{ 200, 3 },
{ 201, 0 },
{ 201, 2 },
{ 203, 0 },
{ 203, 2 },
{ 203, 4 },
|
| ︙ | ︙ | |||
109856 109857 109858 109859 109860 109861 109862 |
{ 217, 1 },
{ 219, 4 },
{ 219, 5 },
{ 218, 0 },
{ 218, 3 },
{ 213, 3 },
{ 213, 1 },
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 110819 110820 110821 110822 110823 110824 110825 110826 110827 110828 110829 110830 110831 110832 110833 110834 110835 110836 110837 110838 110839 110840 110841 110842 110843 110844 110845 110846 110847 110848 110849 110850 110851 110852 110853 110854 110855 110856 110857 110858 110859 110860 110861 110862 110863 110864 110865 110866 110867 110868 110869 110870 110871 110872 110873 110874 110875 110876 110877 110878 110879 110880 110881 110882 110883 110884 110885 110886 110887 110888 110889 110890 110891 110892 110893 110894 110895 110896 |
{ 217, 1 },
{ 219, 4 },
{ 219, 5 },
{ 218, 0 },
{ 218, 3 },
{ 213, 3 },
{ 213, 1 },
{ 174, 1 },
{ 174, 3 },
{ 173, 1 },
{ 174, 1 },
{ 174, 1 },
{ 174, 3 },
{ 174, 5 },
{ 173, 1 },
{ 173, 1 },
{ 174, 1 },
{ 174, 1 },
{ 174, 3 },
{ 174, 6 },
{ 174, 5 },
{ 174, 4 },
{ 173, 1 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 174, 3 },
{ 221, 1 },
{ 221, 2 },
{ 221, 1 },
{ 221, 2 },
{ 174, 3 },
{ 174, 5 },
{ 174, 2 },
{ 174, 3 },
{ 174, 3 },
{ 174, 4 },
{ 174, 2 },
{ 174, 2 },
{ 174, 2 },
{ 174, 2 },
{ 222, 1 },
{ 222, 2 },
{ 174, 5 },
{ 223, 1 },
{ 223, 2 },
{ 174, 5 },
{ 174, 3 },
{ 174, 5 },
{ 174, 4 },
{ 174, 4 },
{ 174, 5 },
{ 225, 5 },
{ 225, 4 },
{ 226, 2 },
{ 226, 0 },
{ 224, 1 },
{ 224, 0 },
{ 220, 1 },
{ 220, 0 },
{ 215, 3 },
{ 215, 1 },
{ 147, 11 },
{ 227, 1 },
{ 227, 0 },
{ 178, 0 },
{ 178, 3 },
{ 187, 5 },
{ 187, 3 },
{ 228, 0 },
{ 228, 2 },
{ 147, 4 },
{ 147, 1 },
{ 147, 2 },
|
| ︙ | ︙ | |||
109966 109967 109968 109969 109970 109971 109972 |
{ 239, 3 },
{ 239, 2 },
{ 237, 7 },
{ 237, 5 },
{ 237, 5 },
{ 237, 5 },
{ 237, 1 },
| | | | 110929 110930 110931 110932 110933 110934 110935 110936 110937 110938 110939 110940 110941 110942 110943 110944 |
{ 239, 3 },
{ 239, 2 },
{ 237, 7 },
{ 237, 5 },
{ 237, 5 },
{ 237, 5 },
{ 237, 1 },
{ 174, 4 },
{ 174, 6 },
{ 191, 1 },
{ 191, 1 },
{ 191, 1 },
{ 147, 4 },
{ 147, 6 },
{ 147, 3 },
{ 241, 0 },
|
| ︙ | ︙ | |||
110075 110076 110077 110078 110079 110080 110081 |
break;
case 13: /* transtype ::= */
{yygotominor.yy392 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
| | | | 111038 111039 111040 111041 111042 111043 111044 111045 111046 111047 111048 111049 111050 111051 111052 111053 |
break;
case 13: /* transtype ::= */
{yygotominor.yy392 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
{yygotominor.yy392 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
{sqlite3CommitTransaction(pParse);}
break;
case 19: /* cmd ::= ROLLBACK trans_opt */
|
| ︙ | ︙ | |||
110114 110115 110116 110117 110118 110119 110120 |
{
pParse->db->lookaside.bEnabled = 0;
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 28: /* ifnotexists ::= */
case 31: /* temp ::= */ yytestcase(yyruleno==31);
| | | | | | | | | | | | | | | | | | 111077 111078 111079 111080 111081 111082 111083 111084 111085 111086 111087 111088 111089 111090 111091 111092 111093 111094 111095 111096 111097 111098 111099 111100 111101 111102 111103 111104 111105 111106 111107 111108 111109 111110 |
{
pParse->db->lookaside.bEnabled = 0;
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 28: /* ifnotexists ::= */
case 31: /* temp ::= */ yytestcase(yyruleno==31);
case 69: /* autoinc ::= */ yytestcase(yyruleno==69);
case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82);
case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84);
case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86);
case 98: /* defer_subclause_opt ::= */ yytestcase(yyruleno==98);
case 109: /* ifexists ::= */ yytestcase(yyruleno==109);
case 120: /* distinct ::= ALL */ yytestcase(yyruleno==120);
case 121: /* distinct ::= */ yytestcase(yyruleno==121);
case 221: /* between_op ::= BETWEEN */ yytestcase(yyruleno==221);
case 224: /* in_op ::= IN */ yytestcase(yyruleno==224);
{yygotominor.yy392 = 0;}
break;
case 29: /* ifnotexists ::= IF NOT EXISTS */
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
case 70: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==70);
case 85: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==85);
case 108: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==108);
case 119: /* distinct ::= DISTINCT */ yytestcase(yyruleno==119);
case 222: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==222);
case 225: /* in_op ::= NOT IN */ yytestcase(yyruleno==225);
{yygotominor.yy392 = 1;}
break;
case 32: /* create_table_args ::= LP columnlist conslist_opt RP */
{
sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
}
break;
|
| ︙ | ︙ | |||
110157 110158 110159 110160 110161 110162 110163 110164 110165 110166 110167 110168 110169 110170 110171 110172 110173 |
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
}
break;
case 37: /* columnid ::= nm */
{
sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
yygotominor.yy0 = yymsp[0].minor.yy0;
}
break;
case 38: /* id ::= ID */
case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
case 41: /* nm ::= id */ yytestcase(yyruleno==41);
case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
| > | | | | | | | | | | | | | | | | > < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 111120 111121 111122 111123 111124 111125 111126 111127 111128 111129 111130 111131 111132 111133 111134 111135 111136 111137 111138 111139 111140 111141 111142 111143 111144 111145 111146 111147 111148 111149 111150 111151 111152 111153 111154 111155 111156 111157 111158 111159 111160 111161 111162 111163 111164 111165 111166 111167 111168 111169 111170 111171 111172 111173 111174 111175 111176 111177 111178 111179 111180 111181 111182 111183 111184 111185 111186 111187 111188 111189 111190 111191 111192 111193 111194 111195 111196 111197 111198 111199 111200 111201 111202 111203 111204 111205 111206 111207 111208 111209 111210 111211 111212 111213 111214 111215 111216 111217 111218 111219 111220 111221 111222 111223 111224 111225 111226 111227 111228 111229 111230 111231 111232 111233 111234 111235 111236 111237 111238 111239 111240 111241 111242 111243 111244 111245 111246 111247 111248 111249 111250 111251 111252 111253 111254 111255 111256 111257 111258 111259 111260 111261 111262 111263 111264 111265 111266 111267 111268 111269 111270 111271 111272 111273 111274 111275 111276 111277 111278 111279 111280 111281 111282 111283 111284 111285 111286 111287 111288 111289 111290 111291 111292 111293 111294 111295 111296 111297 111298 111299 111300 111301 111302 111303 111304 111305 111306 111307 111308 111309 111310 111311 111312 111313 111314 111315 111316 111317 111318 111319 111320 111321 111322 111323 111324 111325 111326 111327 111328 111329 111330 111331 111332 111333 111334 111335 111336 111337 111338 111339 111340 111341 111342 111343 111344 111345 111346 111347 111348 111349 111350 111351 111352 111353 111354 111355 111356 111357 111358 111359 111360 111361 111362 111363 111364 111365 111366 111367 111368 111369 111370 111371 111372 111373 111374 111375 111376 111377 111378 111379 111380 111381 111382 111383 111384 111385 111386 111387 111388 111389 111390 111391 111392 111393 111394 111395 111396 111397 111398 111399 111400 111401 111402 111403 111404 111405 111406 111407 111408 111409 111410 111411 111412 111413 111414 111415 111416 111417 111418 111419 111420 111421 111422 111423 111424 111425 111426 111427 111428 111429 111430 111431 111432 111433 111434 111435 111436 111437 111438 111439 111440 111441 111442 111443 111444 111445 111446 111447 111448 111449 111450 111451 111452 111453 111454 111455 111456 111457 111458 111459 111460 111461 111462 111463 111464 111465 111466 111467 111468 111469 111470 111471 111472 111473 111474 111475 111476 111477 111478 111479 111480 111481 111482 111483 111484 111485 111486 111487 111488 111489 111490 111491 111492 111493 111494 111495 111496 111497 111498 111499 111500 111501 111502 111503 111504 111505 111506 111507 111508 111509 111510 111511 111512 111513 111514 111515 111516 111517 111518 111519 111520 111521 111522 111523 111524 111525 111526 111527 111528 111529 111530 111531 111532 111533 111534 111535 111536 111537 111538 111539 111540 111541 111542 111543 111544 111545 111546 111547 111548 111549 111550 111551 111552 111553 111554 111555 111556 111557 111558 111559 111560 111561 111562 111563 111564 111565 111566 111567 111568 111569 111570 111571 111572 111573 111574 111575 111576 111577 111578 111579 111580 111581 111582 111583 111584 111585 111586 111587 111588 111589 111590 111591 111592 111593 111594 111595 111596 111597 111598 111599 111600 111601 111602 111603 111604 111605 111606 111607 111608 111609 111610 111611 111612 111613 111614 111615 111616 111617 111618 111619 111620 111621 111622 111623 111624 111625 111626 111627 111628 111629 111630 111631 111632 111633 111634 111635 111636 111637 111638 111639 111640 111641 111642 111643 111644 111645 111646 111647 111648 111649 111650 111651 111652 111653 111654 111655 111656 111657 111658 111659 111660 111661 111662 111663 111664 111665 111666 111667 111668 111669 111670 111671 111672 111673 111674 111675 111676 111677 111678 111679 111680 111681 111682 111683 111684 111685 111686 111687 111688 111689 111690 111691 111692 111693 111694 111695 111696 111697 111698 111699 111700 111701 111702 111703 111704 111705 111706 111707 111708 111709 111710 111711 111712 111713 111714 111715 111716 111717 111718 111719 111720 111721 111722 111723 111724 111725 111726 111727 111728 111729 111730 111731 111732 111733 111734 111735 111736 111737 111738 111739 111740 111741 111742 111743 111744 111745 111746 111747 111748 111749 111750 111751 111752 111753 111754 111755 111756 111757 111758 111759 111760 111761 111762 111763 |
yygotominor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
}
break;
case 37: /* columnid ::= nm */
{
sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
yygotominor.yy0 = yymsp[0].minor.yy0;
pParse->constraintName.n = 0;
}
break;
case 38: /* id ::= ID */
case 39: /* id ::= INDEXED */ yytestcase(yyruleno==39);
case 40: /* ids ::= ID|STRING */ yytestcase(yyruleno==40);
case 41: /* nm ::= id */ yytestcase(yyruleno==41);
case 42: /* nm ::= STRING */ yytestcase(yyruleno==42);
case 43: /* nm ::= JOIN_KW */ yytestcase(yyruleno==43);
case 46: /* typetoken ::= typename */ yytestcase(yyruleno==46);
case 49: /* typename ::= ids */ yytestcase(yyruleno==49);
case 127: /* as ::= AS nm */ yytestcase(yyruleno==127);
case 128: /* as ::= ids */ yytestcase(yyruleno==128);
case 138: /* dbnm ::= DOT nm */ yytestcase(yyruleno==138);
case 147: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==147);
case 250: /* collate ::= COLLATE ids */ yytestcase(yyruleno==250);
case 259: /* nmnum ::= plus_num */ yytestcase(yyruleno==259);
case 260: /* nmnum ::= nm */ yytestcase(yyruleno==260);
case 261: /* nmnum ::= ON */ yytestcase(yyruleno==261);
case 262: /* nmnum ::= DELETE */ yytestcase(yyruleno==262);
case 263: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==263);
case 264: /* plus_num ::= PLUS number */ yytestcase(yyruleno==264);
case 265: /* plus_num ::= number */ yytestcase(yyruleno==265);
case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266);
case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267);
case 283: /* trnm ::= nm */ yytestcase(yyruleno==283);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
case 45: /* type ::= typetoken */
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
case 47: /* typetoken ::= typename LP signed RP */
{
yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
}
break;
case 48: /* typetoken ::= typename LP signed COMMA signed RP */
{
yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
}
break;
case 50: /* typename ::= typename ids */
{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
case 55: /* ccons ::= CONSTRAINT nm */
case 93: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==93);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
case 56: /* ccons ::= DEFAULT term */
case 58: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==58);
{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy342);}
break;
case 57: /* ccons ::= DEFAULT LP expr RP */
{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy342);}
break;
case 59: /* ccons ::= DEFAULT MINUS term */
{
ExprSpan v;
v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy342.pExpr, 0, 0);
v.zStart = yymsp[-1].minor.yy0.z;
v.zEnd = yymsp[0].minor.yy342.zEnd;
sqlite3AddDefaultValue(pParse,&v);
}
break;
case 60: /* ccons ::= DEFAULT id */
{
ExprSpan v;
spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
sqlite3AddDefaultValue(pParse,&v);
}
break;
case 62: /* ccons ::= NOT NULL onconf */
{sqlite3AddNotNull(pParse, yymsp[0].minor.yy392);}
break;
case 63: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy392,yymsp[0].minor.yy392,yymsp[-2].minor.yy392);}
break;
case 64: /* ccons ::= UNIQUE onconf */
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy392,0,0,0,0);}
break;
case 65: /* ccons ::= CHECK LP expr RP */
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy342.pExpr);}
break;
case 66: /* ccons ::= REFERENCES nm idxlist_opt refargs */
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy442,yymsp[0].minor.yy392);}
break;
case 67: /* ccons ::= defer_subclause */
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy392);}
break;
case 68: /* ccons ::= COLLATE ids */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
case 71: /* refargs ::= */
{ yygotominor.yy392 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
case 72: /* refargs ::= refargs refarg */
{ yygotominor.yy392 = (yymsp[-1].minor.yy392 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; }
break;
case 73: /* refarg ::= MATCH nm */
case 74: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==74);
{ yygotominor.yy207.value = 0; yygotominor.yy207.mask = 0x000000; }
break;
case 75: /* refarg ::= ON DELETE refact */
{ yygotominor.yy207.value = yymsp[0].minor.yy392; yygotominor.yy207.mask = 0x0000ff; }
break;
case 76: /* refarg ::= ON UPDATE refact */
{ yygotominor.yy207.value = yymsp[0].minor.yy392<<8; yygotominor.yy207.mask = 0x00ff00; }
break;
case 77: /* refact ::= SET NULL */
{ yygotominor.yy392 = OE_SetNull; /* EV: R-33326-45252 */}
break;
case 78: /* refact ::= SET DEFAULT */
{ yygotominor.yy392 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
case 79: /* refact ::= CASCADE */
{ yygotominor.yy392 = OE_Cascade; /* EV: R-33326-45252 */}
break;
case 80: /* refact ::= RESTRICT */
{ yygotominor.yy392 = OE_Restrict; /* EV: R-33326-45252 */}
break;
case 81: /* refact ::= NO ACTION */
{ yygotominor.yy392 = OE_None; /* EV: R-33326-45252 */}
break;
case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 99: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==99);
case 101: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==101);
case 104: /* resolvetype ::= raisetype */ yytestcase(yyruleno==104);
{yygotominor.yy392 = yymsp[0].minor.yy392;}
break;
case 87: /* conslist_opt ::= */
{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
break;
case 88: /* conslist_opt ::= COMMA conslist */
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
case 91: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
case 94: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy442,yymsp[0].minor.yy392,yymsp[-2].minor.yy392,0);}
break;
case 95: /* tcons ::= UNIQUE LP idxlist RP onconf */
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy442,yymsp[0].minor.yy392,0,0,0,0);}
break;
case 96: /* tcons ::= CHECK LP expr RP onconf */
{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy342.pExpr);}
break;
case 97: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
{
sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy442, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy442, yymsp[-1].minor.yy392);
sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy392);
}
break;
case 100: /* onconf ::= */
{yygotominor.yy392 = OE_Default;}
break;
case 102: /* orconf ::= */
{yygotominor.yy258 = OE_Default;}
break;
case 103: /* orconf ::= OR resolvetype */
{yygotominor.yy258 = (u8)yymsp[0].minor.yy392;}
break;
case 105: /* resolvetype ::= IGNORE */
{yygotominor.yy392 = OE_Ignore;}
break;
case 106: /* resolvetype ::= REPLACE */
{yygotominor.yy392 = OE_Replace;}
break;
case 107: /* cmd ::= DROP TABLE ifexists fullname */
{
sqlite3DropTable(pParse, yymsp[0].minor.yy347, 0, yymsp[-1].minor.yy392);
}
break;
case 110: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
{
sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy159, yymsp[-6].minor.yy392, yymsp[-4].minor.yy392);
}
break;
case 111: /* cmd ::= DROP VIEW ifexists fullname */
{
sqlite3DropTable(pParse, yymsp[0].minor.yy347, 1, yymsp[-1].minor.yy392);
}
break;
case 112: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0};
sqlite3Select(pParse, yymsp[0].minor.yy159, &dest);
sqlite3ExplainBegin(pParse->pVdbe);
sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy159);
sqlite3ExplainFinish(pParse->pVdbe);
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy159);
}
break;
case 113: /* select ::= oneselect */
{yygotominor.yy159 = yymsp[0].minor.yy159;}
break;
case 114: /* select ::= select multiselect_op oneselect */
{
if( yymsp[0].minor.yy159 ){
yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
}else{
sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
}
yygotominor.yy159 = yymsp[0].minor.yy159;
}
break;
case 116: /* multiselect_op ::= UNION ALL */
{yygotominor.yy392 = TK_ALL;}
break;
case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
yygotominor.yy159 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy442,yymsp[-5].minor.yy347,yymsp[-4].minor.yy122,yymsp[-3].minor.yy442,yymsp[-2].minor.yy122,yymsp[-1].minor.yy442,yymsp[-7].minor.yy392,yymsp[0].minor.yy64.pLimit,yymsp[0].minor.yy64.pOffset);
}
break;
case 122: /* sclp ::= selcollist COMMA */
case 246: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==246);
{yygotominor.yy442 = yymsp[-1].minor.yy442;}
break;
case 123: /* sclp ::= */
case 151: /* orderby_opt ::= */ yytestcase(yyruleno==151);
case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158);
case 239: /* exprlist ::= */ yytestcase(yyruleno==239);
case 245: /* idxlist_opt ::= */ yytestcase(yyruleno==245);
{yygotominor.yy442 = 0;}
break;
case 124: /* selcollist ::= sclp expr as */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy442, yymsp[-1].minor.yy342.pExpr);
if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[0].minor.yy0, 1);
sqlite3ExprListSetSpan(pParse,yygotominor.yy442,&yymsp[-1].minor.yy342);
}
break;
case 125: /* selcollist ::= sclp STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy442, p);
}
break;
case 126: /* selcollist ::= sclp nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442, pDot);
}
break;
case 129: /* as ::= */
{yygotominor.yy0.n = 0;}
break;
case 130: /* from ::= */
{yygotominor.yy347 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy347));}
break;
case 131: /* from ::= FROM seltablist */
{
yygotominor.yy347 = yymsp[0].minor.yy347;
sqlite3SrcListShiftJoinType(yygotominor.yy347);
}
break;
case 132: /* stl_prefix ::= seltablist joinop */
{
yygotominor.yy347 = yymsp[-1].minor.yy347;
if( ALWAYS(yygotominor.yy347 && yygotominor.yy347->nSrc>0) ) yygotominor.yy347->a[yygotominor.yy347->nSrc-1].jointype = (u8)yymsp[0].minor.yy392;
}
break;
case 133: /* stl_prefix ::= */
{yygotominor.yy347 = 0;}
break;
case 134: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
sqlite3SrcListIndexedBy(pParse, yygotominor.yy347, &yymsp[-2].minor.yy0);
}
break;
case 135: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy159,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
}
break;
case 136: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
if( yymsp[-6].minor.yy347==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy122==0 && yymsp[0].minor.yy180==0 ){
yygotominor.yy347 = yymsp[-4].minor.yy347;
}else{
Select *pSubquery;
sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy347);
pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy347,0,0,0,0,0,0,0);
yygotominor.yy347 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy347,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy122,yymsp[0].minor.yy180);
}
}
break;
case 137: /* dbnm ::= */
case 146: /* indexed_opt ::= */ yytestcase(yyruleno==146);
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
case 139: /* fullname ::= nm dbnm */
{yygotominor.yy347 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 140: /* joinop ::= COMMA|JOIN */
{ yygotominor.yy392 = JT_INNER; }
break;
case 141: /* joinop ::= JOIN_KW JOIN */
{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
break;
case 142: /* joinop ::= JOIN_KW nm JOIN */
{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
break;
case 143: /* joinop ::= JOIN_KW nm nm JOIN */
{ yygotominor.yy392 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
break;
case 144: /* on_opt ::= ON expr */
case 161: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==161);
case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168);
case 234: /* case_else ::= ELSE expr */ yytestcase(yyruleno==234);
case 236: /* case_operand ::= expr */ yytestcase(yyruleno==236);
{yygotominor.yy122 = yymsp[0].minor.yy342.pExpr;}
break;
case 145: /* on_opt ::= */
case 160: /* having_opt ::= */ yytestcase(yyruleno==160);
case 167: /* where_opt ::= */ yytestcase(yyruleno==167);
case 235: /* case_else ::= */ yytestcase(yyruleno==235);
case 237: /* case_operand ::= */ yytestcase(yyruleno==237);
{yygotominor.yy122 = 0;}
break;
case 148: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
case 149: /* using_opt ::= USING LP inscollist RP */
case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180);
{yygotominor.yy180 = yymsp[-1].minor.yy180;}
break;
case 150: /* using_opt ::= */
case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
{yygotominor.yy180 = 0;}
break;
case 152: /* orderby_opt ::= ORDER BY sortlist */
case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159);
case 238: /* exprlist ::= nexprlist */ yytestcase(yyruleno==238);
{yygotominor.yy442 = yymsp[0].minor.yy442;}
break;
case 153: /* sortlist ::= sortlist COMMA expr sortorder */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy442,yymsp[-1].minor.yy342.pExpr);
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
}
break;
case 154: /* sortlist ::= expr sortorder */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy342.pExpr);
if( yygotominor.yy442 && ALWAYS(yygotominor.yy442->a) ) yygotominor.yy442->a[0].sortOrder = (u8)yymsp[0].minor.yy392;
}
break;
case 155: /* sortorder ::= ASC */
case 157: /* sortorder ::= */ yytestcase(yyruleno==157);
{yygotominor.yy392 = SQLITE_SO_ASC;}
break;
case 156: /* sortorder ::= DESC */
{yygotominor.yy392 = SQLITE_SO_DESC;}
break;
case 162: /* limit_opt ::= */
{yygotominor.yy64.pLimit = 0; yygotominor.yy64.pOffset = 0;}
break;
case 163: /* limit_opt ::= LIMIT expr */
{yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr; yygotominor.yy64.pOffset = 0;}
break;
case 164: /* limit_opt ::= LIMIT expr OFFSET expr */
{yygotominor.yy64.pLimit = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pOffset = yymsp[0].minor.yy342.pExpr;}
break;
case 165: /* limit_opt ::= LIMIT expr COMMA expr */
{yygotominor.yy64.pOffset = yymsp[-2].minor.yy342.pExpr; yygotominor.yy64.pLimit = yymsp[0].minor.yy342.pExpr;}
break;
case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
{
sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy347, &yymsp[-1].minor.yy0);
sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy347,yymsp[0].minor.yy122);
}
break;
case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
{
sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy347, &yymsp[-3].minor.yy0);
sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy442,"set list");
sqlite3Update(pParse,yymsp[-4].minor.yy347,yymsp[-1].minor.yy442,yymsp[0].minor.yy122,yymsp[-5].minor.yy258);
}
break;
case 170: /* setlist ::= setlist COMMA nm EQ expr */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy442, yymsp[0].minor.yy342.pExpr);
sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
}
break;
case 171: /* setlist ::= nm EQ expr */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy342.pExpr);
sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
}
break;
case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */
{sqlite3Insert(pParse, yymsp[-2].minor.yy347, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
break;
case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
{sqlite3Insert(pParse, yymsp[-2].minor.yy347, 0, yymsp[0].minor.yy159, yymsp[-1].minor.yy180, yymsp[-4].minor.yy258);}
break;
case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
{sqlite3Insert(pParse, yymsp[-3].minor.yy347, 0, 0, yymsp[-2].minor.yy180, yymsp[-5].minor.yy258);}
break;
case 175: /* insert_cmd ::= INSERT orconf */
{yygotominor.yy258 = yymsp[0].minor.yy258;}
break;
case 176: /* insert_cmd ::= REPLACE */
{yygotominor.yy258 = OE_Replace;}
break;
case 177: /* valuelist ::= VALUES LP nexprlist RP */
{
yygotominor.yy487.pList = yymsp[-1].minor.yy442;
yygotominor.yy487.pSelect = 0;
}
break;
case 178: /* valuelist ::= valuelist COMMA LP exprlist RP */
{
Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy442, 0, 0, 0, 0, 0, 0, 0, 0);
if( yymsp[-4].minor.yy487.pList ){
yymsp[-4].minor.yy487.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy487.pList, 0, 0, 0, 0, 0, 0, 0, 0);
yymsp[-4].minor.yy487.pList = 0;
}
yygotominor.yy487.pList = 0;
if( yymsp[-4].minor.yy487.pSelect==0 || pRight==0 ){
sqlite3SelectDelete(pParse->db, pRight);
sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy487.pSelect);
yygotominor.yy487.pSelect = 0;
}else{
pRight->op = TK_ALL;
pRight->pPrior = yymsp[-4].minor.yy487.pSelect;
pRight->selFlags |= SF_Values;
pRight->pPrior->selFlags |= SF_Values;
yygotominor.yy487.pSelect = pRight;
}
}
break;
case 181: /* inscollist ::= inscollist COMMA nm */
{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy180,&yymsp[0].minor.yy0);}
break;
case 182: /* inscollist ::= nm */
{yygotominor.yy180 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
break;
case 183: /* expr ::= term */
{yygotominor.yy342 = yymsp[0].minor.yy342;}
break;
case 184: /* expr ::= LP expr RP */
{yygotominor.yy342.pExpr = yymsp[-1].minor.yy342.pExpr; spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
break;
case 185: /* term ::= NULL */
case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
{spanExpr(&yygotominor.yy342, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
break;
case 186: /* expr ::= id */
case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
{spanExpr(&yygotominor.yy342, pParse, TK_ID, &yymsp[0].minor.yy0);}
break;
case 188: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
spanSet(&yygotominor.yy342,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 189: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 192: /* expr ::= REGISTER */
{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
yygotominor.yy342.pExpr = 0;
}else{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
if( yygotominor.yy342.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy342.pExpr->iTable);
}
spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 193: /* expr ::= VARIABLE */
{
spanExpr(&yygotominor.yy342, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
sqlite3ExprAssignVarNumber(pParse, yygotominor.yy342.pExpr);
spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 194: /* expr ::= expr COLLATE ids */
{
yygotominor.yy342.pExpr = sqlite3ExprSetCollByToken(pParse, yymsp[-2].minor.yy342.pExpr, &yymsp[0].minor.yy0);
yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 195: /* expr ::= CAST LP expr AS typetoken RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy342.pExpr, 0, &yymsp[-1].minor.yy0);
spanSet(&yygotominor.yy342,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 196: /* expr ::= ID LP distinct exprlist RP */
{
if( yymsp[-1].minor.yy442 && yymsp[-1].minor.yy442->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy442, &yymsp[-4].minor.yy0);
spanSet(&yygotominor.yy342,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
if( yymsp[-2].minor.yy392 && yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->flags |= EP_Distinct;
}
}
break;
case 197: /* expr ::= ID LP STAR RP */
{
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
spanSet(&yygotominor.yy342,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
break;
case 198: /* term ::= CTIME_KW */
{
/* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are
** treated as functions that return constants */
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->op = TK_CONST_FUNC;
}
spanSet(&yygotominor.yy342, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 199: /* expr ::= expr AND expr */
case 200: /* expr ::= expr OR expr */ yytestcase(yyruleno==200);
case 201: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==201);
case 202: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==202);
case 203: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==203);
case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204);
case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205);
case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206);
{spanBinaryExpr(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);}
break;
case 207: /* likeop ::= LIKE_KW */
case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209);
{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 0;}
break;
case 208: /* likeop ::= NOT LIKE_KW */
case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210);
{yygotominor.yy318.eOperator = yymsp[0].minor.yy0; yygotominor.yy318.bNot = 1;}
break;
case 211: /* expr ::= expr likeop expr */
{
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy342.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy342.pExpr);
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy318.eOperator);
if( yymsp[-1].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-2].minor.yy342.zStart;
yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
}
break;
case 212: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy342.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
yygotominor.yy342.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy318.eOperator);
if( yymsp[-3].minor.yy318.bNot ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
if( yygotominor.yy342.pExpr ) yygotominor.yy342.pExpr->flags |= EP_InfixFunc;
}
break;
case 213: /* expr ::= expr ISNULL|NOTNULL */
{spanUnaryPostfix(&yygotominor.yy342,pParse,yymsp[0].major,&yymsp[-1].minor.yy342,&yymsp[0].minor.yy0);}
break;
case 214: /* expr ::= expr NOT NULL */
{spanUnaryPostfix(&yygotominor.yy342,pParse,TK_NOTNULL,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy0);}
break;
case 215: /* expr ::= expr IS expr */
{
spanBinaryExpr(&yygotominor.yy342,pParse,TK_IS,&yymsp[-2].minor.yy342,&yymsp[0].minor.yy342);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_ISNULL);
}
break;
case 216: /* expr ::= expr IS NOT expr */
{
spanBinaryExpr(&yygotominor.yy342,pParse,TK_ISNOT,&yymsp[-3].minor.yy342,&yymsp[0].minor.yy342);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy342.pExpr, yygotominor.yy342.pExpr, TK_NOTNULL);
}
break;
case 217: /* expr ::= NOT expr */
case 218: /* expr ::= BITNOT expr */ yytestcase(yyruleno==218);
{spanUnaryPrefix(&yygotominor.yy342,pParse,yymsp[-1].major,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
break;
case 219: /* expr ::= MINUS expr */
{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UMINUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
break;
case 220: /* expr ::= PLUS expr */
{spanUnaryPrefix(&yygotominor.yy342,pParse,TK_UPLUS,&yymsp[0].minor.yy342,&yymsp[-1].minor.yy0);}
break;
case 223: /* expr ::= expr between_op expr AND expr */
{
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy342.pExpr);
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy342.pExpr, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = yymsp[0].minor.yy342.zEnd;
}
break;
case 226: /* expr ::= expr in_op LP exprlist RP */
{
if( yymsp[-1].minor.yy442==0 ){
/* Expressions of the form
**
** expr1 IN ()
** expr1 NOT IN ()
**
|
| ︙ | ︙ | |||
110811 110812 110813 110814 110815 110816 110817 |
}
if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
}
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | 111776 111777 111778 111779 111780 111781 111782 111783 111784 111785 111786 111787 111788 111789 111790 111791 111792 111793 111794 111795 111796 111797 111798 111799 111800 111801 111802 111803 111804 111805 111806 111807 111808 111809 111810 111811 111812 111813 111814 111815 111816 111817 111818 111819 111820 111821 111822 111823 111824 111825 111826 111827 111828 111829 111830 111831 111832 111833 111834 111835 111836 111837 111838 111839 111840 111841 111842 111843 111844 111845 111846 111847 111848 111849 111850 111851 111852 111853 111854 111855 111856 111857 111858 111859 111860 111861 111862 111863 111864 111865 111866 111867 111868 111869 111870 111871 111872 111873 111874 111875 111876 111877 111878 111879 111880 111881 111882 111883 111884 111885 111886 111887 111888 111889 111890 111891 111892 111893 111894 111895 111896 111897 111898 111899 111900 111901 111902 111903 111904 111905 111906 111907 111908 111909 111910 111911 111912 111913 111914 111915 111916 111917 111918 111919 111920 111921 111922 111923 111924 111925 111926 111927 111928 111929 111930 111931 111932 111933 111934 111935 111936 111937 111938 111939 111940 111941 111942 111943 111944 111945 111946 111947 111948 111949 111950 111951 111952 111953 111954 111955 111956 111957 111958 111959 111960 111961 111962 111963 111964 111965 111966 111967 111968 111969 111970 111971 111972 111973 111974 111975 111976 111977 111978 111979 111980 111981 111982 111983 111984 111985 111986 111987 111988 111989 111990 111991 111992 111993 111994 111995 111996 111997 111998 111999 112000 112001 112002 112003 112004 112005 112006 112007 112008 112009 112010 112011 112012 112013 112014 112015 112016 112017 112018 112019 112020 112021 112022 112023 112024 112025 112026 112027 112028 112029 112030 112031 112032 112033 112034 112035 112036 112037 112038 112039 112040 112041 112042 112043 112044 112045 112046 112047 112048 112049 112050 112051 112052 112053 112054 112055 112056 112057 112058 112059 112060 112061 112062 112063 112064 112065 112066 112067 112068 112069 112070 112071 112072 112073 112074 112075 112076 112077 112078 112079 112080 112081 112082 112083 112084 112085 112086 112087 112088 112089 112090 112091 112092 112093 112094 112095 112096 112097 112098 112099 112100 112101 112102 112103 112104 112105 112106 112107 112108 112109 112110 112111 112112 112113 112114 112115 112116 112117 112118 112119 112120 112121 112122 112123 112124 112125 112126 112127 112128 112129 112130 112131 112132 112133 112134 112135 112136 112137 112138 112139 112140 112141 112142 112143 112144 112145 112146 112147 112148 112149 112150 112151 112152 112153 112154 112155 112156 112157 112158 112159 |
}
if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
}
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 227: /* expr ::= LP select RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
}
yygotominor.yy342.zStart = yymsp[-2].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 228: /* expr ::= expr in_op LP select RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy342.pExpr, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pSelect = yymsp[-1].minor.yy159;
ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
}
if( yymsp[-3].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-4].minor.yy342.zStart;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 229: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy342.pExpr, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
ExprSetProperty(yygotominor.yy342.pExpr, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
if( yymsp[-2].minor.yy392 ) yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy342.pExpr, 0, 0);
yygotominor.yy342.zStart = yymsp[-3].minor.yy342.zStart;
yygotominor.yy342.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
}
break;
case 230: /* expr ::= EXISTS LP select RP */
{
Expr *p = yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
p->x.pSelect = yymsp[-1].minor.yy159;
ExprSetProperty(p, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, p);
}else{
sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy159);
}
yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 231: /* expr ::= CASE case_operand case_exprlist case_else END */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy122, yymsp[-1].minor.yy122, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->x.pList = yymsp[-2].minor.yy442;
sqlite3ExprSetHeight(pParse, yygotominor.yy342.pExpr);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy442);
}
yygotominor.yy342.zStart = yymsp[-4].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 232: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, yymsp[-2].minor.yy342.pExpr);
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
}
break;
case 233: /* case_exprlist ::= WHEN expr THEN expr */
{
yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy342.pExpr);
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yygotominor.yy442, yymsp[0].minor.yy342.pExpr);
}
break;
case 240: /* nexprlist ::= nexprlist COMMA expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
break;
case 241: /* nexprlist ::= expr */
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
break;
case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
{
sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392,
&yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
}
break;
case 243: /* uniqueflag ::= UNIQUE */
case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
{yygotominor.yy392 = OE_Abort;}
break;
case 244: /* uniqueflag ::= */
{yygotominor.yy392 = OE_None;}
break;
case 247: /* idxlist ::= idxlist COMMA nm collate sortorder */
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
p = sqlite3Expr(pParse->db, TK_COLUMN, 0);
sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
}
yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy442, p);
sqlite3ExprListSetName(pParse,yygotominor.yy442,&yymsp[-2].minor.yy0,1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
}
break;
case 248: /* idxlist ::= nm collate sortorder */
{
Expr *p = 0;
if( yymsp[-1].minor.yy0.n>0 ){
p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
sqlite3ExprSetCollByToken(pParse, p, &yymsp[-1].minor.yy0);
}
yygotominor.yy442 = sqlite3ExprListAppend(pParse,0, p);
sqlite3ExprListSetName(pParse, yygotominor.yy442, &yymsp[-2].minor.yy0, 1);
sqlite3ExprListCheckLength(pParse, yygotominor.yy442, "index");
if( yygotominor.yy442 ) yygotominor.yy442->a[yygotominor.yy442->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy392;
}
break;
case 249: /* collate ::= */
{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
break;
case 251: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy347, yymsp[-1].minor.yy392);}
break;
case 252: /* cmd ::= VACUUM */
case 253: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==253);
{sqlite3Vacuum(pParse);}
break;
case 254: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
case 255: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
case 256: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
case 257: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
case 258: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
case 268: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy327, &all);
}
break;
case 269: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy392, yymsp[-4].minor.yy410.a, yymsp[-4].minor.yy410.b, yymsp[-2].minor.yy347, yymsp[0].minor.yy122, yymsp[-10].minor.yy392, yymsp[-8].minor.yy392);
yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
}
break;
case 270: /* trigger_time ::= BEFORE */
case 273: /* trigger_time ::= */ yytestcase(yyruleno==273);
{ yygotominor.yy392 = TK_BEFORE; }
break;
case 271: /* trigger_time ::= AFTER */
{ yygotominor.yy392 = TK_AFTER; }
break;
case 272: /* trigger_time ::= INSTEAD OF */
{ yygotominor.yy392 = TK_INSTEAD;}
break;
case 274: /* trigger_event ::= DELETE|INSERT */
case 275: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==275);
{yygotominor.yy410.a = yymsp[0].major; yygotominor.yy410.b = 0;}
break;
case 276: /* trigger_event ::= UPDATE OF inscollist */
{yygotominor.yy410.a = TK_UPDATE; yygotominor.yy410.b = yymsp[0].minor.yy180;}
break;
case 279: /* when_clause ::= */
case 301: /* key_opt ::= */ yytestcase(yyruleno==301);
{ yygotominor.yy122 = 0; }
break;
case 280: /* when_clause ::= WHEN expr */
case 302: /* key_opt ::= KEY expr */ yytestcase(yyruleno==302);
{ yygotominor.yy122 = yymsp[0].minor.yy342.pExpr; }
break;
case 281: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
assert( yymsp[-2].minor.yy327!=0 );
yymsp[-2].minor.yy327->pLast->pNext = yymsp[-1].minor.yy327;
yymsp[-2].minor.yy327->pLast = yymsp[-1].minor.yy327;
yygotominor.yy327 = yymsp[-2].minor.yy327;
}
break;
case 282: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
assert( yymsp[-1].minor.yy327!=0 );
yymsp[-1].minor.yy327->pLast = yymsp[-1].minor.yy327;
yygotominor.yy327 = yymsp[-1].minor.yy327;
}
break;
case 284: /* trnm ::= nm DOT nm */
{
yygotominor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
"statements within triggers");
}
break;
case 286: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
case 287: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
case 288: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
{ yygotominor.yy327 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy442, yymsp[0].minor.yy122, yymsp[-5].minor.yy258); }
break;
case 289: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */
{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, yymsp[0].minor.yy487.pList, yymsp[0].minor.yy487.pSelect, yymsp[-4].minor.yy258);}
break;
case 290: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
{yygotominor.yy327 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy180, 0, yymsp[0].minor.yy159, yymsp[-4].minor.yy258);}
break;
case 291: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
{yygotominor.yy327 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy122);}
break;
case 292: /* trigger_cmd ::= select */
{yygotominor.yy327 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy159); }
break;
case 293: /* expr ::= RAISE LP IGNORE RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
if( yygotominor.yy342.pExpr ){
yygotominor.yy342.pExpr->affinity = OE_Ignore;
}
yygotominor.yy342.zStart = yymsp[-3].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 294: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
yygotominor.yy342.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
if( yygotominor.yy342.pExpr ) {
yygotominor.yy342.pExpr->affinity = (char)yymsp[-3].minor.yy392;
}
yygotominor.yy342.zStart = yymsp[-5].minor.yy0.z;
yygotominor.yy342.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
case 295: /* raisetype ::= ROLLBACK */
{yygotominor.yy392 = OE_Rollback;}
break;
case 297: /* raisetype ::= FAIL */
{yygotominor.yy392 = OE_Fail;}
break;
case 298: /* cmd ::= DROP TRIGGER ifexists fullname */
{
sqlite3DropTrigger(pParse,yymsp[0].minor.yy347,yymsp[-1].minor.yy392);
}
break;
case 299: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
sqlite3Attach(pParse, yymsp[-3].minor.yy342.pExpr, yymsp[-1].minor.yy342.pExpr, yymsp[0].minor.yy122);
}
break;
case 300: /* cmd ::= DETACH database_kw_opt expr */
{
sqlite3Detach(pParse, yymsp[0].minor.yy342.pExpr);
}
break;
case 305: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
case 306: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 307: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
case 308: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 309: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy347,&yymsp[0].minor.yy0);
}
break;
case 310: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
case 311: /* add_column_fullname ::= fullname */
{
pParse->db->lookaside.bEnabled = 0;
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy347);
}
break;
case 314: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
case 315: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
case 316: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy392);
}
break;
case 319: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
case 321: /* vtabargtoken ::= ANY */
case 322: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==322);
case 323: /* lp ::= LP */ yytestcase(yyruleno==323);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
default:
/* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
/* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
/* (2) cmdlist ::= ecmd */ yytestcase(yyruleno==2);
/* (3) ecmd ::= SEMI */ yytestcase(yyruleno==3);
/* (4) ecmd ::= explain cmdx SEMI */ yytestcase(yyruleno==4);
/* (10) trans_opt ::= */ yytestcase(yyruleno==10);
/* (11) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==11);
/* (12) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==12);
/* (20) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==20);
/* (21) savepoint_opt ::= */ yytestcase(yyruleno==21);
/* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
/* (34) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==34);
/* (35) columnlist ::= column */ yytestcase(yyruleno==35);
/* (44) type ::= */ yytestcase(yyruleno==44);
/* (51) signed ::= plus_num */ yytestcase(yyruleno==51);
/* (52) signed ::= minus_num */ yytestcase(yyruleno==52);
/* (53) carglist ::= carglist ccons */ yytestcase(yyruleno==53);
/* (54) carglist ::= */ yytestcase(yyruleno==54);
/* (61) ccons ::= NULL onconf */ yytestcase(yyruleno==61);
/* (89) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==89);
/* (90) conslist ::= tcons */ yytestcase(yyruleno==90);
/* (92) tconscomma ::= */ yytestcase(yyruleno==92);
/* (277) foreach_clause ::= */ yytestcase(yyruleno==277);
/* (278) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==278);
/* (285) tridxby ::= */ yytestcase(yyruleno==285);
/* (303) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==303);
/* (304) database_kw_opt ::= */ yytestcase(yyruleno==304);
/* (312) kwcolumn_opt ::= */ yytestcase(yyruleno==312);
/* (313) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==313);
/* (317) vtabarglist ::= vtabarg */ yytestcase(yyruleno==317);
/* (318) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==318);
/* (320) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==320);
/* (324) anylist ::= */ yytestcase(yyruleno==324);
/* (325) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==325);
/* (326) anylist ::= anylist ANY */ yytestcase(yyruleno==326);
break;
};
yygoto = yyRuleInfo[yyruleno].lhs;
yysize = yyRuleInfo[yyruleno].nrhs;
yypParser->yyidx -= yysize;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
if( yyact < YYNSTATE ){
|
| ︙ | ︙ | |||
112689 112690 112691 112692 112693 112694 112695 112696 112697 112698 112699 112700 112701 112702 | ** name of a directory, then that directory will be used to store ** temporary files. ** ** See also the "PRAGMA temp_store_directory" SQL command. */ SQLITE_API char *sqlite3_temp_directory = 0; /* ** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as | > > > > > > > > > | 113655 113656 113657 113658 113659 113660 113661 113662 113663 113664 113665 113666 113667 113668 113669 113670 113671 113672 113673 113674 113675 113676 113677 | ** name of a directory, then that directory will be used to store ** temporary files. ** ** See also the "PRAGMA temp_store_directory" SQL command. */ SQLITE_API char *sqlite3_temp_directory = 0; /* ** If the following global variable points to a string which is the ** name of a directory, then that directory will be used to store ** all database files specified with a relative pathname. ** ** See also the "PRAGMA data_store_directory" SQL command. */ SQLITE_API char *sqlite3_data_directory = 0; /* ** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as |
| ︙ | ︙ | |||
112887 112888 112889 112890 112891 112892 112893 112894 112895 112896 112897 112898 112899 112900 |
if( sqlite3GlobalConfig.isPCacheInit ){
sqlite3PcacheShutdown();
sqlite3GlobalConfig.isPCacheInit = 0;
}
if( sqlite3GlobalConfig.isMallocInit ){
sqlite3MallocEnd();
sqlite3GlobalConfig.isMallocInit = 0;
}
if( sqlite3GlobalConfig.isMutexInit ){
sqlite3MutexEnd();
sqlite3GlobalConfig.isMutexInit = 0;
}
return SQLITE_OK;
| > > > > > > > > > > > > | 113862 113863 113864 113865 113866 113867 113868 113869 113870 113871 113872 113873 113874 113875 113876 113877 113878 113879 113880 113881 113882 113883 113884 113885 113886 113887 |
if( sqlite3GlobalConfig.isPCacheInit ){
sqlite3PcacheShutdown();
sqlite3GlobalConfig.isPCacheInit = 0;
}
if( sqlite3GlobalConfig.isMallocInit ){
sqlite3MallocEnd();
sqlite3GlobalConfig.isMallocInit = 0;
#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES
/* The heap subsystem has now been shutdown and these values are supposed
** to be NULL or point to memory that was obtained from sqlite3_malloc(),
** which would rely on that heap subsystem; therefore, make sure these
** values cannot refer to heap memory that was just invalidated when the
** heap subsystem was shutdown. This is only done if the current call to
** this function resulted in the heap subsystem actually being shutdown.
*/
sqlite3_data_directory = 0;
sqlite3_temp_directory = 0;
#endif
}
if( sqlite3GlobalConfig.isMutexInit ){
sqlite3MutexEnd();
sqlite3GlobalConfig.isMutexInit = 0;
}
return SQLITE_OK;
|
| ︙ | ︙ | |||
113334 113335 113336 113337 113338 113339 113340 113341 113342 113343 113344 113345 113346 113347 113348 113349 113350 113351 113352 113353 113354 113355 113356 |
pDestructor->nRef--;
if( pDestructor->nRef==0 ){
pDestructor->xDestroy(pDestructor->pUserData);
sqlite3DbFree(db, pDestructor);
}
}
}
/*
** Close an existing SQLite database
*/
SQLITE_API int sqlite3_close(sqlite3 *db){
HashElem *i; /* Hash table iterator */
int j;
if( !db ){
return SQLITE_OK;
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
| > > > > > > > > > > > > > > > > > > > > > > > > | | | | 114321 114322 114323 114324 114325 114326 114327 114328 114329 114330 114331 114332 114333 114334 114335 114336 114337 114338 114339 114340 114341 114342 114343 114344 114345 114346 114347 114348 114349 114350 114351 114352 114353 114354 114355 114356 114357 114358 114359 114360 114361 114362 114363 114364 114365 114366 114367 114368 114369 114370 114371 114372 114373 114374 114375 114376 114377 114378 |
pDestructor->nRef--;
if( pDestructor->nRef==0 ){
pDestructor->xDestroy(pDestructor->pUserData);
sqlite3DbFree(db, pDestructor);
}
}
}
/*
** Disconnect all sqlite3_vtab objects that belong to database connection
** db. This is called when db is being closed.
*/
static void disconnectAllVtab(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
int i;
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
if( db->aDb[i].pSchema ){
HashElem *p;
for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
Table *pTab = (Table *)sqliteHashData(p);
if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
}
}
}
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
#endif
}
/*
** Close an existing SQLite database
*/
SQLITE_API int sqlite3_close(sqlite3 *db){
HashElem *i; /* Hash table iterator */
int j;
if( !db ){
return SQLITE_OK;
}
if( !sqlite3SafetyCheckSickOrOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
/* Force xDisconnect calls on all virtual tables */
disconnectAllVtab(db);
/* If a transaction is open, the disconnectAllVtab() call above
** will not have called the xDisconnect() method on any virtual
** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
** call will do so. We need to do this before the check for active
** SQL statements below, as the v-table implementation may be storing
** some prepared statements internally.
*/
sqlite3VtabRollback(db);
|
| ︙ | ︙ | |||
113384 113385 113386 113387 113388 113389 113390 113391 113392 113393 113394 113395 113396 113397 113398 113399 113400 |
return SQLITE_BUSY;
}
}
/* Free any outstanding Savepoint structures. */
sqlite3CloseSavepoints(db);
for(j=0; j<db->nDb; j++){
struct Db *pDb = &db->aDb[j];
if( pDb->pBt ){
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
if( j!=1 ){
pDb->pSchema = 0;
}
}
}
| > > > > > > | > > > > < < | 114395 114396 114397 114398 114399 114400 114401 114402 114403 114404 114405 114406 114407 114408 114409 114410 114411 114412 114413 114414 114415 114416 114417 114418 114419 114420 114421 114422 114423 114424 114425 114426 114427 114428 114429 114430 114431 114432 114433 114434 114435 |
return SQLITE_BUSY;
}
}
/* Free any outstanding Savepoint structures. */
sqlite3CloseSavepoints(db);
/* Close all database connections */
for(j=0; j<db->nDb; j++){
struct Db *pDb = &db->aDb[j];
if( pDb->pBt ){
sqlite3BtreeClose(pDb->pBt);
pDb->pBt = 0;
if( j!=1 ){
pDb->pSchema = 0;
}
}
}
/* Clear the TEMP schema separately and last */
if( db->aDb[1].pSchema ){
sqlite3SchemaClear(db->aDb[1].pSchema);
}
sqlite3VtabUnlockList(db);
/* Free up the array of auxiliary databases */
sqlite3CollapseDatabaseArray(db);
assert( db->nDb<=2 );
assert( db->aDb==db->aDbStatic );
/* Tell the code in notify.c that the connection no longer holds any
** locks and does not require any further unlock-notify callbacks.
*/
sqlite3ConnectionClosed(db);
for(j=0; j<ArraySize(db->aFunc.a); j++){
FuncDef *pNext, *pHash, *p;
for(p=db->aFunc.a[j]; p; p=pHash){
pHash = p->pHash;
while( p ){
functionDestroy(db, p);
pNext = p->pNext;
|
| ︙ | ︙ | |||
113489 113490 113491 113492 113493 113494 113495 |
}
}
sqlite3VtabRollback(db);
sqlite3EndBenignMalloc();
if( db->flags&SQLITE_InternChanges ){
sqlite3ExpirePreparedStatements(db);
| | | 114508 114509 114510 114511 114512 114513 114514 114515 114516 114517 114518 114519 114520 114521 114522 |
}
}
sqlite3VtabRollback(db);
sqlite3EndBenignMalloc();
if( db->flags&SQLITE_InternChanges ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
}
/* Any deferred constraint violations have now been resolved. */
db->nDeferredCons = 0;
/* If one has been configured, invoke the rollback-hook callback */
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
|
| ︙ | ︙ | |||
114627 114628 114629 114630 114631 114632 114633 114634 114635 114636 |
zModeType = "cache";
}
if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){
static struct OpenMode aOpenMode[] = {
{ "ro", SQLITE_OPEN_READONLY },
{ "rw", SQLITE_OPEN_READWRITE },
{ "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
{ 0, 0 }
};
| > > > | > | > | 115646 115647 115648 115649 115650 115651 115652 115653 115654 115655 115656 115657 115658 115659 115660 115661 115662 115663 115664 115665 115666 115667 115668 115669 115670 115671 115672 115673 115674 115675 115676 115677 115678 115679 115680 115681 115682 115683 115684 115685 115686 115687 115688 115689 115690 115691 115692 115693 115694 115695 115696 115697 115698 115699 115700 115701 115702 115703 115704 115705 115706 115707 |
zModeType = "cache";
}
if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){
static struct OpenMode aOpenMode[] = {
{ "ro", SQLITE_OPEN_READONLY },
{ "rw", SQLITE_OPEN_READWRITE },
{ "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
{ "memory",
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
| SQLITE_OPEN_MEMORY },
{ 0, 0 }
};
mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY;
aMode = aOpenMode;
limit = mask & flags;
zModeType = "access";
}
if( aMode ){
int i;
int mode = 0;
for(i=0; aMode[i].z; i++){
const char *z = aMode[i].z;
if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){
mode = aMode[i].mode;
break;
}
}
if( mode==0 ){
*pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal);
rc = SQLITE_ERROR;
goto parse_uri_out;
}
if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){
*pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s",
zModeType, zVal);
rc = SQLITE_PERM;
goto parse_uri_out;
}
flags = (flags & ~mask) | mode;
}
}
zOpt = &zVal[nVal+1];
}
}else{
zFile = sqlite3_malloc(nUri+2);
if( !zFile ) return SQLITE_NOMEM;
memcpy(zFile, zUri, nUri);
zFile[nUri] = '\0';
zFile[nUri+1] = '\0';
flags &= ~SQLITE_OPEN_URI;
}
*ppVfs = sqlite3_vfs_find(zVfs);
if( *ppVfs==0 ){
*pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs);
rc = SQLITE_ERROR;
}
|
| ︙ | ︙ | |||
117109 117110 117111 117112 117113 117114 117115 |
SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart(
Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
| | > > > > > > > | 118133 118134 118135 118136 118137 118138 118139 118140 118141 118142 118143 118144 118145 118146 118147 118148 118149 118150 118151 118152 118153 118154 118155 118156 118157 118158 |
SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart(
Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **);
SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int);
SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
#endif
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
#endif /* _FTSINT_H */
/************** End of fts3Int.h *********************************************/
/************** Continuing where we left off in fts3.c ***********************/
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
|
| ︙ | ︙ | |||
120383 120384 120385 120386 120387 120388 120389 120390 120391 120392 120393 120394 120395 120396 120397 120398 120399 120400 120401 120402 120403 120404 120405 120406 120407 120408 120409 120410 120411 120412 120413 120414 120415 120416 |
**
** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
** to by the argument to point to the "simple" tokenizer implementation.
** And so on.
*/
SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#ifdef SQLITE_ENABLE_ICU
SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#endif
/*
** Initialise the fts3 extension. If this extension is built as part
** of the sqlite library, then this function is called directly by
** SQLite. If fts3 is built as a dynamically loadable extension, this
** function is called by the sqlite3_extension_init() entry point.
*/
SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
int rc = SQLITE_OK;
Fts3Hash *pHash = 0;
const sqlite3_tokenizer_module *pSimple = 0;
const sqlite3_tokenizer_module *pPorter = 0;
#ifdef SQLITE_ENABLE_ICU
const sqlite3_tokenizer_module *pIcu = 0;
sqlite3Fts3IcuTokenizerModule(&pIcu);
#endif
#ifdef SQLITE_TEST
rc = sqlite3Fts3InitTerm(db);
if( rc!=SQLITE_OK ) return rc;
#endif
rc = sqlite3Fts3InitAux(db);
| > > > > > > > > > > | 121414 121415 121416 121417 121418 121419 121420 121421 121422 121423 121424 121425 121426 121427 121428 121429 121430 121431 121432 121433 121434 121435 121436 121437 121438 121439 121440 121441 121442 121443 121444 121445 121446 121447 121448 121449 121450 121451 121452 121453 121454 121455 121456 121457 |
**
** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
** to by the argument to point to the "simple" tokenizer implementation.
** And so on.
*/
SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule);
#endif
#ifdef SQLITE_ENABLE_ICU
SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#endif
/*
** Initialise the fts3 extension. If this extension is built as part
** of the sqlite library, then this function is called directly by
** SQLite. If fts3 is built as a dynamically loadable extension, this
** function is called by the sqlite3_extension_init() entry point.
*/
SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
int rc = SQLITE_OK;
Fts3Hash *pHash = 0;
const sqlite3_tokenizer_module *pSimple = 0;
const sqlite3_tokenizer_module *pPorter = 0;
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
const sqlite3_tokenizer_module *pUnicode = 0;
#endif
#ifdef SQLITE_ENABLE_ICU
const sqlite3_tokenizer_module *pIcu = 0;
sqlite3Fts3IcuTokenizerModule(&pIcu);
#endif
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
sqlite3Fts3UnicodeTokenizer(&pUnicode);
#endif
#ifdef SQLITE_TEST
rc = sqlite3Fts3InitTerm(db);
if( rc!=SQLITE_OK ) return rc;
#endif
rc = sqlite3Fts3InitAux(db);
|
| ︙ | ︙ | |||
120427 120428 120429 120430 120431 120432 120433 120434 120435 120436 120437 120438 120439 120440 |
sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
}
/* Load the built-in tokenizers into the hash table */
if( rc==SQLITE_OK ){
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
#ifdef SQLITE_ENABLE_ICU
|| (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
#endif
){
rc = SQLITE_NOMEM;
}
}
| > > > > | 121468 121469 121470 121471 121472 121473 121474 121475 121476 121477 121478 121479 121480 121481 121482 121483 121484 121485 |
sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
}
/* Load the built-in tokenizers into the hash table */
if( rc==SQLITE_OK ){
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
|| sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode)
#endif
#ifdef SQLITE_ENABLE_ICU
|| (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
#endif
){
rc = SQLITE_NOMEM;
}
}
|
| ︙ | ︙ | |||
120774 120775 120776 120777 120778 120779 120780 | */ SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( int bDescIdx, /* True if the doclist is desc */ char *aDoclist, /* Pointer to entire doclist */ int nDoclist, /* Length of aDoclist in bytes */ char **ppIter, /* IN/OUT: Iterator pointer */ sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ | | | 121819 121820 121821 121822 121823 121824 121825 121826 121827 121828 121829 121830 121831 121832 121833 |
*/
SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(
int bDescIdx, /* True if the doclist is desc */
char *aDoclist, /* Pointer to entire doclist */
int nDoclist, /* Length of aDoclist in bytes */
char **ppIter, /* IN/OUT: Iterator pointer */
sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */
int *pnList, /* OUT: List length pointer */
u8 *pbEof /* OUT: End-of-file flag */
){
char *p = *ppIter;
assert( nDoclist>0 );
assert( *pbEof==0 );
assert( p || *piDocid==0 );
|
| ︙ | ︙ | |||
120820 120821 120822 120823 120824 120825 120826 120827 120828 120829 120830 120831 120832 120833 |
char *pSave = p;
fts3ReversePoslist(aDoclist, &p);
*pnList = (int)(pSave - p);
}
*ppIter = p;
}
}
/*
** Attempt to move the phrase iterator to point to the next matching docid.
** If an error occurs, return an SQLite error code. Otherwise, return
** SQLITE_OK.
**
** If there is no "next" entry and no error occurs, then *pbEof is set to
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 121865 121866 121867 121868 121869 121870 121871 121872 121873 121874 121875 121876 121877 121878 121879 121880 121881 121882 121883 121884 121885 121886 121887 121888 121889 121890 121891 121892 121893 121894 121895 121896 121897 121898 121899 121900 121901 121902 121903 121904 121905 121906 121907 121908 121909 121910 121911 121912 121913 |
char *pSave = p;
fts3ReversePoslist(aDoclist, &p);
*pnList = (int)(pSave - p);
}
*ppIter = p;
}
}
/*
** Iterate forwards through a doclist.
*/
SQLITE_PRIVATE void sqlite3Fts3DoclistNext(
int bDescIdx, /* True if the doclist is desc */
char *aDoclist, /* Pointer to entire doclist */
int nDoclist, /* Length of aDoclist in bytes */
char **ppIter, /* IN/OUT: Iterator pointer */
sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */
u8 *pbEof /* OUT: End-of-file flag */
){
char *p = *ppIter;
assert( nDoclist>0 );
assert( *pbEof==0 );
assert( p || *piDocid==0 );
assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) );
if( p==0 ){
p = aDoclist;
p += sqlite3Fts3GetVarint(p, piDocid);
}else{
fts3PoslistCopy(0, &p);
if( p>=&aDoclist[nDoclist] ){
*pbEof = 1;
}else{
sqlite3_int64 iVar;
p += sqlite3Fts3GetVarint(p, &iVar);
*piDocid += ((bDescIdx ? -1 : 1) * iVar);
}
}
*ppIter = p;
}
/*
** Attempt to move the phrase iterator to point to the next matching docid.
** If an error occurs, return an SQLite error code. Otherwise, return
** SQLITE_OK.
**
** If there is no "next" entry and no error occurs, then *pbEof is set to
|
| ︙ | ︙ | |||
121976 121977 121978 121979 121980 121981 121982 | ** for 'X' is requested, the buffer returned may contain: ** ** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00 ** ** This function works regardless of whether or not the phrase is deferred, ** incremental, or neither. */ | | | > | > > > > > > > | | > | > > > > | > > > > > > > | > > > > > > > > > > > > > | | > > > > | > > > > > > > > > > > > > > > > > > > > > > > > | > | 123056 123057 123058 123059 123060 123061 123062 123063 123064 123065 123066 123067 123068 123069 123070 123071 123072 123073 123074 123075 123076 123077 123078 123079 123080 123081 123082 123083 123084 123085 123086 123087 123088 123089 123090 123091 123092 123093 123094 123095 123096 123097 123098 123099 123100 123101 123102 123103 123104 123105 123106 123107 123108 123109 123110 123111 123112 123113 123114 123115 123116 123117 123118 123119 123120 123121 123122 123123 123124 123125 123126 123127 123128 123129 123130 123131 123132 123133 123134 123135 123136 123137 123138 123139 123140 123141 123142 123143 123144 123145 123146 123147 123148 123149 123150 123151 123152 123153 123154 123155 123156 123157 123158 123159 123160 123161 123162 123163 123164 123165 |
** for 'X' is requested, the buffer returned may contain:
**
** 0x04 0x05 0x03 0x01 or 0x04 0x05 0x03 0x00
**
** This function works regardless of whether or not the phrase is deferred,
** incremental, or neither.
*/
SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
Fts3Cursor *pCsr, /* FTS3 cursor object */
Fts3Expr *pExpr, /* Phrase to return doclist for */
int iCol, /* Column to return position list for */
char **ppOut /* OUT: Pointer to position list */
){
Fts3Phrase *pPhrase = pExpr->pPhrase;
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
char *pIter;
int iThis;
sqlite3_int64 iDocid;
/* If this phrase is applies specifically to some column other than
** column iCol, return a NULL pointer. */
*ppOut = 0;
assert( iCol>=0 && iCol<pTab->nColumn );
if( (pPhrase->iColumn<pTab->nColumn && pPhrase->iColumn!=iCol) ){
return SQLITE_OK;
}
iDocid = pExpr->iDocid;
pIter = pPhrase->doclist.pList;
if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */
int bOr = 0;
u8 bEof = 0;
Fts3Expr *p;
/* Check if this phrase descends from an OR expression node. If not,
** return NULL. Otherwise, the entry that corresponds to docid
** pCsr->iPrevId may lie earlier in the doclist buffer. */
for(p=pExpr->pParent; p; p=p->pParent){
if( p->eType==FTSQUERY_OR ) bOr = 1;
}
if( bOr==0 ) return SQLITE_OK;
/* This is the descendent of an OR node. In this case we cannot use
** an incremental phrase. Load the entire doclist for the phrase
** into memory in this case. */
if( pPhrase->bIncr ){
int rc = SQLITE_OK;
int bEofSave = pExpr->bEof;
fts3EvalRestart(pCsr, pExpr, &rc);
while( rc==SQLITE_OK && !pExpr->bEof ){
fts3EvalNextRow(pCsr, pExpr, &rc);
if( bEofSave==0 && pExpr->iDocid==iDocid ) break;
}
pIter = pPhrase->doclist.pList;
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
if( rc!=SQLITE_OK ) return rc;
}
if( pExpr->bEof ){
pIter = 0;
iDocid = 0;
}
bEof = (pPhrase->doclist.nAll==0);
assert( bDescDoclist==0 || bDescDoclist==1 );
assert( pCsr->bDesc==0 || pCsr->bDesc==1 );
if( pCsr->bDesc==bDescDoclist ){
int dummy;
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
sqlite3Fts3DoclistPrev(
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
&pIter, &iDocid, &dummy, &bEof
);
}
}else{
while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
sqlite3Fts3DoclistNext(
bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll,
&pIter, &iDocid, &bEof
);
}
}
if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
}
if( pIter==0 ) return SQLITE_OK;
if( *pIter==0x01 ){
pIter++;
pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
}else{
iThis = 0;
}
while( iThis<iCol ){
fts3ColumnlistCopy(0, &pIter);
if( *pIter==0x00 ) return 0;
pIter++;
pIter += sqlite3Fts3GetVarint32(pIter, &iThis);
}
*ppOut = ((iCol==iThis)?pIter:0);
return SQLITE_OK;
}
/*
** Free all components of the Fts3Phrase structure that were allocated by
** the eval module. Specifically, this means to free:
**
** * the contents of pPhrase->doclist, and
|
| ︙ | ︙ | |||
128482 128483 128484 128485 128486 128487 128488 |
if( sqlite3_step(pStmt)==SQLITE_ROW ){
fts3DecodeIntArray(nStat, a,
sqlite3_column_blob(pStmt, 0),
sqlite3_column_bytes(pStmt, 0));
}else{
memset(a, 0, sizeof(u32)*(nStat) );
}
| | > > > > > | 129624 129625 129626 129627 129628 129629 129630 129631 129632 129633 129634 129635 129636 129637 129638 129639 129640 129641 129642 129643 |
if( sqlite3_step(pStmt)==SQLITE_ROW ){
fts3DecodeIntArray(nStat, a,
sqlite3_column_blob(pStmt, 0),
sqlite3_column_bytes(pStmt, 0));
}else{
memset(a, 0, sizeof(u32)*(nStat) );
}
rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ){
sqlite3_free(a);
*pRC = rc;
return;
}
if( nChng<0 && a[0]<(u32)(-nChng) ){
a[0] = 0;
}else{
a[0] += nChng;
}
for(i=0; i<p->nColumn+1; i++){
u32 x = a[i+1];
|
| ︙ | ︙ | |||
129047 129048 129049 129050 129051 129052 129053 |
}
/* Advance to the next output block */
pLeaf->iBlock++;
pLeaf->key.n = 0;
pLeaf->block.n = 0;
| < | 130194 130195 130196 130197 130198 130199 130200 130201 130202 130203 130204 130205 130206 130207 |
}
/* Advance to the next output block */
pLeaf->iBlock++;
pLeaf->key.n = 0;
pLeaf->block.n = 0;
nSuffix = nTerm;
nSpace = 1;
nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist;
}
blobGrowBuffer(&pLeaf->block, pLeaf->block.n + nSpace, &rc);
|
| ︙ | ︙ | |||
131057 131058 131059 131060 131061 131062 131063 131064 131065 |
** This function is an fts3ExprIterate() callback used by fts3BestSnippet().
** Each invocation populates an element of the SnippetIter.aPhrase[] array.
*/
static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
SnippetIter *p = (SnippetIter *)ctx;
SnippetPhrase *pPhrase = &p->aPhrase[iPhrase];
char *pCsr;
pPhrase->nToken = pExpr->pPhrase->nToken;
| > < | > > | > | | 132203 132204 132205 132206 132207 132208 132209 132210 132211 132212 132213 132214 132215 132216 132217 132218 132219 132220 132221 132222 132223 132224 132225 132226 132227 132228 132229 132230 132231 132232 132233 132234 132235 132236 132237 |
** This function is an fts3ExprIterate() callback used by fts3BestSnippet().
** Each invocation populates an element of the SnippetIter.aPhrase[] array.
*/
static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
SnippetIter *p = (SnippetIter *)ctx;
SnippetPhrase *pPhrase = &p->aPhrase[iPhrase];
char *pCsr;
int rc;
pPhrase->nToken = pExpr->pPhrase->nToken;
rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr);
assert( rc==SQLITE_OK || pCsr==0 );
if( pCsr ){
int iFirst = 0;
pPhrase->pList = pCsr;
fts3GetDeltaPosition(&pCsr, &iFirst);
assert( iFirst>=0 );
pPhrase->pHead = pCsr;
pPhrase->pTail = pCsr;
pPhrase->iHead = iFirst;
pPhrase->iTail = iFirst;
}else{
assert( rc!=SQLITE_OK || (
pPhrase->pList==0 && pPhrase->pHead==0 && pPhrase->pTail==0
));
}
return rc;
}
/*
** Select the fragment of text consisting of nFragment contiguous tokens
** from column iCol that represent the "best" snippet. The best snippet
** is the snippet with the highest score, where scores are calculated
** by adding:
|
| ︙ | ︙ | |||
131467 131468 131469 131470 131471 131472 131473 131474 131475 131476 131477 |
** array that are different for each row returned by the query.
*/
static int fts3ExprLocalHitsCb(
Fts3Expr *pExpr, /* Phrase expression node */
int iPhrase, /* Phrase number */
void *pCtx /* Pointer to MatchInfo structure */
){
MatchInfo *p = (MatchInfo *)pCtx;
int iStart = iPhrase * p->nCol * 3;
int i;
| > | | | | 132616 132617 132618 132619 132620 132621 132622 132623 132624 132625 132626 132627 132628 132629 132630 132631 132632 132633 132634 132635 132636 132637 132638 132639 132640 132641 132642 132643 132644 132645 |
** array that are different for each row returned by the query.
*/
static int fts3ExprLocalHitsCb(
Fts3Expr *pExpr, /* Phrase expression node */
int iPhrase, /* Phrase number */
void *pCtx /* Pointer to MatchInfo structure */
){
int rc = SQLITE_OK;
MatchInfo *p = (MatchInfo *)pCtx;
int iStart = iPhrase * p->nCol * 3;
int i;
for(i=0; i<p->nCol && rc==SQLITE_OK; i++){
char *pCsr;
rc = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr);
if( pCsr ){
p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr);
}else{
p->aMatchinfo[iStart+i*3] = 0;
}
}
return rc;
}
static int fts3MatchinfoCheck(
Fts3Table *pTab,
char cArg,
char **pzErr
){
|
| ︙ | ︙ | |||
131642 131643 131644 131645 131646 131647 131648 131649 |
}
for(iCol=0; iCol<pInfo->nCol; iCol++){
int nLcs = 0; /* LCS value for this column */
int nLive = 0; /* Number of iterators in aIter not at EOF */
for(i=0; i<pInfo->nPhrase; i++){
LcsIterator *pIt = &aIter[i];
| > | > | 132792 132793 132794 132795 132796 132797 132798 132799 132800 132801 132802 132803 132804 132805 132806 132807 132808 132809 |
}
for(iCol=0; iCol<pInfo->nCol; iCol++){
int nLcs = 0; /* LCS value for this column */
int nLive = 0; /* Number of iterators in aIter not at EOF */
for(i=0; i<pInfo->nPhrase; i++){
int rc;
LcsIterator *pIt = &aIter[i];
rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead);
if( rc!=SQLITE_OK ) return rc;
if( pIt->pRead ){
pIt->iPos = pIt->iPosOffset;
fts3LcsIteratorAdvance(&aIter[i]);
nLive++;
}
}
|
| ︙ | ︙ | |||
131995 131996 131997 131998 131999 132000 132001 132002 132003 |
*/
static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
TermOffsetCtx *p = (TermOffsetCtx *)ctx;
int nTerm; /* Number of tokens in phrase */
int iTerm; /* For looping through nTerm phrase terms */
char *pList; /* Pointer to position list for phrase */
int iPos = 0; /* First position in position-list */
UNUSED_PARAMETER(iPhrase);
| > | | | 133147 133148 133149 133150 133151 133152 133153 133154 133155 133156 133157 133158 133159 133160 133161 133162 133163 133164 133165 133166 133167 133168 133169 133170 133171 133172 133173 133174 133175 133176 133177 133178 |
*/
static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
TermOffsetCtx *p = (TermOffsetCtx *)ctx;
int nTerm; /* Number of tokens in phrase */
int iTerm; /* For looping through nTerm phrase terms */
char *pList; /* Pointer to position list for phrase */
int iPos = 0; /* First position in position-list */
int rc;
UNUSED_PARAMETER(iPhrase);
rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pList);
nTerm = pExpr->pPhrase->nToken;
if( pList ){
fts3GetDeltaPosition(&pList, &iPos);
assert( iPos>=0 );
}
for(iTerm=0; iTerm<nTerm; iTerm++){
TermOffset *pT = &p->aTerm[p->iTerm++];
pT->iOff = nTerm-iTerm-1;
pT->pList = pList;
pT->iPos = iPos;
}
return rc;
}
/*
** Implementation of offsets() function.
*/
SQLITE_PRIVATE void sqlite3Fts3Offsets(
sqlite3_context *pCtx, /* SQLite function call context */
|
| ︙ | ︙ | |||
132199 132200 132201 132202 132203 132204 132205 132206 132207 132208 132209 132210 132211 132212 |
sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
}
}
#endif
/************** End of fts3_snippet.c ****************************************/
/************** Begin file rtree.c *******************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 133352 133353 133354 133355 133356 133357 133358 133359 133360 133361 133362 133363 133364 133365 133366 133367 133368 133369 133370 133371 133372 133373 133374 133375 133376 133377 133378 133379 133380 133381 133382 133383 133384 133385 133386 133387 133388 133389 133390 133391 133392 133393 133394 133395 133396 133397 133398 133399 133400 133401 133402 133403 133404 133405 133406 133407 133408 133409 133410 133411 133412 133413 133414 133415 133416 133417 133418 133419 133420 133421 133422 133423 133424 133425 133426 133427 133428 133429 133430 133431 133432 133433 133434 133435 133436 133437 133438 133439 133440 133441 133442 133443 133444 133445 133446 133447 133448 133449 133450 133451 133452 133453 133454 133455 133456 133457 133458 133459 133460 133461 133462 133463 133464 133465 133466 133467 133468 133469 133470 133471 133472 133473 133474 133475 133476 133477 133478 133479 133480 133481 133482 133483 133484 133485 133486 133487 133488 133489 133490 133491 133492 133493 133494 133495 133496 133497 133498 133499 133500 133501 133502 133503 133504 133505 133506 133507 133508 133509 133510 133511 133512 133513 133514 133515 133516 133517 133518 133519 133520 133521 133522 133523 133524 133525 133526 133527 133528 133529 133530 133531 133532 133533 133534 133535 133536 133537 133538 133539 133540 133541 133542 133543 133544 133545 133546 133547 133548 133549 133550 133551 133552 133553 133554 133555 133556 133557 133558 133559 133560 133561 133562 133563 133564 133565 133566 133567 133568 133569 133570 133571 133572 133573 133574 133575 133576 133577 133578 133579 133580 133581 133582 133583 133584 133585 133586 133587 133588 133589 133590 133591 133592 133593 133594 133595 133596 133597 133598 133599 133600 133601 133602 133603 133604 133605 133606 133607 133608 133609 133610 133611 133612 133613 133614 133615 133616 133617 133618 133619 133620 133621 133622 133623 133624 133625 133626 133627 133628 133629 133630 133631 133632 133633 133634 133635 133636 133637 133638 133639 133640 133641 133642 133643 133644 133645 133646 133647 133648 133649 133650 133651 133652 133653 133654 133655 133656 133657 133658 133659 133660 133661 133662 133663 133664 133665 133666 133667 133668 133669 133670 133671 133672 133673 133674 133675 133676 133677 133678 133679 133680 133681 133682 133683 133684 133685 133686 133687 133688 133689 133690 133691 133692 133693 133694 133695 133696 133697 133698 133699 133700 133701 133702 133703 133704 133705 133706 133707 133708 133709 133710 133711 133712 133713 133714 133715 133716 133717 133718 133719 133720 133721 133722 133723 133724 133725 133726 133727 133728 133729 133730 133731 133732 133733 133734 133735 133736 133737 133738 133739 133740 133741 133742 133743 133744 133745 133746 133747 133748 133749 133750 133751 133752 133753 133754 133755 133756 133757 133758 133759 133760 133761 133762 133763 133764 133765 133766 133767 133768 133769 133770 133771 133772 133773 133774 133775 133776 133777 133778 133779 133780 133781 133782 133783 133784 133785 133786 133787 133788 133789 133790 133791 133792 133793 133794 133795 133796 133797 133798 133799 133800 133801 133802 133803 133804 133805 133806 133807 133808 133809 133810 133811 133812 133813 133814 133815 133816 133817 133818 133819 133820 133821 133822 133823 133824 133825 133826 133827 133828 133829 133830 133831 133832 133833 133834 133835 133836 133837 133838 133839 133840 133841 133842 133843 133844 133845 133846 133847 133848 133849 133850 133851 133852 133853 133854 133855 133856 133857 133858 133859 133860 133861 133862 133863 133864 133865 133866 133867 133868 133869 133870 133871 133872 133873 133874 133875 133876 133877 133878 133879 133880 133881 133882 133883 133884 133885 133886 133887 133888 133889 133890 133891 133892 133893 133894 133895 133896 133897 133898 133899 133900 133901 133902 133903 133904 133905 133906 133907 133908 133909 133910 133911 133912 133913 133914 133915 133916 133917 133918 133919 133920 133921 133922 133923 133924 133925 133926 133927 133928 133929 133930 133931 133932 133933 133934 133935 133936 133937 133938 133939 133940 133941 133942 133943 133944 133945 133946 133947 133948 133949 133950 133951 133952 133953 133954 133955 133956 133957 133958 133959 133960 133961 133962 133963 133964 133965 133966 133967 133968 133969 133970 133971 133972 133973 133974 133975 133976 133977 133978 133979 133980 133981 133982 133983 133984 133985 133986 133987 133988 133989 133990 133991 133992 133993 133994 133995 133996 133997 133998 133999 134000 134001 134002 134003 134004 134005 134006 134007 134008 134009 134010 |
sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
}
}
#endif
/************** End of fts3_snippet.c ****************************************/
/************** Begin file fts3_unicode.c ************************************/
/*
** 2012 May 24
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
**
** Implementation of the "unicode" full-text-search tokenizer.
*/
#ifdef SQLITE_ENABLE_FTS4_UNICODE61
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
/* #include <assert.h> */
/* #include <stdlib.h> */
/* #include <stdio.h> */
/* #include <string.h> */
/*
** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
** from the sqlite3 source file utf.c. If this file is compiled as part
** of the amalgamation, they are not required.
*/
#ifndef SQLITE_AMALGAMATION
static const unsigned char sqlite3Utf8Trans1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
};
#define READ_UTF8(zIn, zTerm, c) \
c = *(zIn++); \
if( c>=0xc0 ){ \
c = sqlite3Utf8Trans1[c-0xc0]; \
while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
c = (c<<6) + (0x3f & *(zIn++)); \
} \
if( c<0x80 \
|| (c&0xFFFFF800)==0xD800 \
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
}
#define WRITE_UTF8(zOut, c) { \
if( c<0x00080 ){ \
*zOut++ = (u8)(c&0xFF); \
} \
else if( c<0x00800 ){ \
*zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
} \
else if( c<0x10000 ){ \
*zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
}else{ \
*zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \
*zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
} \
}
#endif /* ifndef SQLITE_AMALGAMATION */
typedef struct unicode_tokenizer unicode_tokenizer;
typedef struct unicode_cursor unicode_cursor;
struct unicode_tokenizer {
sqlite3_tokenizer base;
int bRemoveDiacritic;
};
struct unicode_cursor {
sqlite3_tokenizer_cursor base;
const unsigned char *aInput; /* Input text being tokenized */
int nInput; /* Size of aInput[] in bytes */
int iOff; /* Current offset within aInput[] */
int iToken; /* Index of next token to be returned */
char *zToken; /* storage for current token */
int nAlloc; /* space allocated at zToken */
};
/*
** Create a new tokenizer instance.
*/
static int unicodeCreate(
int nArg, /* Size of array argv[] */
const char * const *azArg, /* Tokenizer creation arguments */
sqlite3_tokenizer **pp /* OUT: New tokenizer handle */
){
unicode_tokenizer *pNew; /* New tokenizer object */
int i;
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
if( pNew==NULL ){
return SQLITE_NOMEM;
}
memset(pNew, 0, sizeof(unicode_tokenizer));
pNew->bRemoveDiacritic = 1;
for(i=0; i<nArg; i++){
const char *z = azArg[i];
int n = strlen(z);
if( n==19 && memcmp("remove_diacritics=1", z, 19)==0 ){
pNew->bRemoveDiacritic = 1;
}
else if( n==19 && memcmp("remove_diacritics=0", z, 19)==0 ){
pNew->bRemoveDiacritic = 0;
}
else{
/* Unrecognized argument */
return SQLITE_ERROR;
}
}
*pp = &pNew->base;
return SQLITE_OK;
}
/*
** Destroy a tokenizer allocated by unicodeCreate().
*/
static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){
sqlite3_free(pTokenizer);
return SQLITE_OK;
}
/*
** Prepare to begin tokenizing a particular string. The input
** string to be tokenized is pInput[0..nBytes-1]. A cursor
** used to incrementally tokenize this string is returned in
** *ppCursor.
*/
static int unicodeOpen(
sqlite3_tokenizer *p, /* The tokenizer */
const char *aInput, /* Input string */
int nInput, /* Size of string aInput in bytes */
sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */
){
unicode_cursor *pCsr;
pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor));
if( pCsr==0 ){
return SQLITE_NOMEM;
}
memset(pCsr, 0, sizeof(unicode_cursor));
pCsr->aInput = (const unsigned char *)aInput;
if( aInput==0 ){
pCsr->nInput = 0;
}else if( nInput<0 ){
pCsr->nInput = (int)strlen(aInput);
}else{
pCsr->nInput = nInput;
}
*pp = &pCsr->base;
UNUSED_PARAMETER(p);
return SQLITE_OK;
}
/*
** Close a tokenization cursor previously opened by a call to
** simpleOpen() above.
*/
static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){
unicode_cursor *pCsr = (unicode_cursor *) pCursor;
sqlite3_free(pCsr->zToken);
sqlite3_free(pCsr);
return SQLITE_OK;
}
/*
** Extract the next token from a tokenization cursor. The cursor must
** have been opened by a prior call to simpleOpen().
*/
static int unicodeNext(
sqlite3_tokenizer_cursor *p, /* Cursor returned by simpleOpen */
const char **paToken, /* OUT: Token text */
int *pnToken, /* OUT: Number of bytes at *paToken */
int *piStart, /* OUT: Starting offset of token */
int *piEnd, /* OUT: Ending offset of token */
int *piPos /* OUT: Position integer of token */
){
unicode_cursor *pCsr = (unicode_cursor *)p;
int iCode;
char *zOut;
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
const unsigned char *zStart = z;
const unsigned char *zEnd;
const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput];
/* Scan past any delimiter characters before the start of the next token.
** Return SQLITE_DONE early if this takes us all the way to the end of
** the input. */
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
if( sqlite3FtsUnicodeIsalnum(iCode) ) break;
zStart = z;
}
if( zStart>=zTerm ) return SQLITE_DONE;
zOut = pCsr->zToken;
do {
int iOut;
/* Grow the output buffer if required. */
if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
if( !zNew ) return SQLITE_NOMEM;
zOut = &zNew[zOut - pCsr->zToken];
pCsr->zToken = zNew;
pCsr->nAlloc += 64;
}
/* Write the folded case of the last character read to the output */
zEnd = z;
iOut = sqlite3FtsUnicodeFold(iCode,
((unicode_tokenizer *)pCsr->base.pTokenizer)->bRemoveDiacritic
);
if( iOut ){
WRITE_UTF8(zOut, iOut);
}
/* If the cursor is not at EOF, read the next character */
if( z>=zTerm ) break;
READ_UTF8(z, zTerm, iCode);
}while( sqlite3FtsUnicodeIsalnum(iCode)
|| sqlite3FtsUnicodeIsdiacritic(iCode)
);
/* Set the output variables and return. */
pCsr->iOff = (z - pCsr->aInput);
*paToken = pCsr->zToken;
*pnToken = zOut - pCsr->zToken;
*piStart = (zStart - pCsr->aInput);
*piEnd = (zEnd - pCsr->aInput);
*piPos = pCsr->iToken++;
return SQLITE_OK;
}
/*
** Set *ppModule to a pointer to the sqlite3_tokenizer_module
** structure for the unicode tokenizer.
*/
SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){
static const sqlite3_tokenizer_module module = {
0,
unicodeCreate,
unicodeDestroy,
unicodeOpen,
unicodeClose,
unicodeNext,
0,
};
*ppModule = &module;
}
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
#endif /* ifndef SQLITE_ENABLE_FTS4_UNICODE61 */
/************** End of fts3_unicode.c ****************************************/
/************** Begin file fts3_unicode2.c ***********************************/
/*
** 2012 May 25
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
******************************************************************************
*/
/*
** DO NOT EDIT THIS MACHINE GENERATED FILE.
*/
#if defined(SQLITE_ENABLE_FTS4_UNICODE61)
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
/* #include <assert.h> */
/*
** Return true if the argument corresponds to a unicode codepoint
** classified as either a letter or a number. Otherwise false.
**
** The results are undefined if the value passed to this function
** is less than zero.
*/
SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){
/* Each unsigned integer in the following array corresponds to a contiguous
** range of unicode codepoints that are not either letters or numbers (i.e.
** codepoints for which this function should return 0).
**
** The most significant 22 bits in each 32-bit value contain the first
** codepoint in the range. The least significant 10 bits are used to store
** the size of the range (always at least 1). In other words, the value
** ((C<<22) + N) represents a range of N codepoints starting with codepoint
** C. It is not possible to represent a range larger than 1023 codepoints
** using this format.
*/
const static unsigned int aEntry[] = {
0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810,
0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023,
0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807,
0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405,
0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E,
0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01,
0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01,
0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016,
0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004,
0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004,
0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5,
0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01,
0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401,
0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064,
0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F,
0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009,
0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014,
0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001,
0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018,
0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401,
0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001,
0x43FFF401,
};
static const unsigned int aAscii[4] = {
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
};
if( c<128 ){
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
}else if( c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( key >= aEntry[iTest] ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( aEntry[0]<key );
assert( key>=aEntry[iRes] );
return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
}
return 1;
}
/*
** If the argument is a codepoint corresponding to a lowercase letter
** in the ASCII range with a diacritic added, return the codepoint
** of the ASCII letter only. For example, if passed 235 - "LATIN
** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER
** E"). The resuls of passing a codepoint that corresponds to an
** uppercase letter are undefined.
*/
static int remove_diacritic(int c){
unsigned short aDia[] = {
0, 1797, 1848, 1859, 1891, 1928, 1940, 1995,
2024, 2040, 2060, 2110, 2168, 2206, 2264, 2286,
2344, 2383, 2472, 2488, 2516, 2596, 2668, 2732,
2782, 2842, 2894, 2954, 2984, 3000, 3028, 3336,
3456, 3696, 3712, 3728, 3744, 3896, 3912, 3928,
3968, 4008, 4040, 4106, 4138, 4170, 4202, 4234,
4266, 4296, 4312, 4344, 4408, 4424, 4472, 4504,
6148, 6198, 6264, 6280, 6360, 6429, 6505, 6529,
61448, 61468, 61534, 61592, 61642, 61688, 61704, 61726,
61784, 61800, 61836, 61880, 61914, 61948, 61998, 62122,
62154, 62200, 62218, 62302, 62364, 62442, 62478, 62536,
62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730,
62924, 63050, 63082, 63274, 63390,
};
char aChar[] = {
'\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c',
'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r',
's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o',
'u', 'g', 'k', 'o', 'j', 'g', 'n', 'a', 'e', 'i', 'o', 'r',
'u', 's', 't', 'h', 'a', 'e', 'o', 'y', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', 'a', 'b', 'd', 'd', 'e', 'f', 'g', 'h',
'h', 'i', 'k', 'l', 'l', 'm', 'n', 'p', 'r', 'r', 's', 't',
'u', 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a',
'e', 'i', 'o', 'u', 'y',
};
unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
int iRes = 0;
int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
int iLo = 0;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( key >= aDia[iTest] ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( key>=aDia[iRes] );
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
};
/*
** Return true if the argument interpreted as a unicode codepoint
** is a diacritical modifier character.
*/
SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){
unsigned int mask0 = 0x08029FDF;
unsigned int mask1 = 0x000361F8;
if( c<768 || c>817 ) return 0;
return (c < 768+32) ?
(mask0 & (1 << (c-768))) :
(mask1 & (1 << (c-768-32)));
}
/*
** Interpret the argument as a unicode codepoint. If the codepoint
** is an upper case character that has a lower case equivalent,
** return the codepoint corresponding to the lower case version.
** Otherwise, return a copy of the argument.
**
** The results are undefined if the value passed to this function
** is less than zero.
*/
SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
**
** If the least significant bit in flags is clear, then the rule applies
** to all nRange codepoints (i.e. all nRange codepoints are upper case and
** need to be folded). Or, if it is set, then the rule only applies to
** every second codepoint in the range, starting with codepoint C.
**
** The 7 most significant bits in flags are an index into the aiOff[]
** array. If a specific codepoint C does require folding, then its lower
** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF).
**
** The contents of this array are generated by parsing the CaseFolding.txt
** file distributed as part of the "Unicode Character Database". See
** http://www.unicode.org for details.
*/
static const struct TableEntry {
unsigned short iCode;
unsigned char flags;
unsigned char nRange;
} aEntry[] = {
{65, 14, 26}, {181, 64, 1}, {192, 14, 23},
{216, 14, 7}, {256, 1, 48}, {306, 1, 6},
{313, 1, 16}, {330, 1, 46}, {376, 116, 1},
{377, 1, 6}, {383, 104, 1}, {385, 50, 1},
{386, 1, 4}, {390, 44, 1}, {391, 0, 1},
{393, 42, 2}, {395, 0, 1}, {398, 32, 1},
{399, 38, 1}, {400, 40, 1}, {401, 0, 1},
{403, 42, 1}, {404, 46, 1}, {406, 52, 1},
{407, 48, 1}, {408, 0, 1}, {412, 52, 1},
{413, 54, 1}, {415, 56, 1}, {416, 1, 6},
{422, 60, 1}, {423, 0, 1}, {425, 60, 1},
{428, 0, 1}, {430, 60, 1}, {431, 0, 1},
{433, 58, 2}, {435, 1, 4}, {439, 62, 1},
{440, 0, 1}, {444, 0, 1}, {452, 2, 1},
{453, 0, 1}, {455, 2, 1}, {456, 0, 1},
{458, 2, 1}, {459, 1, 18}, {478, 1, 18},
{497, 2, 1}, {498, 1, 4}, {502, 122, 1},
{503, 134, 1}, {504, 1, 40}, {544, 110, 1},
{546, 1, 18}, {570, 70, 1}, {571, 0, 1},
{573, 108, 1}, {574, 68, 1}, {577, 0, 1},
{579, 106, 1}, {580, 28, 1}, {581, 30, 1},
{582, 1, 10}, {837, 36, 1}, {880, 1, 4},
{886, 0, 1}, {902, 18, 1}, {904, 16, 3},
{908, 26, 1}, {910, 24, 2}, {913, 14, 17},
{931, 14, 9}, {962, 0, 1}, {975, 4, 1},
{976, 140, 1}, {977, 142, 1}, {981, 146, 1},
{982, 144, 1}, {984, 1, 24}, {1008, 136, 1},
{1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1},
{1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1},
{1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32},
{1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1},
{1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38},
{4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1},
{7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1},
{7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6},
{7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6},
{8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8},
{8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2},
{8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1},
{8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2},
{8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2},
{8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2},
{8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1},
{8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16},
{8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47},
{11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1},
{11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1},
{11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1},
{11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2},
{11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
{42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14},
{42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1},
{42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1},
{42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1},
{65313, 14, 26},
};
static const unsigned short aiOff[] = {
1, 2, 8, 15, 16, 26, 28, 32,
37, 38, 40, 48, 63, 64, 69, 71,
79, 80, 116, 202, 203, 205, 206, 207,
209, 210, 211, 213, 214, 217, 218, 219,
775, 7264, 10792, 10795, 23228, 23256, 30204, 54721,
54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274,
57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406,
65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462,
65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511,
65514, 65521, 65527, 65528, 65529,
};
int ret = c;
assert( c>=0 );
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
if( c<128 ){
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
}else if( c<65536 ){
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
int iRes = -1;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
int cmp = (c - aEntry[iTest].iCode);
if( cmp>=0 ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( iRes<0 || c>=aEntry[iRes].iCode );
if( iRes>=0 ){
const struct TableEntry *p = &aEntry[iRes];
if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
assert( ret>0 );
}
}
if( bRemoveDiacritic ) ret = remove_diacritic(ret);
}
else if( c>=66560 && c<66600 ){
ret = c + 40;
}
return ret;
}
#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
#endif /* !defined(SQLITE_ENABLE_FTS4_UNICODE61) */
/************** End of fts3_unicode2.c ***************************************/
/************** Begin file rtree.c *******************************************/
/*
** 2001 September 15
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
|
| ︙ | ︙ | |||
132382 132383 132384 132385 132386 132387 132388 132389 132390 132391 132392 132393 132394 132395 | int eCoordType; }; /* Possible values for eCoordType: */ #define RTREE_COORD_REAL32 0 #define RTREE_COORD_INT32 1 /* ** The minimum number of cells allowed for a node is a third of the ** maximum. In Gutman's notation: ** ** m = M/3 ** ** If an R*-tree "Reinsert" operation is required, the same number of | > > > > > > > > > > > > > | 134180 134181 134182 134183 134184 134185 134186 134187 134188 134189 134190 134191 134192 134193 134194 134195 134196 134197 134198 134199 134200 134201 134202 134203 134204 134205 134206 | int eCoordType; }; /* Possible values for eCoordType: */ #define RTREE_COORD_REAL32 0 #define RTREE_COORD_INT32 1 /* ** If SQLITE_RTREE_INT_ONLY is defined, then this virtual table will ** only deal with integer coordinates. No floating point operations ** will be done. */ #ifdef SQLITE_RTREE_INT_ONLY typedef sqlite3_int64 RtreeDValue; /* High accuracy coordinate */ typedef int RtreeValue; /* Low accuracy coordinate */ #else typedef double RtreeDValue; /* High accuracy coordinate */ typedef float RtreeValue; /* Low accuracy coordinate */ #endif /* ** The minimum number of cells allowed for a node is a third of the ** maximum. In Gutman's notation: ** ** m = M/3 ** ** If an R*-tree "Reinsert" operation is required, the same number of |
| ︙ | ︙ | |||
132417 132418 132419 132420 132421 132422 132423 |
int iCell; /* Index of current cell in pNode */
int iStrategy; /* Copy of idxNum search parameter */
int nConstraint; /* Number of entries in aConstraint */
RtreeConstraint *aConstraint; /* Search constraints. */
};
union RtreeCoord {
| | | | > > > > | | | | | > | | | 134228 134229 134230 134231 134232 134233 134234 134235 134236 134237 134238 134239 134240 134241 134242 134243 134244 134245 134246 134247 134248 134249 134250 134251 134252 134253 134254 134255 134256 134257 134258 134259 134260 134261 134262 134263 134264 134265 134266 134267 134268 134269 |
int iCell; /* Index of current cell in pNode */
int iStrategy; /* Copy of idxNum search parameter */
int nConstraint; /* Number of entries in aConstraint */
RtreeConstraint *aConstraint; /* Search constraints. */
};
union RtreeCoord {
RtreeValue f;
int i;
};
/*
** The argument is an RtreeCoord. Return the value stored within the RtreeCoord
** formatted as a RtreeDValue (double or int64). This macro assumes that local
** variable pRtree points to the Rtree structure associated with the
** RtreeCoord.
*/
#ifdef SQLITE_RTREE_INT_ONLY
# define DCOORD(coord) ((RtreeDValue)coord.i)
#else
# define DCOORD(coord) ( \
(pRtree->eCoordType==RTREE_COORD_REAL32) ? \
((double)coord.f) : \
((double)coord.i) \
)
#endif
/*
** A search constraint.
*/
struct RtreeConstraint {
int iCoord; /* Index of constrained coordinate */
int op; /* Constraining operation */
RtreeDValue rValue; /* Constraint value. */
int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
sqlite3_rtree_geometry *pGeom; /* Constraint callback argument for a MATCH */
};
/* Possible values for RtreeConstraint.op */
#define RTREE_EQ 0x41
#define RTREE_LE 0x42
#define RTREE_LT 0x43
|
| ︙ | ︙ | |||
132487 132488 132489 132490 132491 132492 132493 |
/*
** An instance of this structure must be supplied as a blob argument to
** the right-hand-side of an SQL MATCH operator used to constrain an
** r-tree query.
*/
struct RtreeMatchArg {
u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
| | | | | 134303 134304 134305 134306 134307 134308 134309 134310 134311 134312 134313 134314 134315 134316 134317 134318 134319 134320 134321 134322 134323 134324 134325 134326 134327 134328 134329 134330 134331 134332 |
/*
** An instance of this structure must be supplied as a blob argument to
** the right-hand-side of an SQL MATCH operator used to constrain an
** r-tree query.
*/
struct RtreeMatchArg {
u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue*, int *);
void *pContext;
int nParam;
RtreeDValue aParam[1];
};
/*
** When a geometry callback is created (see sqlite3_rtree_geometry_callback),
** a single instance of the following structure is allocated. It is used
** as the context for the user-function created by by s_r_g_c(). The object
** is eventually deleted by the destructor mechanism provided by
** sqlite3_create_function_v2() (which is called by s_r_g_c() to create
** the geometry callback function).
*/
struct RtreeGeomCallback {
int (*xGeom)(sqlite3_rtree_geometry*, int, RtreeDValue*, int*);
void *pContext;
};
#ifndef MAX
# define MAX(x,y) ((x) < (y) ? (y) : (x))
#endif
#ifndef MIN
|
| ︙ | ︙ | |||
133068 133069 133070 133071 133072 133073 133074 |
static int testRtreeGeom(
Rtree *pRtree, /* R-Tree object */
RtreeConstraint *pConstraint, /* MATCH constraint to test */
RtreeCell *pCell, /* Cell to test */
int *pbRes /* OUT: Test result */
){
int i;
| | | 134884 134885 134886 134887 134888 134889 134890 134891 134892 134893 134894 134895 134896 134897 134898 |
static int testRtreeGeom(
Rtree *pRtree, /* R-Tree object */
RtreeConstraint *pConstraint, /* MATCH constraint to test */
RtreeCell *pCell, /* Cell to test */
int *pbRes /* OUT: Test result */
){
int i;
RtreeDValue aCoord[RTREE_MAX_DIMENSIONS*2];
int nCoord = pRtree->nDim*2;
assert( pConstraint->op==RTREE_MATCH );
assert( pConstraint->pGeom );
for(i=0; i<nCoord; i++){
aCoord[i] = DCOORD(pCell->aCoord[i]);
|
| ︙ | ︙ | |||
133098 133099 133100 133101 133102 133103 133104 |
int ii;
int bRes = 0;
int rc = SQLITE_OK;
nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
RtreeConstraint *p = &pCursor->aConstraint[ii];
| | | | 134914 134915 134916 134917 134918 134919 134920 134921 134922 134923 134924 134925 134926 134927 134928 134929 |
int ii;
int bRes = 0;
int rc = SQLITE_OK;
nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
RtreeConstraint *p = &pCursor->aConstraint[ii];
RtreeDValue cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
RtreeDValue cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
|| p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
);
switch( p->op ){
case RTREE_LE: case RTREE_LT:
|
| ︙ | ︙ | |||
133151 133152 133153 133154 133155 133156 133157 |
RtreeCell cell;
int ii;
*pbEof = 0;
nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
for(ii=0; ii<pCursor->nConstraint; ii++){
RtreeConstraint *p = &pCursor->aConstraint[ii];
| | | 134967 134968 134969 134970 134971 134972 134973 134974 134975 134976 134977 134978 134979 134980 134981 |
RtreeCell cell;
int ii;
*pbEof = 0;
nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
for(ii=0; ii<pCursor->nConstraint; ii++){
RtreeConstraint *p = &pCursor->aConstraint[ii];
RtreeDValue coord = DCOORD(cell.aCoord[p->iCoord]);
int res;
assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
|| p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_MATCH
);
switch( p->op ){
case RTREE_LE: res = (coord<=p->rValue); break;
case RTREE_LT: res = (coord<p->rValue); break;
|
| ︙ | ︙ | |||
133349 133350 133351 133352 133353 133354 133355 133356 133357 |
if( i==0 ){
i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
sqlite3_result_int64(ctx, iRowid);
}else{
RtreeCoord c;
nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
sqlite3_result_double(ctx, c.f);
| > | > > | 135165 135166 135167 135168 135169 135170 135171 135172 135173 135174 135175 135176 135177 135178 135179 135180 135181 135182 135183 135184 |
if( i==0 ){
i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
sqlite3_result_int64(ctx, iRowid);
}else{
RtreeCoord c;
nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
sqlite3_result_double(ctx, c.f);
}else
#endif
{
assert( pRtree->eCoordType==RTREE_COORD_INT32 );
sqlite3_result_int(ctx, c.i);
}
}
return SQLITE_OK;
}
|
| ︙ | ︙ | |||
133398 133399 133400 133401 133402 133403 133404 | /* Check that value is actually a blob. */ if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR; /* Check that the blob is roughly the right size. */ nBlob = sqlite3_value_bytes(pValue); if( nBlob<(int)sizeof(RtreeMatchArg) | | | | 135217 135218 135219 135220 135221 135222 135223 135224 135225 135226 135227 135228 135229 135230 135231 135232 135233 135234 135235 135236 135237 135238 135239 135240 135241 135242 135243 135244 135245 |
/* Check that value is actually a blob. */
if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
/* Check that the blob is roughly the right size. */
nBlob = sqlite3_value_bytes(pValue);
if( nBlob<(int)sizeof(RtreeMatchArg)
|| ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
){
return SQLITE_ERROR;
}
pGeom = (sqlite3_rtree_geometry *)sqlite3_malloc(
sizeof(sqlite3_rtree_geometry) + nBlob
);
if( !pGeom ) return SQLITE_NOMEM;
memset(pGeom, 0, sizeof(sqlite3_rtree_geometry));
p = (RtreeMatchArg *)&pGeom[1];
memcpy(p, sqlite3_value_blob(pValue), nBlob);
if( p->magic!=RTREE_GEOMETRY_MAGIC
|| nBlob!=(int)(sizeof(RtreeMatchArg) + (p->nParam-1)*sizeof(RtreeDValue))
){
sqlite3_free(pGeom);
return SQLITE_ERROR;
}
pGeom->pContext = p->pContext;
pGeom->nParam = p->nParam;
|
| ︙ | ︙ | |||
133484 133485 133486 133487 133488 133489 133490 133491 133492 133493 133494 133495 133496 133497 133498 |
** an sqlite3_rtree_geometry_callback() SQL user function.
*/
rc = deserializeGeometry(argv[ii], p);
if( rc!=SQLITE_OK ){
break;
}
}else{
p->rValue = sqlite3_value_double(argv[ii]);
}
}
}
}
if( rc==SQLITE_OK ){
pCsr->pNode = 0;
| > > > > | 135303 135304 135305 135306 135307 135308 135309 135310 135311 135312 135313 135314 135315 135316 135317 135318 135319 135320 135321 |
** an sqlite3_rtree_geometry_callback() SQL user function.
*/
rc = deserializeGeometry(argv[ii], p);
if( rc!=SQLITE_OK ){
break;
}
}else{
#ifdef SQLITE_RTREE_INT_ONLY
p->rValue = sqlite3_value_int64(argv[ii]);
#else
p->rValue = sqlite3_value_double(argv[ii]);
#endif
}
}
}
}
if( rc==SQLITE_OK ){
pCsr->pNode = 0;
|
| ︙ | ︙ | |||
133618 133619 133620 133621 133622 133623 133624 | pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1)); return rc; } /* ** Return the N-dimensional volumn of the cell stored in *p. */ | | | | | | | | 135441 135442 135443 135444 135445 135446 135447 135448 135449 135450 135451 135452 135453 135454 135455 135456 135457 135458 135459 135460 135461 135462 135463 135464 135465 135466 135467 135468 135469 135470 135471 135472 |
pIdxInfo->estimatedCost = (2000000.0 / (double)(iIdx + 1));
return rc;
}
/*
** Return the N-dimensional volumn of the cell stored in *p.
*/
static RtreeDValue cellArea(Rtree *pRtree, RtreeCell *p){
RtreeDValue area = (RtreeDValue)1;
int ii;
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
area = (area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii])));
}
return area;
}
/*
** Return the margin length of cell p. The margin length is the sum
** of the objects size in each dimension.
*/
static RtreeDValue cellMargin(Rtree *pRtree, RtreeCell *p){
RtreeDValue margin = (RtreeDValue)0;
int ii;
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
}
return margin;
}
/*
** Store the union of cells p1 and p2 in p1.
*/
|
| ︙ | ︙ | |||
133680 133681 133682 133683 133684 133685 133686 | } return 1; } /* ** Return the amount cell p would grow by if it were unioned with pCell. */ | | | | | | | < | | | < | | 135503 135504 135505 135506 135507 135508 135509 135510 135511 135512 135513 135514 135515 135516 135517 135518 135519 135520 135521 135522 135523 135524 135525 135526 135527 135528 135529 135530 135531 135532 135533 135534 135535 135536 135537 135538 135539 135540 135541 135542 135543 135544 135545 135546 135547 135548 135549 135550 135551 135552 135553 135554 135555 135556 135557 135558 135559 135560 135561 135562 135563 135564 135565 135566 135567 135568 135569 135570 135571 135572 135573 135574 135575 135576 135577 135578 135579 |
}
return 1;
}
/*
** Return the amount cell p would grow by if it were unioned with pCell.
*/
static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
RtreeDValue area;
RtreeCell cell;
memcpy(&cell, p, sizeof(RtreeCell));
area = cellArea(pRtree, &cell);
cellUnion(pRtree, &cell, pCell);
return (cellArea(pRtree, &cell)-area);
}
#if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT
static RtreeDValue cellOverlap(
Rtree *pRtree,
RtreeCell *p,
RtreeCell *aCell,
int nCell,
int iExclude
){
int ii;
RtreeDValue overlap = 0.0;
for(ii=0; ii<nCell; ii++){
#if VARIANT_RSTARTREE_CHOOSESUBTREE
if( ii!=iExclude )
#else
assert( iExclude==-1 );
UNUSED_PARAMETER(iExclude);
#endif
{
int jj;
RtreeDValue o = (RtreeDValue)1;
for(jj=0; jj<(pRtree->nDim*2); jj+=2){
RtreeDValue x1, x2;
x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
if( x2<x1 ){
o = 0.0;
break;
}else{
o = o * (x2-x1);
}
}
overlap += o;
}
}
return overlap;
}
#endif
#if VARIANT_RSTARTREE_CHOOSESUBTREE
static RtreeDValue cellOverlapEnlargement(
Rtree *pRtree,
RtreeCell *p,
RtreeCell *pInsert,
RtreeCell *aCell,
int nCell,
int iExclude
){
RtreeDValue before, after;
before = cellOverlap(pRtree, p, aCell, nCell, iExclude);
cellUnion(pRtree, p, pInsert);
after = cellOverlap(pRtree, p, aCell, nCell, iExclude);
return (after-before);
}
#endif
/*
** This function implements the ChooseLeaf algorithm from Gutman[84].
** ChooseSubTree in r*tree terminology.
|
| ︙ | ︙ | |||
133768 133769 133770 133771 133772 133773 133774 |
RtreeNode *pNode;
rc = nodeAcquire(pRtree, 1, 0, &pNode);
for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
int iCell;
sqlite3_int64 iBest = 0;
| | | | | | 135589 135590 135591 135592 135593 135594 135595 135596 135597 135598 135599 135600 135601 135602 135603 135604 135605 135606 135607 |
RtreeNode *pNode;
rc = nodeAcquire(pRtree, 1, 0, &pNode);
for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
int iCell;
sqlite3_int64 iBest = 0;
RtreeDValue fMinGrowth = 0.0;
RtreeDValue fMinArea = 0.0;
#if VARIANT_RSTARTREE_CHOOSESUBTREE
RtreeDValue fMinOverlap = 0.0;
RtreeDValue overlap;
#endif
int nCell = NCELL(pNode);
RtreeCell cell;
RtreeNode *pChild;
RtreeCell *aCell = 0;
|
| ︙ | ︙ | |||
133803 133804 133805 133806 133807 133808 133809 |
/* Select the child node which will be enlarged the least if pCell
** is inserted into it. Resolve ties by choosing the entry with
** the smallest area.
*/
for(iCell=0; iCell<nCell; iCell++){
int bBest = 0;
| | | | 135624 135625 135626 135627 135628 135629 135630 135631 135632 135633 135634 135635 135636 135637 135638 135639 |
/* Select the child node which will be enlarged the least if pCell
** is inserted into it. Resolve ties by choosing the entry with
** the smallest area.
*/
for(iCell=0; iCell<nCell; iCell++){
int bBest = 0;
RtreeDValue growth;
RtreeDValue 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);
|
| ︙ | ︙ | |||
133931 133932 133933 133934 133935 133936 133937 |
int nCell,
int *piLeftSeed,
int *piRightSeed
){
int i;
int iLeftSeed = 0;
int iRightSeed = 1;
| | | | | | | | | | 135752 135753 135754 135755 135756 135757 135758 135759 135760 135761 135762 135763 135764 135765 135766 135767 135768 135769 135770 135771 135772 135773 135774 135775 135776 135777 135778 135779 135780 135781 135782 135783 135784 135785 135786 135787 135788 135789 135790 135791 135792 135793 135794 135795 135796 135797 135798 135799 135800 |
int nCell,
int *piLeftSeed,
int *piRightSeed
){
int i;
int iLeftSeed = 0;
int iRightSeed = 1;
RtreeDValue maxNormalInnerWidth = (RtreeDValue)0;
/* Pick two "seed" cells from the array of cells. The algorithm used
** here is the LinearPickSeeds algorithm from Gutman[1984]. The
** indices of the two seed cells in the array are stored in local
** variables iLeftSeek and iRightSeed.
*/
for(i=0; i<pRtree->nDim; i++){
RtreeDValue x1 = DCOORD(aCell[0].aCoord[i*2]);
RtreeDValue x2 = DCOORD(aCell[0].aCoord[i*2+1]);
RtreeDValue x3 = x1;
RtreeDValue x4 = x2;
int jj;
int iCellLeft = 0;
int iCellRight = 0;
for(jj=1; jj<nCell; jj++){
RtreeDValue left = DCOORD(aCell[jj].aCoord[i*2]);
RtreeDValue right = DCOORD(aCell[jj].aCoord[i*2+1]);
if( left<x1 ) x1 = left;
if( right>x4 ) x4 = right;
if( left>x3 ){
x3 = left;
iCellRight = jj;
}
if( right<x2 ){
x2 = right;
iCellLeft = jj;
}
}
if( x4!=x1 ){
RtreeDValue normalwidth = (x3 - x2) / (x4 - x1);
if( normalwidth>maxNormalInnerWidth ){
iLeftSeed = iCellLeft;
iRightSeed = iCellRight;
}
}
}
|
| ︙ | ︙ | |||
133994 133995 133996 133997 133998 133999 134000 |
RtreeCell *pLeftBox,
RtreeCell *pRightBox,
int *aiUsed
){
#define FABS(a) ((a)<0.0?-1.0*(a):(a))
int iSelect = -1;
| | | | | | 135815 135816 135817 135818 135819 135820 135821 135822 135823 135824 135825 135826 135827 135828 135829 135830 135831 135832 135833 135834 135835 |
RtreeCell *pLeftBox,
RtreeCell *pRightBox,
int *aiUsed
){
#define FABS(a) ((a)<0.0?-1.0*(a):(a))
int iSelect = -1;
RtreeDValue fDiff;
int ii;
for(ii=0; ii<nCell; ii++){
if( aiUsed[ii]==0 ){
RtreeDValue left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
RtreeDValue right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
RtreeDValue diff = FABS(right-left);
if( iSelect<0 || diff>fDiff ){
fDiff = diff;
iSelect = ii;
}
}
}
aiUsed[iSelect] = 1;
|
| ︙ | ︙ | |||
134027 134028 134029 134030 134031 134032 134033 |
int *piRightSeed
){
int ii;
int jj;
int iLeftSeed = 0;
int iRightSeed = 1;
| | | | | | 135848 135849 135850 135851 135852 135853 135854 135855 135856 135857 135858 135859 135860 135861 135862 135863 135864 135865 135866 135867 135868 |
int *piRightSeed
){
int ii;
int jj;
int iLeftSeed = 0;
int iRightSeed = 1;
RtreeDValue fWaste = 0.0;
for(ii=0; ii<nCell; ii++){
for(jj=ii+1; jj<nCell; jj++){
RtreeDValue right = cellArea(pRtree, &aCell[jj]);
RtreeDValue growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
RtreeDValue waste = growth - right;
if( waste>fWaste ){
iLeftSeed = ii;
iRightSeed = jj;
fWaste = waste;
}
}
|
| ︙ | ︙ | |||
134068 134069 134070 134071 134072 134073 134074 | ** ** The aSpare array is used as temporary working space by the ** sorting algorithm. */ static void SortByDistance( int *aIdx, int nIdx, | | | 135889 135890 135891 135892 135893 135894 135895 135896 135897 135898 135899 135900 135901 135902 135903 |
**
** The aSpare array is used as temporary working space by the
** sorting algorithm.
*/
static void SortByDistance(
int *aIdx,
int nIdx,
RtreeDValue *aDistance,
int *aSpare
){
if( nIdx>1 ){
int iLeft = 0;
int iRight = 0;
int nLeft = nIdx/2;
|
| ︙ | ︙ | |||
134094 134095 134096 134097 134098 134099 134100 |
if( iLeft==nLeft ){
aIdx[iLeft+iRight] = aRight[iRight];
iRight++;
}else if( iRight==nRight ){
aIdx[iLeft+iRight] = aLeft[iLeft];
iLeft++;
}else{
| | | | | | 135915 135916 135917 135918 135919 135920 135921 135922 135923 135924 135925 135926 135927 135928 135929 135930 135931 135932 135933 135934 135935 135936 135937 135938 135939 135940 135941 135942 135943 135944 135945 135946 135947 |
if( iLeft==nLeft ){
aIdx[iLeft+iRight] = aRight[iRight];
iRight++;
}else if( iRight==nRight ){
aIdx[iLeft+iRight] = aLeft[iLeft];
iLeft++;
}else{
RtreeDValue fLeft = aDistance[aLeft[iLeft]];
RtreeDValue fRight = aDistance[aRight[iRight]];
if( fLeft<fRight ){
aIdx[iLeft+iRight] = aLeft[iLeft];
iLeft++;
}else{
aIdx[iLeft+iRight] = aRight[iRight];
iRight++;
}
}
}
#if 0
/* Check that the sort worked */
{
int jj;
for(jj=1; jj<nIdx; jj++){
RtreeDValue left = aDistance[aIdx[jj-1]];
RtreeDValue right = aDistance[aIdx[jj]];
assert( left<=right );
}
}
#endif
}
}
|
| ︙ | ︙ | |||
134155 134156 134157 134158 134159 134160 134161 |
SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare);
SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare);
memcpy(aSpare, aLeft, sizeof(int)*nLeft);
aLeft = aSpare;
while( iLeft<nLeft || iRight<nRight ){
| | | | | | | | | | 135976 135977 135978 135979 135980 135981 135982 135983 135984 135985 135986 135987 135988 135989 135990 135991 135992 135993 135994 135995 135996 135997 135998 135999 136000 136001 136002 136003 136004 136005 136006 136007 136008 136009 136010 136011 136012 136013 136014 |
SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare);
SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare);
memcpy(aSpare, aLeft, sizeof(int)*nLeft);
aLeft = aSpare;
while( iLeft<nLeft || iRight<nRight ){
RtreeDValue xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
RtreeDValue xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
RtreeDValue xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
RtreeDValue xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
if( (iLeft!=nLeft) && ((iRight==nRight)
|| (xleft1<xright1)
|| (xleft1==xright1 && xleft2<xright2)
)){
aIdx[iLeft+iRight] = aLeft[iLeft];
iLeft++;
}else{
aIdx[iLeft+iRight] = aRight[iRight];
iRight++;
}
}
#if 0
/* Check that the sort worked */
{
int jj;
for(jj=1; jj<nIdx; jj++){
RtreeDValue xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
RtreeDValue xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
RtreeDValue xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
RtreeDValue xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) );
}
}
#endif
}
}
|
| ︙ | ︙ | |||
134206 134207 134208 134209 134210 134211 134212 |
){
int **aaSorted;
int *aSpare;
int ii;
int iBestDim = 0;
int iBestSplit = 0;
| | | | | | | | 136027 136028 136029 136030 136031 136032 136033 136034 136035 136036 136037 136038 136039 136040 136041 136042 136043 136044 136045 136046 136047 136048 136049 136050 136051 136052 136053 136054 136055 136056 136057 136058 136059 136060 136061 136062 136063 136064 136065 136066 136067 136068 136069 136070 136071 136072 136073 136074 136075 136076 136077 |
){
int **aaSorted;
int *aSpare;
int ii;
int iBestDim = 0;
int iBestSplit = 0;
RtreeDValue fBestMargin = 0.0;
int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
aaSorted = (int **)sqlite3_malloc(nByte);
if( !aaSorted ){
return SQLITE_NOMEM;
}
aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell];
memset(aaSorted, 0, nByte);
for(ii=0; ii<pRtree->nDim; ii++){
int jj;
aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell];
for(jj=0; jj<nCell; jj++){
aaSorted[ii][jj] = jj;
}
SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare);
}
for(ii=0; ii<pRtree->nDim; ii++){
RtreeDValue margin = 0.0;
RtreeDValue fBestOverlap = 0.0;
RtreeDValue fBestArea = 0.0;
int iBestLeft = 0;
int nLeft;
for(
nLeft=RTREE_MINCELLS(pRtree);
nLeft<=(nCell-RTREE_MINCELLS(pRtree));
nLeft++
){
RtreeCell left;
RtreeCell right;
int kk;
RtreeDValue overlap;
RtreeDValue area;
memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell));
memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell));
for(kk=1; kk<(nCell-1); kk++){
if( kk<nLeft ){
cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]);
}else{
|
| ︙ | ︙ | |||
134325 134326 134327 134328 134329 134330 134331 |
nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]);
aiUsed[iLeftSeed] = 1;
aiUsed[iRightSeed] = 1;
for(i=nCell-2; i>0; i--){
RtreeCell *pNext;
pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed);
| | | 136146 136147 136148 136149 136150 136151 136152 136153 136154 136155 136156 136157 136158 136159 136160 |
nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]);
aiUsed[iLeftSeed] = 1;
aiUsed[iRightSeed] = 1;
for(i=nCell-2; i>0; i--){
RtreeCell *pNext;
pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed);
RtreeDValue diff =
cellGrowth(pRtree, pBboxLeft, pNext) -
cellGrowth(pRtree, pBboxRight, pNext)
;
if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i)
|| (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i))
){
nodeInsertCell(pRtree, pRight, pNext);
|
| ︙ | ︙ | |||
134658 134659 134660 134661 134662 134663 134664 |
RtreeNode *pNode,
RtreeCell *pCell,
int iHeight
){
int *aOrder;
int *aSpare;
RtreeCell *aCell;
| | | > | > | | | | | | | | | | | | | | 136479 136480 136481 136482 136483 136484 136485 136486 136487 136488 136489 136490 136491 136492 136493 136494 136495 136496 136497 136498 136499 136500 136501 136502 136503 136504 136505 136506 136507 136508 136509 136510 136511 136512 136513 136514 136515 136516 136517 136518 136519 136520 136521 136522 136523 136524 136525 136526 136527 136528 136529 136530 136531 136532 136533 136534 136535 136536 136537 136538 136539 136540 136541 136542 |
RtreeNode *pNode,
RtreeCell *pCell,
int iHeight
){
int *aOrder;
int *aSpare;
RtreeCell *aCell;
RtreeDValue *aDistance;
int nCell;
RtreeDValue aCenterCoord[RTREE_MAX_DIMENSIONS];
int iDim;
int ii;
int rc = SQLITE_OK;
int n;
memset(aCenterCoord, 0, sizeof(RtreeDValue)*RTREE_MAX_DIMENSIONS);
nCell = NCELL(pNode)+1;
n = (nCell+1)&(~1);
/* Allocate the buffers used by this operation. The allocation is
** relinquished before this function returns.
*/
aCell = (RtreeCell *)sqlite3_malloc(n * (
sizeof(RtreeCell) + /* aCell array */
sizeof(int) + /* aOrder array */
sizeof(int) + /* aSpare array */
sizeof(RtreeDValue) /* aDistance array */
));
if( !aCell ){
return SQLITE_NOMEM;
}
aOrder = (int *)&aCell[n];
aSpare = (int *)&aOrder[n];
aDistance = (RtreeDValue *)&aSpare[n];
for(ii=0; ii<nCell; ii++){
if( ii==(nCell-1) ){
memcpy(&aCell[ii], pCell, sizeof(RtreeCell));
}else{
nodeGetCell(pRtree, pNode, ii, &aCell[ii]);
}
aOrder[ii] = ii;
for(iDim=0; iDim<pRtree->nDim; iDim++){
aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]);
aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]);
}
}
for(iDim=0; iDim<pRtree->nDim; iDim++){
aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2));
}
for(ii=0; ii<nCell; ii++){
aDistance[ii] = 0.0;
for(iDim=0; iDim<pRtree->nDim; iDim++){
RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) -
DCOORD(aCell[ii].aCoord[iDim*2]));
aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]);
}
}
SortByDistance(aOrder, nCell, aDistance, aSpare);
nodeZero(pRtree, pNode);
|
| ︙ | ︙ | |||
134913 134914 134915 134916 134917 134918 134919 134920 134921 134922 134923 134924 134925 134926 |
rc = nodeRelease(pRtree, pRoot);
}else{
nodeRelease(pRtree, pRoot);
}
return rc;
}
/*
** The xUpdate method for rtree module virtual tables.
*/
static int rtreeUpdate(
sqlite3_vtab *pVtab,
int nData,
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 136736 136737 136738 136739 136740 136741 136742 136743 136744 136745 136746 136747 136748 136749 136750 136751 136752 136753 136754 136755 136756 136757 136758 136759 136760 136761 136762 136763 136764 136765 136766 136767 136768 136769 136770 136771 136772 136773 136774 136775 136776 136777 136778 136779 |
rc = nodeRelease(pRtree, pRoot);
}else{
nodeRelease(pRtree, pRoot);
}
return rc;
}
/*
** Rounding constants for float->double conversion.
*/
#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */
#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */
#if !defined(SQLITE_RTREE_INT_ONLY)
/*
** Convert an sqlite3_value into an RtreeValue (presumably a float)
** while taking care to round toward negative or positive, respectively.
*/
static RtreeValue rtreeValueDown(sqlite3_value *v){
double d = sqlite3_value_double(v);
float f = (float)d;
if( f>d ){
f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS));
}
return f;
}
static RtreeValue rtreeValueUp(sqlite3_value *v){
double d = sqlite3_value_double(v);
float f = (float)d;
if( f<d ){
f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY));
}
return f;
}
#endif /* !defined(SQLITE_RTREE_INT_ONLY) */
/*
** The xUpdate method for rtree module virtual tables.
*/
static int rtreeUpdate(
sqlite3_vtab *pVtab,
int nData,
|
| ︙ | ︙ | |||
134947 134948 134949 134950 134951 134952 134953 134954 134955 |
** conflict-handling mode specified by the user.
*/
if( nData>1 ){
int ii;
/* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
assert( nData==(pRtree->nDim*2 + 3) );
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
| > | | | > > | 136800 136801 136802 136803 136804 136805 136806 136807 136808 136809 136810 136811 136812 136813 136814 136815 136816 136817 136818 136819 136820 136821 136822 136823 136824 136825 136826 |
** conflict-handling mode specified by the user.
*/
if( nData>1 ){
int ii;
/* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
assert( nData==(pRtree->nDim*2 + 3) );
#ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
rc = SQLITE_CONSTRAINT;
goto constraint;
}
}
}else
#endif
{
for(ii=0; ii<(pRtree->nDim*2); ii+=2){
cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
rc = SQLITE_CONSTRAINT;
goto constraint;
}
|
| ︙ | ︙ | |||
135354 135355 135356 135357 135358 135359 135360 |
RtreeCell cell;
int jj;
nodeGetCell(&tree, &node, ii, &cell);
sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
nCell = (int)strlen(zCell);
for(jj=0; jj<tree.nDim*2; jj++){
| > | > > > > > | 137210 137211 137212 137213 137214 137215 137216 137217 137218 137219 137220 137221 137222 137223 137224 137225 137226 137227 137228 137229 137230 |
RtreeCell cell;
int jj;
nodeGetCell(&tree, &node, ii, &cell);
sqlite3_snprintf(512-nCell,&zCell[nCell],"%lld", cell.iRowid);
nCell = (int)strlen(zCell);
for(jj=0; jj<tree.nDim*2; jj++){
#ifndef SQLITE_RTREE_INT_ONLY
sqlite3_snprintf(512-nCell,&zCell[nCell], " %f",
(double)cell.aCoord[jj].f);
#else
sqlite3_snprintf(512-nCell,&zCell[nCell], " %d",
cell.aCoord[jj].i);
#endif
nCell = (int)strlen(zCell);
}
if( zText ){
char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
sqlite3_free(zText);
zText = zTextNew;
|
| ︙ | ︙ | |||
135396 135397 135398 135399 135400 135401 135402 135403 135404 135405 135406 135407 135408 135409 135410 |
int rc;
rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
}
if( rc==SQLITE_OK ){
void *c = (void *)RTREE_COORD_REAL32;
rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
}
if( rc==SQLITE_OK ){
void *c = (void *)RTREE_COORD_INT32;
rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
}
| > > > > | 137258 137259 137260 137261 137262 137263 137264 137265 137266 137267 137268 137269 137270 137271 137272 137273 137274 137275 137276 |
int rc;
rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
}
if( rc==SQLITE_OK ){
#ifdef SQLITE_RTREE_INT_ONLY
void *c = (void *)RTREE_COORD_INT32;
#else
void *c = (void *)RTREE_COORD_REAL32;
#endif
rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
}
if( rc==SQLITE_OK ){
void *c = (void *)RTREE_COORD_INT32;
rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
}
|
| ︙ | ︙ | |||
135430 135431 135432 135433 135434 135435 135436 |
** table MATCH operators.
*/
static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
RtreeMatchArg *pBlob;
int nBlob;
| | > > > > | | 137296 137297 137298 137299 137300 137301 137302 137303 137304 137305 137306 137307 137308 137309 137310 137311 137312 137313 137314 137315 137316 137317 137318 137319 137320 137321 137322 137323 137324 137325 137326 137327 137328 137329 137330 137331 137332 137333 137334 137335 137336 137337 |
** table MATCH operators.
*/
static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
RtreeMatchArg *pBlob;
int nBlob;
nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
if( !pBlob ){
sqlite3_result_error_nomem(ctx);
}else{
int i;
pBlob->magic = RTREE_GEOMETRY_MAGIC;
pBlob->xGeom = pGeomCtx->xGeom;
pBlob->pContext = pGeomCtx->pContext;
pBlob->nParam = nArg;
for(i=0; i<nArg; i++){
#ifdef SQLITE_RTREE_INT_ONLY
pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
#else
pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
#endif
}
sqlite3_result_blob(ctx, pBlob, nBlob, doSqlite3Free);
}
}
/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/
SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
int (*xGeom)(sqlite3_rtree_geometry *, int, RtreeDValue *, int *),
void *pContext
){
RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */
/* Allocate and populate the context object. */
pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
if( !pGeomCtx ) return SQLITE_NOMEM;
|
| ︙ | ︙ |
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** string contains the date and time of the check-in (UTC) and an SHA1 ** hash of the entire source tree. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.13" #define SQLITE_VERSION_NUMBER 3007013 #define SQLITE_SOURCE_ID "2012-06-07 07:24:04 506008f000ba4af0b35da023b8c52f7a3f5033bd" /* ** 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 |
| ︙ | ︙ | |||
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ | > > | 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800 /* VFS only */ #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ |
| ︙ | ︙ | |||
767 768 769 770 771 772 773 | ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the | | | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 | ** integer is the delay. If either integer is negative, then the setting ** is not changed but instead the prior value of that setting is written ** into the array entry, allowing the current retry settings to be ** interrogated. The zDbName parameter is ignored. ** ** <li>[[SQLITE_FCNTL_PERSIST_WAL]] ** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the ** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary ** write ahead log and shared memory files used for transaction control ** are automatically deleted when the latest connection to the database ** closes. Setting persistent WAL mode causes those files to persist after ** close. Persisting the files is useful when other processes that do not ** have write permission on the directory containing the database file want ** to read the database file, as the WAL and shared memory files must exist ** in order for the database to be readable. The fourth parameter to |
| ︙ | ︙ | |||
1543 1544 1545 1546 1547 1548 1549 | ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] | | | 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 | ** connection is opened. If it is globally disabled, filenames are ** only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the ** database connection is opened. By default, URI handling is globally ** disabled. The default value may be changed by compiling with the ** [SQLITE_USE_URI] symbol defined. ** ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]] ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE ** <dd> These options are obsolete and should not be used by new code. ** They are retained for backwards compatibility but are now no-ops. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ |
| ︙ | ︙ | |||
2164 2165 2166 2167 2168 2169 2170 | ** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in ** implementation of these routines to be omitted. That capability ** is no longer provided. Only built-in memory allocators can be used. ** | | | | | 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 | ** option is used. ** ** In SQLite version 3.5.0 and 3.5.1, it was possible to define ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in ** implementation of these routines to be omitted. That capability ** is no longer provided. Only built-in memory allocators can be used. ** ** Prior to SQLite version 3.7.10, the Windows OS interface layer called ** the system malloc() and free() directly when converting ** filenames between the UTF-8 encoding used by SQLite ** and whatever filename encoding is used by the particular Windows ** installation. Memory allocation errors were detected, but ** they were reported back as [SQLITE_CANTOPEN] or ** [SQLITE_IOERR] rather than [SQLITE_NOMEM]. ** ** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] ** must be either NULL or else pointers obtained from a prior ** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** |
| ︙ | ︙ | |||
2570 2571 2572 2573 2574 2575 2576 | ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** | | | > | > | | | | 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 | ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown ** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over ** the value passed as the fourth parameter to sqlite3_open_v2(). ** ** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw", ** "rwc", or "memory". Attempting to set it to any other value is ** an error)^. ** ^If "ro" is specified, then the database is opened for read-only ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to ** "rw", then the database is opened for read-write (but not create) ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** been set. ^Value "rwc" is equivalent to setting both ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is ** set to "memory" then a pure [in-memory database] that never reads ** or writes from disk is used. ^It is an error to specify a value for ** the mode parameter that is less restrictive than that specified by ** the flags passed in the third parameter to sqlite3_open_v2(). ** ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to ** sqlite3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in |
| ︙ | ︙ | |||
4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 |
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 |
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [temp_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
/*
** CAPI3REF: Name Of The Folder Holding Database Files
**
** ^(If this global variable is made to point to a string which is
** the name of a folder (a.k.a. directory), then all database files
** specified with a relative pathname and created or accessed by
** SQLite when using a built-in [sqlite3_vfs | VFS] will be assumed
** to be relative to that directory.)^ ^If this variable is a NULL
** pointer, then SQLite assumes that all database files specified
** with a relative pathname are relative to the current directory
** for the process.
**
** Changing the value of this variable while a database connection is
** open can result in a corrupt database.
**
** It is not safe to read or modify this variable in more than one
** thread at a time. It is not safe to read or modify this variable
** if a [database connection] is being used at the same time in a separate
** thread.
** It is intended that this variable be set once
** as part of process initialization and before any SQLite interface
** routines have been called and that this variable remain unchanged
** thereafter.
**
** ^The [data_store_directory pragma] may modify this variable and cause
** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore,
** the [data_store_directory pragma] always assumes that any string
** that this variable points to is held in memory obtained from
** [sqlite3_malloc] and the pragma may attempt to free that memory
** using [sqlite3_free].
** Hence, if this variable is modified directly, either it should be
** made NULL or made to point to memory obtained from [sqlite3_malloc]
** or else the use of the [data_store_directory pragma] should be avoided.
*/
SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
/*
** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode}
**
** ^The sqlite3_get_autocommit() interface returns non-zero or
** zero if the given database connection is or is not in autocommit mode,
** respectively. ^Autocommit mode is on by default.
|
| ︙ | ︙ | |||
4622 4623 4624 4625 4626 4627 4628 | sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache | < | 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 | sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); /* ** CAPI3REF: Enable Or Disable Shared Pager Cache ** ** ^(This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] ** to the same database. Sharing is enabled if the argument is true ** and disabled if the argument is false.)^ ** ** ^Cache sharing is enabled and disabled for an entire process. |
| ︙ | ︙ | |||
6010 6011 6012 6013 6014 6015 6016 | ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect | | | 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 | ** [[SQLITE_DBSTATUS_CACHE_WRITE]] ^(<dt>SQLITE_DBSTATUS_CACHE_WRITE</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 |
| ︙ | ︙ | |||
6981 6982 6983 6984 6985 6986 6987 | ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, | > > > | > | 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 | ** R-Tree geometry query as follows: ** ** SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...) */ SQLITE_API int sqlite3_rtree_geometry_callback( sqlite3 *db, const char *zGeom, #ifdef SQLITE_RTREE_INT_ONLY int (*xGeom)(sqlite3_rtree_geometry*, int n, sqlite3_int64 *a, int *pRes), #else int (*xGeom)(sqlite3_rtree_geometry*, int n, double *a, int *pRes), #endif void *pContext ); /* ** A pointer to a structure of the following type is passed as the first ** argument to callbacks registered using rtree_geometry_callback(). |
| ︙ | ︙ |
Changes to src/stat.c.
| ︙ | ︙ | |||
110 111 112 113 114 115 116 |
" WHERE +tagname GLOB 'tkt-*'");
@ %d(n)
@ </td></tr>
}
@ <tr><th>Duration Of Project:</th><td>
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
" + 0.99");
| | < < < | < | < < < > | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
" WHERE +tagname GLOB 'tkt-*'");
@ %d(n)
@ </td></tr>
}
@ <tr><th>Duration Of Project:</th><td>
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
" + 0.99");
@ %d(n) days or approximately %.2f(n/356.24) years.
@ </td></tr>
@ <tr><th>Project ID:</th><td>%h(db_get("project-code",""))</td></tr>
@ <tr><th>Server ID:</th><td>%h(db_get("server-code",""))</td></tr>
@ <tr><th>Fossil Version:</th><td>
@ %h(RELEASE_VERSION) %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
@ (%h(COMPILER_NAME))
@ </td></tr>
@ <tr><th>SQLite Version:</th><td>%.19s(SQLITE_SOURCE_ID)
@ [%.10s(&SQLITE_SOURCE_ID[20])] (%s(SQLITE_VERSION))</td></tr>
@ <tr><th>Database Stats:</th><td>
zDb = db_name("repository");
@ %d(db_int(0, "PRAGMA %s.page_count", zDb)) pages,
@ %d(db_int(0, "PRAGMA %s.page_size", zDb)) bytes/page,
@ %d(db_int(0, "PRAGMA %s.freelist_count", zDb)) free pages,
@ %s(db_text(0, "PRAGMA %s.encoding", zDb)),
@ %s(db_text(0, "PRAGMA %s.journal_mode", zDb)) mode
@ </td></tr>
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 | static int headerHasBeenGenerated = 0; /* ** remember, if a sidebox was used */ static int sideboxUsed = 0; /* ** Add a new element to the submenu */ void style_submenu_element( const char *zLabel, const char *zTitle, const char *zLink, | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
static int headerHasBeenGenerated = 0;
/*
** remember, if a sidebox was used
*/
static int sideboxUsed = 0;
/*
** List of hyperlinks that need to be resolved by javascript in
** the footer.
*/
char **aHref = 0;
int nHref = 0;
int nHrefAlloc = 0;
/*
** Generate and return a anchor tag like this:
**
** <a href="URL">
** or <a id="ID">
**
** The form of the anchor tag is determined by the g.javascriptHyperlink
** variable. The href="URL" form is used if g.javascriptHyperlink is false.
** If g.javascriptHyperlink is true then the
** id="ID" form is used and javascript is generated in the footer to cause
** href values to be inserted after the page has loaded. If
** g.perm.History is false, then the <a id="ID"> form is still
** generated but the javascript is not generated so the links never
** activate.
**
** Filling in the href="URL" using javascript is a defense against bots.
**
** The name of this routine is deliberately kept short so that can be
** easily used within @-lines. Example:
**
** @ %z(href("%R/artifact/%s",zUuid))%h(zFN)</a>
**
** Note %z format. The string returned by this function is always
** obtained from fossil_malloc() so rendering it with %z will reclaim
** that memory space.
**
** There are two versions of this routine: href() does a plain hyperlink
** and xhref() adds extra attribute text.
*/
char *xhref(const char *zExtra, const char *zFormat, ...){
char *zUrl;
va_list ap;
va_start(ap, zFormat);
zUrl = vmprintf(zFormat, ap);
va_end(ap);
if( g.perm.Hyperlink && !g.javascriptHyperlink ){
return mprintf("<a %s href=\"%z\">", zExtra, zUrl);
}
if( nHref>=nHrefAlloc ){
nHrefAlloc = nHrefAlloc*2 + 10;
aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
}
aHref[nHref++] = zUrl;
return mprintf("<a %s id=%d>", zExtra, nHref);
}
char *href(const char *zFormat, ...){
char *zUrl;
va_list ap;
va_start(ap, zFormat);
zUrl = vmprintf(zFormat, ap);
va_end(ap);
if( g.perm.Hyperlink && !g.javascriptHyperlink ){
return mprintf("<a href=\"%z\">", zUrl);
}
if( nHref>=nHrefAlloc ){
nHrefAlloc = nHrefAlloc*2 + 10;
aHref = fossil_realloc(aHref, nHrefAlloc*sizeof(aHref[0]));
}
aHref[nHref++] = zUrl;
return mprintf("<a id=%d>", nHref);
}
/*
** Generate javascript that will set the href= attribute on all anchors.
*/
void style_resolve_href(void){
int i;
if( !g.perm.Hyperlink || !g.javascriptHyperlink || nHref==0 ) return;
@ <script type="text/JavaScript">
@ /* <![CDATA[ */
@ function u(i,h){ document.getElementById(i).href=h; }
for(i=0; i<nHref; i++){
@ u(%d(i+1),"%s(aHref[i])");
}
@ /* ]]> */
@ </script>
}
/*
** Add a new element to the submenu
*/
void style_submenu_element(
const char *zLabel,
const char *zTitle,
const char *zLink,
|
| ︙ | ︙ | |||
151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
/* Put the footer at the bottom of the page.
** the additional clear/both is needed to extend the content
** part to the end of an optional sidebox.
*/
@ <div class="endContent"></div>
}
@ </div>
zFooter = db_get("footer", (char*)zDefaultFooter);
if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1);
Th_Render(zFooter);
if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1);
/* Render trace log if TH1 tracing is enabled. */
if( g.thTrace ){
| > > > > > | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
/* Put the footer at the bottom of the page.
** the additional clear/both is needed to extend the content
** part to the end of an optional sidebox.
*/
@ <div class="endContent"></div>
}
@ </div>
/* Set the href= field on hyperlinks. Do this before the footer since
** the footer will be generating </html> */
style_resolve_href();
zFooter = db_get("footer", (char*)zDefaultFooter);
if( g.thTrace ) Th_Trace("BEGIN_FOOTER<br />\n", -1);
Th_Render(zFooter);
if( g.thTrace ) Th_Trace("END_FOOTER<br />\n", -1);
/* Render trace log if TH1 tracing is enabled. */
if( g.thTrace ){
|
| ︙ | ︙ |
Changes to src/tag.c.
| ︙ | ︙ | |||
546 547 548 549 550 551 552 |
" AND tagtype=1)"
" AND tagname GLOB 'sym-*'"
" ORDER BY tagname"
);
@ <ul>
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
| | | | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
" AND tagtype=1)"
" AND tagname GLOB 'sym-*'"
" ORDER BY tagname"
);
@ <ul>
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
if( g.perm.Hyperlink ){
@ <li>%z(xhref("class='taglink'","%R/timeline?t=%T",zName))
@ %h(zName)</a></li>
}else{
@ <li><span class="tagDsp">%h(zName)</span></li>
}
}
@ </ul>
db_finalize(&q);
|
| ︙ | ︙ |
Changes to src/tar.c.
| ︙ | ︙ | |||
541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
const char *zName;
zName = find_option("name", 0, 1);
db_find_and_open_repository(0, 0);
if( g.argc!=4 ){
usage("VERSION OUTPUTFILE");
}
rid = name_to_typed_rid(g.argv[2], "ci");
if( zName==0 ){
zName = db_text("default-name",
"SELECT replace(%Q,' ','_') "
" || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
" || substr(blob.uuid, 1, 10)"
" FROM event, blob"
" WHERE event.objid=%d"
| > > > > > | 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 |
const char *zName;
zName = find_option("name", 0, 1);
db_find_and_open_repository(0, 0);
if( g.argc!=4 ){
usage("VERSION OUTPUTFILE");
}
rid = name_to_typed_rid(g.argv[2], "ci");
if( rid==0 ){
fossil_fatal("Checkin not found: %s", g.argv[2]);
return;
}
if( zName==0 ){
zName = db_text("default-name",
"SELECT replace(%Q,' ','_') "
" || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) "
" || substr(blob.uuid, 1, 10)"
" FROM event, blob"
" WHERE event.objid=%d"
|
| ︙ | ︙ | |||
590 591 592 593 594 595 596 |
for(nName=strlen(zName)-1; nName>5; nName--){
if( zName[nName]=='.' ){
zName[nName] = 0;
break;
}
}
}
| | | 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 |
for(nName=strlen(zName)-1; nName>5; nName--){
if( zName[nName]=='.' ){
zName[nName] = 0;
break;
}
}
}
rid = name_to_typed_rid(nRid?zRid:zName, "ci");
if( rid==0 ){
@ Not found
return;
}
if( nRid==0 && nName>10 ) zName[10] = 0;
tarball_of_checkin(rid, &tarball, zName);
free( zName );
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 |
/*
** Generate a hyperlink to a version.
*/
void hyperlink_to_uuid(const char *zUuid){
char z[UUID_SIZE+1];
shorten_uuid(z, zUuid);
| | | | | | | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
/*
** Generate a hyperlink to a version.
*/
void hyperlink_to_uuid(const char *zUuid){
char z[UUID_SIZE+1];
shorten_uuid(z, zUuid);
if( g.perm.Hyperlink ){
@ %z(xhref("class='timelineHistLink'","%R/info/%s",z))[%s(z)]</a>
}else{
@ <span class="timelineHistDsp">[%s(z)]</span>
}
}
/*
** Generate a hyperlink to a diff between two versions.
*/
void hyperlink_to_diff(const char *zV1, const char *zV2){
if( g.perm.Hyperlink ){
if( zV2==0 ){
@ %z(href("%R/diff?v2=%s",zV1))[diff]</a>
}else{
@ %z(href("%R/diff?v1=%s&v2=%s",zV1,zV2))[diff]</a>
}
}
}
/*
** Generate a hyperlink to a date & time.
*/
void hyperlink_to_date(const char *zDate, const char *zSuffix){
if( zSuffix==0 ) zSuffix = "";
if( g.perm.Hyperlink ){
@ %z(href("%R/timeline?c=%T",zDate))%s(zDate)</a>%s(zSuffix)
}else{
@ %s(zDate)%s(zSuffix)
}
}
/*
** Generate a hyperlink to a user. This will link to a timeline showing
** events by that user. If the date+time is specified, then the timeline
** is centered on that date+time.
*/
void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
if( zSuf==0 ) zSuf = "";
if( g.perm.Hyperlink ){
if( zD && zD[0] ){
@ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf)
}else{
@ %z(href("%R/timeline?u=%T",zU))%h(zU)</a>%s(zSuf)
}
}else{
@ %s(zU)
}
}
/*
|
| ︙ | ︙ | |||
351 352 353 354 355 356 357 |
}
blob_reset(&comment);
/* Generate the "user: USERNAME" at the end of the comment, together
** with a hyperlink to another timeline for that user.
*/
if( zTagList && zTagList[0]==0 ) zTagList = 0;
| | | < | < | | | | | | 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 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
}
blob_reset(&comment);
/* Generate the "user: USERNAME" at the end of the comment, together
** with a hyperlink to another timeline for that user.
*/
if( zTagList && zTagList[0]==0 ) zTagList = 0;
if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){
char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate);
@ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051")
}else{
@ (user: %h(zUser)%s(zTagList?",":"\051")
}
/* Generate a "detail" link for tags. */
if( zType[0]=='g' && g.perm.Hyperlink ){
@ [%z(href("%R/info/%S",zUuid))details</a>]
}
/* Generate the "tags: TAGLIST" at the end of the comment, together
** with hyperlinks to the tag list.
*/
if( zTagList ){
if( g.perm.Hyperlink ){
int i;
const char *z = zTagList;
Blob links;
blob_zero(&links);
while( z && z[0] ){
for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
blob_appendf(&links,
"%z%#h</a>%.2s",
href("%R/timeline?r=%#t&nd&c=%s",i,z,zDate), i,z, &z[i]
);
}else{
blob_appendf(&links, "%#h", i+2, z);
}
if( z[i]==0 ) break;
z += i+2;
}
|
| ︙ | ︙ | |||
401 402 403 404 405 406 407 |
/* Generate extra hyperlinks at the end of the comment */
if( xExtra ){
xExtra(rid);
}
/* Generate the file-change list if requested */
| | | 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 |
/* Generate extra hyperlinks at the end of the comment */
if( xExtra ){
xExtra(rid);
}
/* Generate the file-change list if requested */
if( (tmFlags & TIMELINE_FCHANGES)!=0 && zType[0]=='c' && g.perm.Hyperlink ){
int inUl = 0;
if( !fchngQueryInit ){
db_prepare(&fchngQuery,
"SELECT (pid==0) AS isnew,"
" (fid==0) AS isdel,"
" (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
" (SELECT uuid FROM blob WHERE rid=fid),"
|
| ︙ | ︙ | |||
431 432 433 434 435 436 437 |
const char *zNew = db_column_text(&fchngQuery, 3);
if( !inUl ){
@ <ul class="filelist">
inUl = 1;
}
if( isNew ){
@ <li> %h(zFilename) (new file)
| | | | | | | | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
const char *zNew = db_column_text(&fchngQuery, 3);
if( !inUl ){
@ <ul class="filelist">
inUl = 1;
}
if( isNew ){
@ <li> %h(zFilename) (new file)
@ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew))
@ [view]</a></li>
}else if( isDel ){
@ <li> %h(zFilename) (deleted)</li>
}else if( fossil_strcmp(zOld,zNew)==0 && zOldName!=0 ){
@ <li> %h(zOldName) → %h(zFilename)
@ %z(xhref("target='diffwindow'","%R/artifact/%S",zNew))
@ [view]</a></li>
}else{
if( zOldName!=0 ){
@ <li> %h(zOldName) → %h(zFilename)
}else{
@ <li> %h(zFilename)
}
@ %z(xhref("target='diffwindow'","%R/fdiff?v1=%S&v2=%S",zOld,zNew))
@ [diff]</a></li>
}
}
db_reset(&fchngQuery);
if( inUl ){
@ </ul>
}
}
|
| ︙ | ︙ | |||
972 973 974 975 976 977 978 |
while( p ){
blob_appendf(&sql, ",%d", p->rid);
p = p->u.pTo;
}
blob_append(&sql, ")", -1);
path_reset();
blob_append(&desc, "All nodes on the path from ", -1);
| < < < | < < < < | < | 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 |
while( p ){
blob_appendf(&sql, ",%d", p->rid);
p = p->u.pTo;
}
blob_append(&sql, ")", -1);
path_reset();
blob_append(&desc, "All nodes on the path from ", -1);
blob_appendf(&desc, "%z%h</a>", href("%R/info/%h", zFrom), zFrom);
blob_append(&desc, " and ", -1);
blob_appendf(&desc, "%z[%h]</a>", href("%R/info/%h",zTo), zTo);
tmFlags |= TIMELINE_DISJOINT;
db_multi_exec("%s", blob_str(&sql));
}else if( (p_rid || d_rid) && g.perm.Read ){
/* If p= or d= is present, ignore all other parameters other than n= */
char *zUuid;
int np, nd;
|
| ︙ | ︙ | |||
1019 1020 1021 1022 1023 1024 1025 |
if( np>0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
blob_appendf(&desc, "%d ancestors", np);
db_multi_exec("%s", blob_str(&sql));
}
if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
}
| < | | < < < < < < < | < | 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 |
if( np>0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
blob_appendf(&desc, "%d ancestors", np);
db_multi_exec("%s", blob_str(&sql));
}
if( d_rid==0 && useDividers ) timeline_add_dividers(0, p_rid);
}
blob_appendf(&desc, " of %z[%.10s]</a>",
href("%R/info/%s", zUuid), zUuid);
}else if( f_rid && g.perm.Read ){
/* If f= is present, ignore all other parameters other than n= */
char *zUuid;
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY);"
"INSERT INTO ok VALUES(%d);"
"INSERT OR IGNORE INTO ok SELECT pid FROM plink WHERE cid=%d;"
"INSERT OR IGNORE INTO ok SELECT cid FROM plink WHERE pid=%d;",
f_rid, f_rid, f_rid
);
blob_appendf(&sql, " AND event.objid IN ok");
db_multi_exec("%s", blob_str(&sql));
if( useDividers ) timeline_add_dividers(0, f_rid);
blob_appendf(&desc, "Parents and children of check-in ");
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid);
}else{
/* Otherwise, a timeline based on a span of time */
int n;
const char *zEType = "timeline item";
char *zDate;
char *zNEntry = mprintf("%d", nEntry);
url_add_parameter(&url, "n", zNEntry);
|
| ︙ | ︙ | |||
1217 1218 1219 1220 1221 1222 1223 |
blob_appendf(&desc, " occurring on or before %h.<br />", zBefore);
}else if( zCirca ){
blob_appendf(&desc, " occurring around %h.<br />", zCirca);
}
if( zSearch ){
blob_appendf(&desc, " matching \"%h\"", zSearch);
}
| | | 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 |
blob_appendf(&desc, " occurring on or before %h.<br />", zBefore);
}else if( zCirca ){
blob_appendf(&desc, " occurring around %h.<br />", zCirca);
}
if( zSearch ){
blob_appendf(&desc, " matching \"%h\"", zSearch);
}
if( g.perm.Hyperlink ){
if( zAfter || n==nEntry ){
zDate = db_text(0, "SELECT min(timestamp) FROM timeline /*scan*/");
timeline_submenu(&url, "Older", "b", zDate, "a");
free(zDate);
}
if( zBefore || (zAfter && n==nEntry) ){
zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
|
| ︙ | ︙ | |||
1621 1622 1623 1624 1625 1626 1627 |
/*
** WEBPAGE: test_timewarps
*/
void test_timewarp_page(void){
Stmt q;
login_check_credentials();
| | | | 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 |
/*
** WEBPAGE: test_timewarps
*/
void test_timewarp_page(void){
Stmt q;
login_check_credentials();
if( !g.perm.Read || !g.perm.Hyperlink ){ login_needed(); return; }
style_header("Instances of timewarp");
@ <ul>
db_prepare(&q,
"SELECT blob.uuid "
" FROM plink p, plink c, blob"
" WHERE p.cid=c.pid AND p.mtime>c.mtime"
" AND blob.rid=c.cid"
);
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
@ <li>
@ <a href="%s(g.zTop)/timeline?p=%S(zUuid)&d=%S(zUuid)">%S(zUuid)</a>
}
db_finalize(&q);
style_footer();
}
/*
* vim:ts=2:sts=2:et:sw=2:ft=c
*/
|
Changes to src/tkt.c.
| ︙ | ︙ | |||
303 304 305 306 307 308 309 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
if( g.perm.WrTkt || g.perm.ApndTkt ){
style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T",
g.zTop, PD("name",""));
}
| | | | 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
login_check_credentials();
if( !g.perm.RdTkt ){ login_needed(); return; }
if( g.perm.WrTkt || g.perm.ApndTkt ){
style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T",
g.zTop, PD("name",""));
}
if( g.perm.Hyperlink ){
style_submenu_element("History", "History Of This Ticket",
"%s/tkthistory/%T", g.zTop, zUuid);
style_submenu_element("Timeline", "Timeline Of This Ticket",
"%s/tkttimeline/%T", g.zTop, zUuid);
style_submenu_element("Check-ins", "Check-ins Of This Ticket",
"%s/tkttimeline/%T?y=ci", g.zTop, zUuid);
}
if( g.perm.NewTkt ){
style_submenu_element("New Ticket", "Create a new ticket",
"%s/tktnew", g.zTop);
}
if( g.perm.ApndTkt && g.perm.Attach ){
style_submenu_element("Attach", "Add An Attachment",
"%s/attachadd?tkt=%T&from=%s/tktview/%t",
g.zTop, zUuid, g.zTop, zUuid);
}
style_header("View Ticket");
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
ticket_init();
initializeVariablesFromDb();
zScript = ticket_viewpage_code();
|
| ︙ | ︙ | |||
351 352 353 354 355 356 357 |
const char *zUser = db_column_text(&q, 2);
if( cnt==0 ){
@ <hr /><h2>Attachments:</h2>
@ <ul>
}
cnt++;
@ <li>
| | | | | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
const char *zUser = db_column_text(&q, 2);
if( cnt==0 ){
@ <hr /><h2>Attachments:</h2>
@ <ul>
}
cnt++;
@ <li>
if( g.perm.Read && g.perm.Hyperlink ){
@ %z(href("%R/attachview?tkt=%s&file=%t",zFullName,zFile))
@ %h(zFile)</a>
}else{
@ %h(zFile)
}
@ added by %h(zUser) on
hyperlink_to_date(zDate, ".");
if( g.perm.WrTkt && g.perm.Attach ){
@ [%z(href("%R/attachdelete?tkt=%s&file=%t&from=%R/tktview%%3fname=%s",zFullName,zFile,zFullName))delete</a>]
}
@ </li>
}
if( cnt ){
@ </ul>
}
db_finalize(&q);
|
| ︙ | ︙ | |||
645 646 647 648 649 650 651 |
}
}
return 0;
}
/*
** WEBPAGE: tkttimeline
| | | | | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 |
}
}
return 0;
}
/*
** WEBPAGE: tkttimeline
** URL: /tkttimeline?name=TICKETUUID&y=TYPE
**
** Show the change history for a single ticket in timeline format.
*/
void tkttimeline_page(void){
Stmt q;
char *zTitle;
char *zSQL;
const char *zUuid;
char *zFullUuid;
int tagid;
char zGlobPattern[50];
const char *zType;
login_check_credentials();
if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
zUuid = PD("name","");
zType = PD("y","a");
if( zType[0]!='c' ){
style_submenu_element("Check-ins", "Check-ins",
"%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid);
}else{
style_submenu_element("Timeline", "Timeline",
"%s/tkttimeline?name=%T", g.zTop, zUuid);
}
style_submenu_element("History", "History",
"%s/tkthistory/%s", g.zTop, zUuid);
style_submenu_element("Status", "Status",
|
| ︙ | ︙ | |||
734 735 736 737 738 739 740 |
void tkthistory_page(void){
Stmt q;
char *zTitle;
const char *zUuid;
int tagid;
login_check_credentials();
| | | | 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 |
void tkthistory_page(void){
Stmt q;
char *zTitle;
const char *zUuid;
int tagid;
login_check_credentials();
if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
zUuid = PD("name","");
zTitle = mprintf("History Of Ticket %h", zUuid);
style_submenu_element("Status", "Status",
"%s/info/%s", g.zTop, zUuid);
style_submenu_element("Check-ins", "Check-ins",
"%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid);
style_submenu_element("Timeline", "Timeline",
"%s/tkttimeline?name=%s", g.zTop, zUuid);
style_header(zTitle);
free(zTitle);
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
if( tagid==0 ){
|
| ︙ | ︙ | |||
784 785 786 787 788 789 790 |
if( zSrc==0 || zSrc[0]==0 ){
@
@ <p>Delete attachment "%h(zFile)"
}else{
@
@ <p>Add attachment "%h(zFile)"
}
| | | | 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 |
if( zSrc==0 || zSrc[0]==0 ){
@
@ <p>Delete attachment "%h(zFile)"
}else{
@
@ <p>Add attachment "%h(zFile)"
}
@ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
@ (rid %d(rid)) by
hyperlink_to_user(zUser,zDate," on");
hyperlink_to_date(zDate, ".</p>");
}else{
pTicket = manifest_get(rid, CFTYPE_TICKET);
if( pTicket ){
@
@ <p>Ticket change
@ [%z(href("%R/artifact/%T",zChngUuid))%s(zShort)</a>]
@ (rid %d(rid)) by
hyperlink_to_user(pTicket->zUser,zDate," on");
hyperlink_to_date(zDate, ":");
@ </p>
ticket_output_change_artifact(pTicket);
}
manifest_destroy(pTicket);
|
| ︙ | ︙ |
Changes to src/translate.c.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** Input lines that begin with the "@" character are translated into ** either cgi_printf() statements or string literals and the ** translated code is written on standard output. ** ** The problem this program is attempt to solve is as follows: When ** writing CGI programs in C, we typically want to output a lot of HTML ** text to standard output. In pure C code, this involves doing a ** printf() with a big string containing all that text. But we have ** to insert special codes (ex: \n and \") for many common characters, ** which interferes with the readability of the HTML. ** ** This tool allows us to put raw HTML, without the special codes, in ** the middle of a C program. This program then translates the text ** into standard C by inserting all necessary backslashes and other ** punctuation. */ #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h> /* | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** SYNOPSIS: ** ** Input lines that begin with the "@" character are translated into ** either cgi_printf() statements or string literals and the ** translated code is written on standard output. ** ** The problem this program is attempt to solve is as follows: When ** writing CGI programs in C, we typically want to output a lot of HTML ** text to standard output. In pure C code, this involves doing a ** printf() with a big string containing all that text. But we have ** to insert special codes (ex: \n and \") for many common characters, ** which interferes with the readability of the HTML. ** ** This tool allows us to put raw HTML, without the special codes, in ** the middle of a C program. This program then translates the text ** into standard C by inserting all necessary backslashes and other ** punctuation. ** */ #include <stdio.h> #include <ctype.h> #include <stdlib.h> #include <string.h> /* |
| ︙ | ︙ | |||
117 118 119 120 121 122 123 |
fprintf(out,"\n");
}else{
fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
}
}else{
/* Otherwise (if the last non-whitespace was not '=') then generate
** a cgi_printf() statement whose format is the text following the '@'.
| | | | > > | | | < | | > | | | | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
fprintf(out,"\n");
}else{
fprintf(out,"%*s\"%s\\n\"\n",indent, "", zOut);
}
}else{
/* Otherwise (if the last non-whitespace was not '=') then generate
** a cgi_printf() statement whose format is the text following the '@'.
** Substrings of the form "%C(...)" (where C is any sequence of
** characters other than \000 and '(') will put "%C" in the
** format and add the "(...)" as an argument to the cgi_printf call.
*/
int indent;
int nC;
char c;
i++;
if( isspace(zLine[i]) ){ i++; }
indent = i;
for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
if( zLine[i]=='"' || zLine[i]=='\\' ){ zOut[j++] = '\\'; }
zOut[j++] = zLine[i];
if( zLine[i]!='%' || zLine[i+1]=='%' || zLine[i+1]==0 ) continue;
for(nC=1; zLine[i+nC] && zLine[i+nC]!='('; nC++){}
if( zLine[i+nC]!='(' || !isalpha(zLine[i+nC-1]) ) continue;
while( --nC ) zOut[j++] = zLine[++i];
zArg[nArg++] = ',';
k = 0; i++;
while( (c = zLine[i])!=0 ){
zArg[nArg++] = c;
if( c==')' ){
k--;
if( k==0 ) break;
}else if( c=='(' ){
k++;
}
i++;
}
}
zOut[j] = 0;
if( !inPrint ){
fprintf(out,"%*scgi_printf(\"%s\\n\"",indent-2,"", zOut);
inPrint = 1;
}else{
|
| ︙ | ︙ |
Changes to src/update.c.
| ︙ | ︙ | |||
118 119 120 121 122 123 124 |
verboseFlag = find_option("verbose","v",0)!=0;
debugFlag = find_option("debug",0,0)!=0;
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_fatal("cannot find current version");
}
| < < < | > | | 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
verboseFlag = find_option("verbose","v",0)!=0;
debugFlag = find_option("debug",0,0)!=0;
db_must_be_within_tree();
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_fatal("cannot find current version");
}
if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL);
/* Create any empty directories now, as well as after the update,
** so changes in settings are reflected now */
if( !nochangeFlag ) ensure_empty_dirs_created();
if( internalUpdate ){
tid = internalUpdate;
}else if( g.argc>=3 ){
if( fossil_strcmp(g.argv[2], "current")==0 ){
/* If VERSION is "current", then use the same algorithm to find the
** target as if VERSION were omitted. */
|
| ︙ | ︙ | |||
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 |
db_finalize(&mtimeXfer);
fossil_print("--------------\n");
show_common_info(tid, "updated-to:", 1, 0);
/* Report on conflicts
*/
if( !nochangeFlag ){
if( nConflict ){
if( internalUpdate ){
internalConflictCnt = nConflict;
nConflict = 0;
}else{
fossil_warning("WARNING: %d merge conflicts", nConflict);
}
}
if( nOverwrite ){
fossil_warning("WARNING: %d unmanaged files were overwritten",
nOverwrite);
}
}
/*
** Clean up the mid and pid VFILE entries. Then commit the changes.
*/
if( nochangeFlag ){
db_end_transaction(1); /* With --nochange, rollback changes */
| > > > > > > > > > > > > > > > > > > > | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
db_finalize(&mtimeXfer);
fossil_print("--------------\n");
show_common_info(tid, "updated-to:", 1, 0);
/* Report on conflicts
*/
if( !nochangeFlag ){
Stmt q;
int nMerge = 0;
db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
" WHERE id<=0");
while( db_step(&q)==SQLITE_ROW ){
const char *zLabel = "merge";
switch( db_column_int(&q, 1) ){
case -1: zLabel = "cherrypick merge"; break;
case -2: zLabel = "backout merge"; break;
}
fossil_warning("uncommitted %s against %S.",
zLabel, db_column_text(&q, 0));
nMerge++;
}
db_finalize(&q);
if( nConflict ){
if( internalUpdate ){
internalConflictCnt = nConflict;
nConflict = 0;
}else{
fossil_warning("WARNING: %d merge conflicts", nConflict);
}
}
if( nOverwrite ){
fossil_warning("WARNING: %d unmanaged files were overwritten",
nOverwrite);
}
if( nMerge ){
fossil_warning("WARNING: %d uncommitted prior merges", nMerge);
}
}
/*
** Clean up the mid and pid VFILE entries. Then commit the changes.
*/
if( nochangeFlag ){
db_end_transaction(1); /* With --nochange, rollback changes */
|
| ︙ | ︙ |
Changes to src/wiki.c.
| ︙ | ︙ | |||
102 103 104 105 106 107 108 |
g.isHome = 1;
wiki_page();
return;
}
style_header("Home");
@ <p>This is a stub home-page for the project.
@ To fill in this page, first go to
| | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
g.isHome = 1;
wiki_page();
return;
}
style_header("Home");
@ <p>This is a stub home-page for the project.
@ To fill in this page, first go to
@ %z(href("%R/setup_config"))setup/config</a>
@ and establish a "Project Name". Then create a
@ wiki page with that name. The content of that wiki page
@ will be displayed in place of this message.</p>
style_footer();
}
/*
|
| ︙ | ︙ | |||
140 141 142 143 144 145 146 |
if( !g.perm.RdWiki ){ login_needed(); return; }
zPageName = P("name");
if( zPageName==0 ){
style_header("Wiki");
@ <ul>
{ char *zHomePageName = db_get("project-name",0);
if( zHomePageName ){
| | | < | < | | | | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
if( !g.perm.RdWiki ){ login_needed(); return; }
zPageName = P("name");
if( zPageName==0 ){
style_header("Wiki");
@ <ul>
{ char *zHomePageName = db_get("project-name",0);
if( zHomePageName ){
@ <li> %z(href("%R/wiki?name=%t",zHomePageName))
@ %h(zHomePageName)</a> wiki home page.</li>
}
}
@ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li>
@ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li>
@ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a>
@ to experiment.</li>
if( g.perm.NewWiki ){
@ <li> Create a %z(href("%R/wikinew"))new wiki page</a>.</li>
if( g.perm.Write ){
@ <li> Create a %z(href("%R/eventedit"))new event</a>.</li>
}
}
@ <li> %z(href("%R/wcontent"))List of All Wiki Pages</a>
@ available on this server.</li>
@ <li> <form method="get" action="%s(g.zTop)/wfind"><div>
@ Search wiki titles: <input type="text" name="title"/>
@ <input type="submit" /></div></form>
@ </li>
@ </ul>
style_footer();
|
| ︙ | ︙ | |||
190 191 192 193 194 195 196 |
if( !g.isHome ){
if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T",
g.zTop, zPageName);
}
if( rid && g.perm.ApndWiki && g.perm.Attach ){
style_submenu_element("Attach", "Add An Attachment",
| | | | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
if( !g.isHome ){
if( (rid && g.perm.WrWiki) || (!rid && g.perm.NewWiki) ){
style_submenu_element("Edit", "Edit Wiki Page", "%s/wikiedit?name=%T",
g.zTop, zPageName);
}
if( rid && g.perm.ApndWiki && g.perm.Attach ){
style_submenu_element("Attach", "Add An Attachment",
"%s/attachadd?page=%T&from=%s/wiki%%3fname=%T",
g.zTop, zPageName, g.zTop, zPageName);
}
if( rid && g.perm.ApndWiki ){
style_submenu_element("Append", "Add A Comment", "%s/wikiappend?name=%T",
g.zTop, zPageName);
}
if( g.perm.Hyperlink ){
style_submenu_element("History", "History", "%s/whistory?name=%T",
g.zTop, zPageName);
}
}
style_header(zPageName);
blob_init(&wiki, zBody, -1);
wiki_convert(&wiki, 0, 0);
|
| ︙ | ︙ | |||
223 224 225 226 227 228 229 |
const char *zUser = db_column_text(&q, 2);
if( cnt==0 ){
@ <hr /><h2>Attachments:</h2>
@ <ul>
}
cnt++;
@ <li>
| | | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
const char *zUser = db_column_text(&q, 2);
if( cnt==0 ){
@ <hr /><h2>Attachments:</h2>
@ <ul>
}
cnt++;
@ <li>
if( g.perm.Hyperlink && g.perm.Read ){
@ %z(href("%R/attachview?page=%T&file=%t",zPageName,zFile))
@ %h(zFile)</a>
}else{
@ %h(zFile)
}
@ added by %h(zUser) on
hyperlink_to_date(zDate, ".");
if( g.perm.WrWiki && g.perm.Attach ){
@ [%z(href("%R/attachdelete?page=%t&file=%t&from=%R/wiki%%3fname=%f",zPageName,zFile,zPageName))delete</a>]
}
@ </li>
}
if( cnt ){
@ </ul>
}
db_finalize(&q);
|
| ︙ | ︙ | |||
542 543 544 545 546 547 548 |
/*
** Function called to output extra text at the end of each line in
** a wiki history listing.
*/
static void wiki_history_extra(int rid){
if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){
| | | | 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 |
/*
** Function called to output extra text at the end of each line in
** a wiki history listing.
*/
static void wiki_history_extra(int rid){
if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d", rid) ){
@ %z(href("%R/wdiff?name=%t&a=%d",zWikiPageName,rid))[diff]</a>
}
}
/*
** WEBPAGE: whistory
** URL: /whistory?name=PAGENAME
**
** Show the complete change history for a single wiki page.
*/
void whistory_page(void){
Stmt q;
char *zTitle;
char *zSQL;
const char *zPageName;
login_check_credentials();
if( !g.perm.Hyperlink ){ login_needed(); return; }
zPageName = PD("name","");
zTitle = mprintf("History Of %s", zPageName);
style_header(zTitle);
free(zTitle);
zSQL = mprintf("%s AND event.objid IN "
" (SELECT rid FROM tagxref WHERE tagid="
|
| ︙ | ︙ | |||
595 596 597 598 599 600 601 |
const char *zPageName;
Manifest *pW1, *pW2 = 0;
Blob w1, w2, d;
int diffFlags;
login_check_credentials();
rid1 = atoi(PD("a","0"));
| | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 |
const char *zPageName;
Manifest *pW1, *pW2 = 0;
Blob w1, w2, d;
int diffFlags;
login_check_credentials();
rid1 = atoi(PD("a","0"));
if( !g.perm.Hyperlink ){ login_needed(); return; }
if( rid1==0 ) fossil_redirect_home();
rid2 = atoi(PD("b","0"));
zPageName = PD("name","");
zTitle = mprintf("Changes To %s", zPageName);
style_header(zTitle);
free(zTitle);
|
| ︙ | ︙ | |||
672 673 674 675 676 677 678 |
}
@ <ul>
wiki_prepare_page_list(&q);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
int size = db_column_int(&q, 1);
if( size>0 ){
| | | | 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 |
}
@ <ul>
wiki_prepare_page_list(&q);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
int size = db_column_int(&q, 1);
if( size>0 ){
@ <li>%z(href("%R/wiki?name=%T",zName))%h(zName)</a></li>
}else if( showAll ){
@ <li>%z(href("%R/wiki?name=%T",zName))<s>%h(zName)</s></a></li>
}
}
db_finalize(&q);
@ </ul>
style_footer();
}
|
| ︙ | ︙ | |||
702 703 704 705 706 707 708 |
@ <ul>
db_prepare(&q,
"SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
" ORDER BY lower(tagname) /*sort*/" ,
zTitle);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
| | | 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 |
@ <ul>
db_prepare(&q,
"SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
" ORDER BY lower(tagname) /*sort*/" ,
zTitle);
while( db_step(&q)==SQLITE_ROW ){
const char *zName = db_column_text(&q, 0);
@ <li>%z(href("%R/wiki?name=%T",zName))%h(zName)</a></li>
}
db_finalize(&q);
@ </ul>
style_footer();
}
/*
|
| ︙ | ︙ |
Changes to src/wikiformat.c.
| ︙ | ︙ | |||
1041 1042 1043 1044 1045 1046 1047 |
|| strncmp(zTarget, "https:", 6)==0
|| strncmp(zTarget, "ftp:", 4)==0
|| strncmp(zTarget, "mailto:", 7)==0
){
blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
/* zTerm = "⟾</a>"; // doesn't work on windows */
}else if( zTarget[0]=='/' ){
| < | < < < | | | | | | < < | | | 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 |
|| strncmp(zTarget, "https:", 6)==0
|| strncmp(zTarget, "ftp:", 4)==0
|| strncmp(zTarget, "mailto:", 7)==0
){
blob_appendf(p->pOut, "<a href=\"%s\">", zTarget);
/* zTerm = "⟾</a>"; // doesn't work on windows */
}else if( zTarget[0]=='/' ){
blob_appendf(p->pOut, "<a href=\"%s%h\">", g.zTop, zTarget);
}else if( zTarget[0]=='.' || zTarget[0]=='#' ){
if( 1 ){
blob_appendf(p->pOut, "<a href=\"%h\">", zTarget);
}else{
zTerm = "";
}
}else if( is_valid_uuid(zTarget) ){
int isClosed = 0;
if( is_ticket(zTarget, &isClosed) ){
/* Special display processing for tickets. Display the hyperlink
** as crossed out if the ticket is closed.
*/
if( isClosed ){
if( g.perm.Hyperlink ){
blob_appendf(p->pOut,
"%z<span class=\"wikiTagCancelled\">[",
href("%R/info/%s",zTarget)
);
zTerm = "]</span></a>";
}else{
blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">[");
zTerm = "]</span>";
}
}else{
if( g.perm.Hyperlink ){
blob_appendf(p->pOut,"%z[", href("%R/info/%s", zTarget));
zTerm = "]</a>";
}else{
blob_appendf(p->pOut, "[");
zTerm = "]";
}
}
}else if( !in_this_repo(zTarget) ){
blob_appendf(p->pOut, "<span class=\"brokenlink\">[", zTarget);
zTerm = "]</span>";
}else if( g.perm.Hyperlink ){
blob_appendf(p->pOut, "%z[",href("%R/info/%s", zTarget));
zTerm = "]</a>";
}
}else if( strlen(zTarget)>=10 && fossil_isdigit(zTarget[0]) && zTarget[4]=='-'
&& db_int(0, "SELECT datetime(%Q) NOT NULL", zTarget) ){
blob_appendf(p->pOut, "<a href=\"%s/timeline?c=%T\">", g.zTop, zTarget);
}else if( strncmp(zTarget, "wiki:", 5)==0
&& wiki_name_is_wellformed((const unsigned char*)zTarget) ){
|
| ︙ | ︙ |
Changes to src/winhttp.c.
| ︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 |
/*
** Get message string of the last system error. Return a pointer to the
** message string. Call fossil_mbcs_free() to deallocate any memory used
** to store the message string when done.
*/
static char *win32_get_last_errmsg(void){
DWORD nMsg;
LPTSTR tmp = NULL;
char *zMsg = NULL;
nMsg = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
| > > | > > > > > > > > > > > > > > | | 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
/*
** Get message string of the last system error. Return a pointer to the
** message string. Call fossil_mbcs_free() to deallocate any memory used
** to store the message string when done.
*/
static char *win32_get_last_errmsg(void){
DWORD nMsg;
DWORD nErr = GetLastError();
LPTSTR tmp = NULL;
char *zMsg = NULL;
/* Try first to get the error text in english. */
nMsg = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
nErr,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPTSTR) &tmp,
0,
NULL
);
if( !nMsg ){
/* No english, get what the system has available. */
nMsg = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
nErr,
0,
(LPTSTR) &tmp,
0,
NULL
);
}
if( nMsg ){
zMsg = fossil_mbcs_to_utf8(tmp);
}else{
fossil_fatal("unable to get system error message.");
}
if( tmp ){
LocalFree((HLOCAL) tmp);
}
return zMsg;
}
/*
** Report the current status of the service to the service control manager.
** Make sure that during service startup no control codes are accepted.
*/
static void win32_report_service_status(
DWORD dwCurrentState, /* The current state of the service */
DWORD dwWin32ExitCode, /* The error code to report */
DWORD dwWaitHint /* The estimated time for a pending operation */
){
if( dwCurrentState==SERVICE_START_PENDING ){
ssStatus.dwControlsAccepted = 0;
}else{
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
}
ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
|
| ︙ | ︙ | |||
475 476 477 478 479 480 481 | ** -W|--password PASSWORD ** ** Password for the user account. ** ** The following options are more or less the same as for the "server" ** command and influence the behaviour of the http server: ** | | | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | ** -W|--password PASSWORD ** ** Password for the user account. ** ** The following options are more or less the same as for the "server" ** command and influence the behaviour of the http server: ** ** -P|--port TCPPORT ** ** Specifies the TCP port (default port is 8080) on which the ** server should listen. ** ** -R|--repository REPOSITORY ** ** Specifies the name of the repository to be served. |
| ︙ | ︙ | |||
542 543 544 545 546 547 548 |
const char *zSvcName = "Fossil-DSCM"; /* Default service name */
if( g.argc<3 ){
usage("create|delete|show|start|stop ...");
}
zMethod = g.argv[2];
n = strlen(zMethod);
| < < < | | | | | | | | > > > > > > < < | < < < < < < < < | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 |
const char *zSvcName = "Fossil-DSCM"; /* Default service name */
if( g.argc<3 ){
usage("create|delete|show|start|stop ...");
}
zMethod = g.argv[2];
n = strlen(zMethod);
if( strncmp(zMethod, "create", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_DESCRIPTION
svcDescr = {"Fossil - Distributed Software Configuration Management"};
char *zErrFmt = "unable to create service '%s': %s";
DWORD dwStartType = SERVICE_DEMAND_START;
const char *zDisplay = find_option("display", "D", 1);
const char *zStart = find_option("start", "S", 1);
const char *zUsername = find_option("username", "U", 1);
const char *zPassword = find_option("password", "W", 1);
const char *zPort = find_option("port", "P", 1);
const char *zNotFound = find_option("notfound", 0, 1);
const char *zLocalAuth = find_option("localauth", 0, 0);
const char *zRepository = find_option("repository", "R", 1);
Blob binPath;
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for create method.");
}
/* Process service creation specific options. */
if( !zDisplay ){
zDisplay = zSvcName;
}
if( zStart ){
if( strncmp(zStart, "auto", strlen(zStart))==0 ){
dwStartType = SERVICE_AUTO_START;
}else if( strncmp(zStart, "manual", strlen(zStart))==0 ){
dwStartType = SERVICE_DEMAND_START;
}else{
fossil_fatal(zErrFmt, zSvcName,
"specify 'auto' or 'manual' for the '-S|--start' option");
}
}
/* Process options for Fossil running as server. */
if( zPort && (atoi(zPort)<=0) ){
fossil_fatal(zErrFmt, zSvcName,
"port number must be in the range 1 - 65535.");
}
if( !zRepository ){
db_must_be_within_tree();
}else if( file_isdir(zRepository)==1 ){
g.zRepositoryName = mprintf("%s", zRepository);
file_simplify_name(g.zRepositoryName, -1, 0);
}else{
db_open_repository(zRepository);
}
db_close(0);
/* Build the fully-qualified path to the service binary file. */
blob_zero(&binPath);
blob_appendf(&binPath, "\"%s\" server", fossil_nameofexe());
if( zPort ) blob_appendf(&binPath, " --port %s", zPort);
if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound);
if( zLocalAuth ) blob_append(&binPath, " --localauth", -1);
blob_appendf(&binPath, " \"%s\"", g.zRepositoryName);
|
| ︙ | ︙ | |||
640 641 642 643 644 645 646 |
if( strncmp(zMethod, "delete", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to delete service '%s': %s";
verify_all_options();
| > > > | > | 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 |
if( strncmp(zMethod, "delete", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to delete service '%s': %s";
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for delete method.");
}
hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
QueryServiceStatus(hSvc, &sstat);
if( sstat.dwCurrentState!=SERVICE_STOPPED ){
fossil_print("Stopping service '%s'", zSvcName);
|
| ︙ | ︙ | |||
704 705 706 707 708 709 710 |
static const char *zSvcStates[] = {
"Stopped", "Starting", "Stopping", "Running",
"Continue pending", "Pause pending", "Paused"
};
const char *zSvcState = "";
verify_all_options();
| > > > | > | 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 |
static const char *zSvcStates[] = {
"Stopped", "Starting", "Stopping", "Running",
"Continue pending", "Pause pending", "Paused"
};
const char *zSvcState = "";
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for show method.");
}
hScm = OpenSCManager(NULL, NULL, GENERIC_READ);
if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), GENERIC_READ);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
/* Get the service configuration */
bStatus = QueryServiceConfig(hSvc, NULL, 0, &nRequired);
if( !bStatus && GetLastError()!=ERROR_INSUFFICIENT_BUFFER ){
|
| ︙ | ︙ | |||
782 783 784 785 786 787 788 |
if( strncmp(zMethod, "start", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to start service '%s': %s";
verify_all_options();
| > > > | > | 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 |
if( strncmp(zMethod, "start", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to start service '%s': %s";
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for start method.");
}
hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
QueryServiceStatus(hSvc, &sstat);
if( sstat.dwCurrentState!=SERVICE_RUNNING ){
fossil_print("Starting service '%s'", zSvcName);
|
| ︙ | ︙ | |||
814 815 816 817 818 819 820 |
if( strncmp(zMethod, "stop", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to stop service '%s': %s";
verify_all_options();
| > > > | > | 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 |
if( strncmp(zMethod, "stop", n)==0 ){
SC_HANDLE hScm;
SC_HANDLE hSvc;
SERVICE_STATUS sstat;
char *zErrFmt = "unable to stop service '%s': %s";
verify_all_options();
if( g.argc==4 ){
zSvcName = g.argv[3];
}else if( g.argc>4 ){
fossil_fatal("to much arguments for stop method.");
}
hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS);
if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg());
QueryServiceStatus(hSvc, &sstat);
if( sstat.dwCurrentState!=SERVICE_STOPPED ){
fossil_print("Stopping service '%s'", zSvcName);
|
| ︙ | ︙ |
Added tools/fossilwiki.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 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 130 131 132 |
#!/usr/bin/perl
# vim: cin :
$repofile = shift;
$repocmd = '';
$repocmd = "-R $repofile" if -f $repofile;
$mainpage = '';
@rep = ();
if ( ! -f $repofile )
{
@rep = `fossil info | grep 'project-name'`;
}
else
{
@rep = `fossil info $repofile | grep 'project-name'`;
}
$mainpage = $rep[0];
chomp $mainpage;
$mainpage =~ s/^project-name:\s+//;
@pages = `fossil wiki list $repocmd`;
%pages = ();
foreach $page ( @pages )
{
chomp $page;
$text = `fossil wiki export "$page" $repocmd`;
$pages{$page} = $text;
}
@orphans = ();
@nointernals = ();
@terminals = ();
@empties = ();
%badlinks = ();
%alllinks = ();
%links = ();
foreach $page ( keys %pages )
{
my @links = ();
my $text = $pages{$page};
while ( $text =~ m/\[([^][]+)\]/g )
{
push @links,$1;
}
$numlinks = $#links;
if (@links == ())
{
push @terminals, $page;
}
else
{
my @internals = grep { $_ !~ /(http:)|(mailto:)|(https:)/ } @links;
if (@internals == ())
{
push @nointernals, $page;
}
else
{
@{$links{$page}{'links'}} = map {my ($a,$b) = split /\|/; $a;} @internals;
foreach $internal ( @internals )
{
my ($int_link, $display) = split /\|/, $internal;
${$links{$int_link}{'refs'}}++;
$alllinks{$int_link} = 1;
}
}
}
if ($text eq '' || $text =~ m/^<i>Empty Page<\/i>/)
{
chomp $tail;
my ($head, $tail) = split /\/i>/ , $text;
if ($tail =~ m/^\s*$/s) {
push @empties, $page;
}
}
}
foreach $page ( keys %links )
{
if ($page ne $mainpage && (${$links{$page}{'refs'}} == 0))
{
push @orphans, $page;
}
}
foreach $link (keys %alllinks )
{
if (! exists($pages{$link}) && $link !~ /^\./ && $link !~ /^\//)
{
$badlinks{$link} = 1;
}
}
foreach $empty ( @empties )
{
print ("empty: '$empty'\n");
}
foreach $nointernals ( @nointernals )
{
print ("nointernals: '$nointernals'\n");
}
foreach $terminal ( @terminals )
{
print ("terminal: '$terminal'\n");
}
foreach $orphan ( @orphans )
{
print ("orphan: '$orphan'\n");
}
foreach $link ( keys %badlinks )
{
print ("badlink: '$link'\n");
}
foreach $page ( sort keys %links )
{
my @links = @{$links{$page}{'links'}};
if (@links != ())
{
if ($page eq $mainpage)
{
print "links: *** '$page' *** -> ", join (", ", @links), "\n";
}
else
{
print "links: '$page' -> ", join (", ", @links), "\n";
}
}
}
|
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # ZINCDIR = $(SRCDIR)/../zlib-1.2.7 ZLIBDIR = $(SRCDIR)/../zlib-1.2.7 #### The directories where the OpenSSL include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "openssl-1.x" sub-directory of the # Fossil source code directory and the target OpenSSL source directory. # OPENSSLINCDIR = $(SRCDIR)/../openssl-1.0.1a/include OPENSSLLIBDIR = $(SRCDIR)/../openssl-1.0.1a #### Either the directory where the Tcl library is installed or the Tcl # source code directory resides (depending on the value of the macro # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, # this directory must have "include" and "lib" sub-directories. If # this points to the Tcl source code directory, this directory must # have "generic" and "win" sub-directories. The recommended usage |
| ︙ | ︙ |
Changes to win/Makefile.mingw.mistachkin.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # | | | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | FOSSIL_TCL_SOURCE = 1 #### The directories where the zlib include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "zlib-1.x.y" sub-directory of the # Fossil source code directory and the target zlib source directory. # ZINCDIR = $(SRCDIR)/../zlib-1.2.7 ZLIBDIR = $(SRCDIR)/../zlib-1.2.7 #### The directories where the OpenSSL include and library files are located. # The recommended usage here is to use the Sysinternals junction tool # to create a hard link between an "openssl-1.x" sub-directory of the # Fossil source code directory and the target OpenSSL source directory. # OPENSSLINCDIR = $(SRCDIR)/../openssl-1.0.1a/include OPENSSLLIBDIR = $(SRCDIR)/../openssl-1.0.1a #### Either the directory where the Tcl library is installed or the Tcl # source code directory resides (depending on the value of the macro # FOSSIL_TCL_SOURCE). If this points to the Tcl install directory, # this directory must have "include" and "lib" sub-directories. If # this points to the Tcl source code directory, this directory must # have "generic" and "win" sub-directories. The recommended usage |
| ︙ | ︙ |
Changes to www/tech_overview.wiki.
| ︙ | ︙ | |||
289 290 291 292 293 294 295 | to have multiple working checkouts. Each working checkout has a single database in its root directory that records the state of that checkout. The checkout database is named "_FOSSIL_" by default, but can be renamed to ".fslckout" if desired. (Future versions of Fossil might make ".fslckout" the default name.) The checkout database records information such as the following: | | | 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
to have multiple working checkouts. Each working checkout has a single
database in its root directory that records the state of that checkout.
The checkout database is named "_FOSSIL_" by default, but can be renamed
to ".fslckout" if desired. (Future versions of Fossil might make
".fslckout" the default name.) The checkout database records information
such as the following:
* The name of the repository database file.
* The version that is currently checked out.
* Files that have been [/help/add | added],
[/help/rm | removed], or [/help/mv | renamed] but not
yet committed.
* The mtime and size of files as they were originally checked out,
in order to expedite checking which files have been edited.
* Other checkins that have been [/help/merge | merged] into the
|
| ︙ | ︙ |