Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Remove the db_name() function. In its place, the SQLITE_DBCONFIG_MAINDBNAME feature of SQLite is used to ensure that the three attached databases are always exactly named "repository", "configdb" and "localdb", regardless of which is opened first or the order in which they are attached. Update to the latest 3.15 alpha of SQLite which is now required for correct operation, since SQLITE_DBCONFIG_MAINDBNAME is required. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
06aec61111d5e2f77df755ee8a244ab2 |
| User & Date: | drh 2016-08-22 20:12:50.798 |
Context
|
2016-08-22
| ||
| 21:10 | Create a valid rcvfrom entry when adding unversioned content from the command-line. check-in: 7deeb51511 user: drh tags: trunk | |
| 20:12 | Remove the db_name() function. In its place, the SQLITE_DBCONFIG_MAINDBNAME feature of SQLite is used to ensure that the three attached databases are always exactly named "repository", "configdb" and "localdb", regardless of which is opened first or the order in which they are attached. Update to the latest 3.15 alpha of SQLite which is now required for correct operation, since SQLITE_DBCONFIG_MAINDBNAME is required. check-in: 06aec61111 user: drh tags: trunk | |
| 15:20 | Fill in SQL parameters in report formats using HTTP query parameter values. check-in: 0ef09dc9cd user: drh tags: trunk | |
| 02:22 | Slightly improve clarity of the db_database_slot() function. Closed-Leaf check-in: a12d712203 user: mistachkin tags: omit-db_name | |
Changes
Changes to src/add.c.
| ︙ | ︙ | |||
383 384 385 386 387 388 389 |
**
** The temporary table "fremove" is dropped after being processed.
*/
static void process_files_to_remove(
int dryRunFlag /* Zero to actually operate on the file-system. */
){
Stmt remove;
| | | 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
**
** The temporary table "fremove" is dropped after being processed.
*/
static void process_files_to_remove(
int dryRunFlag /* Zero to actually operate on the file-system. */
){
Stmt remove;
if( db_table_exists("temp", "fremove") ){
db_prepare(&remove, "SELECT x FROM fremove ORDER BY x;");
while( db_step(&remove)==SQLITE_ROW ){
const char *zOldName = db_column_text(&remove, 0);
if( !dryRunFlag ){
file_delete(zOldName);
}
fossil_print("DELETED_FILE %s\n", zOldName);
|
| ︙ | ︙ | |||
548 549 550 551 552 553 554 |
#else
caseSensitive = 1; /* Unix */
#endif
caseSensitive = db_get_boolean("case-sensitive",caseSensitive);
}
if( !caseSensitive && g.localOpen ){
db_multi_exec(
| | | < | 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 |
#else
caseSensitive = 1; /* Unix */
#endif
caseSensitive = db_get_boolean("case-sensitive",caseSensitive);
}
if( !caseSensitive && g.localOpen ){
db_multi_exec(
"CREATE INDEX IF NOT EXISTS localdb.vfile_nocase"
" ON vfile(pathname COLLATE nocase)"
);
}
}
return caseSensitive;
}
/*
|
| ︙ | ︙ | |||
777 778 779 780 781 782 783 |
**
** The temporary table "fmove" is dropped after being processed.
*/
static void process_files_to_move(
int dryRunFlag /* Zero to actually operate on the file-system. */
){
Stmt move;
| | | 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 |
**
** The temporary table "fmove" is dropped after being processed.
*/
static void process_files_to_move(
int dryRunFlag /* Zero to actually operate on the file-system. */
){
Stmt move;
if( db_table_exists("temp", "fmove") ){
db_prepare(&move, "SELECT x, y FROM fmove ORDER BY x;");
while( db_step(&move)==SQLITE_ROW ){
const char *zOldName = db_column_text(&move, 0);
const char *zNewName = db_column_text(&move, 1);
if( !dryRunFlag ){
int isOldDir = file_isdir(zOldName);
if( isOldDir==1 ){
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
2227 2228 2229 2230 2231 2232 2233 |
}
/* Clear the undo/redo stack */
undo_reset();
/* Commit */
db_multi_exec("DELETE FROM vvar WHERE name='ci-comment'");
| | | | 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 |
}
/* Clear the undo/redo stack */
undo_reset();
/* Commit */
db_multi_exec("DELETE FROM vvar WHERE name='ci-comment'");
db_multi_exec("PRAGMA repository.application_id=252006673;");
db_multi_exec("PRAGMA localdb.application_id=252006674;");
if( dryRunFlag ){
db_end_transaction(1);
exit(1);
}
db_end_transaction(0);
if( !g.markPrivate ){
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
304 305 306 307 308 309 310 |
verify_all_options();
if( !forceFlag && unsaved_changes(0) ){
fossil_fatal("there are unsaved changes in the current checkout");
}
if( !forceFlag
&& db_table_exists("localdb","stash")
| | | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
verify_all_options();
if( !forceFlag && unsaved_changes(0) ){
fossil_fatal("there are unsaved changes in the current checkout");
}
if( !forceFlag
&& db_table_exists("localdb","stash")
&& db_exists("SELECT 1 FROM localdb.stash")
){
fossil_fatal("closing the checkout will delete your stash");
}
if( db_is_writeable("repository") ){
char *zUnset = mprintf("ckout:%q", g.zLocalRoot);
db_unset(zUnset, 1);
fossil_free(zUnset);
|
| ︙ | ︙ |
Changes to src/codecheck1.c.
| ︙ | ︙ | |||
247 248 249 250 251 252 253 |
/*
** A list of functions that return strings that are safe to insert into
** SQL using %s.
*/
static const char *azSafeFunc[] = {
"filename_collation",
| < | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
/*
** A list of functions that return strings that are safe to insert into
** SQL using %s.
*/
static const char *azSafeFunc[] = {
"filename_collation",
"leaf_is_closed_sql",
"timeline_query_for_www",
"timeline_query_for_tty",
"blob_sql_text",
"glob_expr",
"fossil_all_reserved_names",
"configure_inop_rhs",
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
959 960 961 962 963 964 965 966 967 968 969 970 971 |
void db_attach(const char *zDbName, const char *zLabel){
Blob key;
db_encryption_key(zDbName, &key);
db_multi_exec("ATTACH DATABASE %Q AS %Q KEY %Q",
zDbName, zLabel, blob_str(&key));
blob_reset(&key);
}
/*
** zDbName is the name of a database file. If no other database
** file is open, then open this one. If another database file is
** already open, then attach zDbName using the name zLabel.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < | < < < | > | < < | < > | | 959 960 961 962 963 964 965 966 967 968 969 970 971 972 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 998 999 1000 1001 1002 1003 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 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 |
void db_attach(const char *zDbName, const char *zLabel){
Blob key;
db_encryption_key(zDbName, &key);
db_multi_exec("ATTACH DATABASE %Q AS %Q KEY %Q",
zDbName, zLabel, blob_str(&key));
blob_reset(&key);
}
/*
** Change the schema name of the "main" database to zLabel.
** zLabel must be a static string that is unchanged for the life of
** the database connection.
**
** After calling this routine, db_database_slot(zLabel) should
** return 0.
*/
void db_set_main_schemaname(sqlite3 *db, const char *zLabel){
if( sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, zLabel) ){
fossil_fatal("Fossil requires a version of SQLite that supports the "
"SQLITE_DBCONFIG_MAINDBNAME interface.");
}
}
/*
** Return the slot number for database zLabel. The first database
** opened is slot 0. The "temp" database is slot 1. Attached databases
** are slots 2 and higher.
**
** Return -1 if zLabel does not match any open database.
*/
int db_database_slot(const char *zLabel){
int iSlot = -1;
Stmt q;
if( g.db==0 ) return iSlot;
db_prepare(&q, "PRAGMA database_list");
while( db_step(&q)==SQLITE_ROW ){
if( fossil_strcmp(db_column_text(&q,1),zLabel)==0 ){
iSlot = db_column_int(&q, 0);
break;
}
}
db_finalize(&q);
return iSlot;
}
/*
** zDbName is the name of a database file. If no other database
** file is open, then open this one. If another database file is
** already open, then attach zDbName using the name zLabel.
*/
void db_open_or_attach(const char *zDbName, const char *zLabel){
if( !g.db ){
g.db = db_open(zDbName);
db_set_main_schemaname(g.db, zLabel);
}else{
db_attach(zDbName, zLabel);
}
}
/*
** Close the per-user database file in ~/.fossil
*/
void db_close_config(){
int iSlot = db_database_slot("configdb");
if( iSlot>0 ){
db_detach("configdb");
g.zConfigDbName = 0;
}else if( g.dbConfig ){
sqlite3_wal_checkpoint(g.dbConfig, 0);
sqlite3_close(g.dbConfig);
g.dbConfig = 0;
g.zConfigDbName = 0;
}else if( g.db && 0==iSlot ){
sqlite3_wal_checkpoint(g.db, 0);
sqlite3_close(g.db);
g.db = 0;
g.zConfigDbName = 0;
}
}
/*
** Open the user database in "~/.fossil". Create the database anew if
** it does not already exist.
**
** If the useAttach flag is 0 (the usual case) then the user database is
** opened on a separate database connection g.dbConfig. This prevents
** the ~/.fossil database from becoming locked on long check-in or sync
** operations which hold an exclusive transaction. In a few cases, though,
** it is convenient for the ~/.fossil to be attached to the main database
** connection so that we can join between the various databases. In that
** case, invoke this routine with useAttach as 1.
*/
int db_open_config(int useAttach, int isOptional){
char *zDbName;
char *zHome;
if( g.zConfigDbName ){
int alreadyAttached = db_database_slot("configdb")>0;
if( useAttach==alreadyAttached ) return 1; /* Already open. */
db_close_config();
}
zHome = fossil_getenv("FOSSIL_HOME");
#if defined(_WIN32) || defined(__CYGWIN__)
if( zHome==0 ){
zHome = fossil_getenv("LOCALAPPDATA");
if( zHome==0 ){
|
| ︙ | ︙ | |||
1075 1076 1077 1078 1079 1080 1081 |
db_init_database(zDbName, zConfigSchema, (char*)0);
}
if( file_access(zDbName, W_OK) ){
if( isOptional ) return 0;
fossil_fatal("configuration file %s must be writeable", zDbName);
}
if( useAttach ){
| | < < | | < | | < | | | | | | | 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 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 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 |
db_init_database(zDbName, zConfigSchema, (char*)0);
}
if( file_access(zDbName, W_OK) ){
if( isOptional ) return 0;
fossil_fatal("configuration file %s must be writeable", zDbName);
}
if( useAttach ){
db_open_or_attach(zDbName, "configdb");
g.dbConfig = 0;
}else{
g.dbConfig = db_open(zDbName);
db_set_main_schemaname(g.dbConfig, "configdb");
}
g.zConfigDbName = zDbName;
return 1;
}
/*
** Return TRUE if zTable exists.
*/
int db_table_exists(
const char *zDb, /* One of: NULL, "configdb", "localdb", "repository" */
const char *zTable /* Name of table */
){
return sqlite3_table_column_metadata(g.db, zDb, zTable, 0,
0, 0, 0, 0, 0)==SQLITE_OK;
}
/*
** Return TRUE if zTable exists and contains column zColumn.
** Return FALSE if zTable does not exist or if zTable exists
** but lacks zColumn.
*/
int db_table_has_column(
const char *zDb, /* One of: NULL, "config", "localdb", "repository" */
const char *zTable, /* Name of table */
const char *zColumn /* Name of column in table */
){
return sqlite3_table_column_metadata(g.db, zDb, zTable, zColumn,
0, 0, 0, 0, 0)==SQLITE_OK;
}
/*
** Returns TRUE if zTable exists in the local database but lacks column
** zColumn
*/
static int db_local_table_exists_but_lacks_column(
const char *zTable,
const char *zColumn
){
return db_table_exists("localdb", zTable)
&& !db_table_has_column("localdb", zTable, zColumn);
}
/*
** If zDbName is a valid local database file, open it and return
** true. If it is not a valid local database file, return 0.
*/
static int isValidLocalDb(const char *zDbName){
i64 lsize;
char *zVFileDef;
if( file_access(zDbName, F_OK) ) return 0;
lsize = file_size(zDbName);
if( lsize%1024!=0 || lsize<4096 ) return 0;
db_open_or_attach(zDbName, "localdb");
zVFileDef = db_text(0, "SELECT sql FROM localdb.sqlite_master"
" WHERE name=='vfile'");
if( zVFileDef==0 ) return 0;
/* If the "isexe" column is missing from the vfile table, then
** add it now. This code added on 2010-03-06. After all users have
** upgraded, this code can be safely deleted.
*/
if( sqlite3_strglob("* isexe *", zVFileDef)!=0 ){
|
| ︙ | ︙ | |||
1288 1289 1290 1291 1292 1293 1294 |
#ifdef FOSSIL_ENABLE_JSON
g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
#endif
fossil_panic("not a valid repository: %s", zDbName);
}
}
g.zRepositoryName = mprintf("%s", zDbName);
| | | | | < | 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 |
#ifdef FOSSIL_ENABLE_JSON
g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
#endif
fossil_panic("not a valid repository: %s", zDbName);
}
}
g.zRepositoryName = mprintf("%s", zDbName);
db_open_or_attach(g.zRepositoryName, "repository");
g.repositoryOpen = 1;
/* Cache "allow-symlinks" option, because we'll need it on every stat call */
g.allowSymlinks = db_get_boolean("allow-symlinks",
db_allow_symlinks_by_default());
g.zAuxSchema = db_get("aux-schema","");
/* Verify that the PLINK table has a new column added by the
** 2014-11-28 schema change. Create it if necessary. This code
** can be removed in the future, once all users have upgraded to the
** 2014-11-28 or later schema.
*/
if( !db_table_has_column("repository","plink","baseid") ){
db_multi_exec(
"ALTER TABLE repository.plink ADD COLUMN baseid;"
);
}
/* Verify that the MLINK table has the newer columns added by the
** 2015-01-24 schema change. Create them if necessary. This code
** can be removed in the future, once all users have upgraded to the
** 2015-01-24 or later schema.
*/
if( !db_table_has_column("repository","mlink","isaux") ){
db_begin_transaction();
db_multi_exec(
"ALTER TABLE repository.mlink ADD COLUMN pmid INTEGER DEFAULT 0;"
"ALTER TABLE repository.mlink ADD COLUMN isaux BOOLEAN DEFAULT 0;"
);
db_end_transaction(0);
}
}
/*
** Flags for the db_find_and_open_repository() function.
|
| ︙ | ︙ | |||
1372 1373 1374 1375 1376 1377 1378 |
fossil_fatal("use --repository or -R to specify the repository database");
}else{
fossil_fatal("specify the repository name as a command-line argument");
}
}
}
| < < < < < < < < < < < < | | 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 |
fossil_fatal("use --repository or -R to specify the repository database");
}else{
fossil_fatal("specify the repository name as a command-line argument");
}
}
}
/*
** Return TRUE if the schema is out-of-date
*/
int db_schema_is_outofdate(void){
return strcmp(g.zAuxSchema,AUX_SCHEMA_MIN)<0
|| strcmp(g.zAuxSchema,AUX_SCHEMA_MAX)>0;
}
/*
** Return true if the database is writeable
*/
int db_is_writeable(const char *zName){
return g.db!=0 && !sqlite3_db_readonly(g.db, zName);
}
/*
** Verify that the repository schema is correct. If it is not correct,
** issue a fatal error and die.
*/
void db_verify_schema(void){
|
| ︙ | ︙ | |||
1441 1442 1443 1444 1445 1446 1447 |
if( file_access(zRepo, F_OK) ){
fossil_fatal("no such file: %s", zRepo);
}
if( db_open_local(zRepo)==0 ){
fossil_fatal("not in a local checkout");
return;
}
| | | 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 |
if( file_access(zRepo, F_OK) ){
fossil_fatal("no such file: %s", zRepo);
}
if( db_open_local(zRepo)==0 ){
fossil_fatal("not in a local checkout");
return;
}
db_open_or_attach(zRepo, "test_repo");
db_lset("repository", blob_str(&repo));
db_record_repository_filename(blob_str(&repo));
db_close(1);
}
/*
|
| ︙ | ︙ | |||
1501 1502 1503 1504 1505 1506 1507 |
while( db.pAllStmt ){
db_finalize(db.pAllStmt);
}
db_end_transaction(1);
pStmt = 0;
db_close_config();
| | | | | | | < < < | 1512 1513 1514 1515 1516 1517 1518 1519 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 |
while( db.pAllStmt ){
db_finalize(db.pAllStmt);
}
db_end_transaction(1);
pStmt = 0;
db_close_config();
/* If the localdb has a lot of unused free space,
** then VACUUM it as we shut down.
*/
if( db_database_slot("localdb")>=0 ){
int nFree = db_int(0, "PRAGMA localdb.freelist_count");
int nTotal = db_int(0, "PRAGMA localdb.page_count");
if( nFree>nTotal/4 ){
db_multi_exec("VACUUM localdb;");
}
}
if( g.db ){
int rc;
sqlite3_wal_checkpoint(g.db, 0);
rc = sqlite3_close(g.db);
if( rc==SQLITE_BUSY && reportErrors ){
while( (pStmt = sqlite3_next_stmt(g.db, pStmt))!=0 ){
fossil_warning("unfinalized SQL statement: [%s]", sqlite3_sql(pStmt));
}
}
g.db = 0;
}
g.repositoryOpen = 0;
g.localOpen = 0;
assert( g.dbConfig==0 );
assert( g.zConfigDbName==0 );
}
/*
** Create a new empty repository database with the given name.
**
** Only the schema is initialized. The required VAR tables entries
|
| ︙ | ︙ | |||
2006 2007 2008 2009 2010 2011 2012 |
** same constraint also holds true when restoring the previously swapped
** database connection; otherwise, it means that no swap was performed
** because the main database connection was already pointing to the config
** database.
*/
if( g.dbConfig ){
sqlite3 *dbTemp = g.db;
| < < < | 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 |
** same constraint also holds true when restoring the previously swapped
** database connection; otherwise, it means that no swap was performed
** because the main database connection was already pointing to the config
** database.
*/
if( g.dbConfig ){
sqlite3 *dbTemp = g.db;
g.db = g.dbConfig;
g.dbConfig = dbTemp;
}
}
/*
** Try to read a versioned setting string from .fossil-settings/<name>.
**
** Return the text of the string if it is found. Return NULL if not
|
| ︙ | ︙ | |||
3017 3018 3019 3020 3021 3022 3023 |
*/
void test_without_rowid(void){
int i, j;
Stmt q;
Blob allSql;
int dryRun = find_option("dry-run", "n", 0)!=0;
for(i=2; i<g.argc; i++){
| | | 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 |
*/
void test_without_rowid(void){
int i, j;
Stmt q;
Blob allSql;
int dryRun = find_option("dry-run", "n", 0)!=0;
for(i=2; i<g.argc; i++){
db_open_or_attach(g.argv[i], "main");
blob_init(&allSql, "BEGIN;\n", -1);
db_prepare(&q,
"SELECT name, sql FROM main.sqlite_master "
" WHERE type='table' AND sql NOT LIKE '%%WITHOUT ROWID%%'"
" AND name IN ('global_config','shun','concealed','config',"
" 'plink','tagxref','backlink','vcache');"
);
|
| ︙ | ︙ | |||
3072 3073 3074 3075 3076 3077 3078 |
** Make sure the adminlog table exists. Create it if it does not
*/
void create_admin_log_table(void){
static int once = 0;
if( once ) return;
once = 1;
db_multi_exec(
| | | | 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 |
** Make sure the adminlog table exists. Create it if it does not
*/
void create_admin_log_table(void){
static int once = 0;
if( once ) return;
once = 1;
db_multi_exec(
"CREATE TABLE IF NOT EXISTS repository.admin_log(\n"
" id INTEGER PRIMARY KEY,\n"
" time INTEGER, -- Seconds since 1970\n"
" page TEXT, -- path of page\n"
" who TEXT, -- User who made the change\n "
" what TEXT -- What changed\n"
")"
);
}
/*
** Write a message into the admin_event table, if admin logging is
** enabled via the admin-log configuration option.
*/
|
| ︙ | ︙ |
Changes to src/file.c.
| ︙ | ︙ | |||
519 520 521 522 523 524 525 |
void test_set_mtime(void){
const char *zFile;
char *zDate;
i64 iMTime;
if( g.argc!=4 ){
usage("FILENAME DATE/TIME");
}
| | | 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 |
void test_set_mtime(void){
const char *zFile;
char *zDate;
i64 iMTime;
if( g.argc!=4 ){
usage("FILENAME DATE/TIME");
}
db_open_or_attach(":memory:", "mem");
iMTime = db_int64(0, "SELECT strftime('%%s',%Q)", g.argv[3]);
zFile = g.argv[2];
file_set_mtime(zFile, iMTime);
iMTime = file_wd_mtime(zFile);
zDate = db_text(0, "SELECT datetime(%lld, 'unixepoch')", iMTime);
fossil_print("Set mtime of \"%s\" to %s (%lld)\n", zFile, zDate, iMTime);
}
|
| ︙ | ︙ |
Changes to src/json.c.
| ︙ | ︙ | |||
1257 1258 1259 1260 1261 1262 1263 | #define INT(OBJ,K) cson_object_set(o, #K, json_new_int(OBJ.K)) #define CSTR(OBJ,K) cson_object_set(o, #K, OBJ.K ? json_new_string(OBJ.K) : cson_value_null()) #define VAL(K,V) cson_object_set(o, #K, (V) ? (V) : cson_value_null()) VAL(capabilities, json_cap_value()); INT(g, argc); INT(g, isConst); | < | 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 | #define INT(OBJ,K) cson_object_set(o, #K, json_new_int(OBJ.K)) #define CSTR(OBJ,K) cson_object_set(o, #K, OBJ.K ? json_new_string(OBJ.K) : cson_value_null()) #define VAL(K,V) cson_object_set(o, #K, (V) ? (V) : cson_value_null()) VAL(capabilities, json_cap_value()); INT(g, argc); INT(g, isConst); CSTR(g, zConfigDbName); INT(g, repositoryOpen); INT(g, localOpen); INT(g, minPrefix); INT(g, fSqlTrace); INT(g, fSqlStats); INT(g, fSqlPrint); |
| ︙ | ︙ | |||
1294 1295 1296 1297 1298 1299 1300 | INT(g, rcvid); INT(g, okCsrf); INT(g, thTrace); INT(g, isHome); INT(g, nAux); INT(g, allowSymlinks); | < < | 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 | INT(g, rcvid); INT(g, okCsrf); INT(g, thTrace); INT(g, isHome); INT(g, nAux); INT(g, allowSymlinks); CSTR(g, zOpenRevision); CSTR(g, zLocalRoot); CSTR(g, zPath); CSTR(g, zExtra); CSTR(g, zBaseURL); CSTR(g, zTop); CSTR(g, zContentType); |
| ︙ | ︙ | |||
1903 1904 1905 1906 1907 1908 1909 |
** Implementation of the /json/stat page/command.
**
*/
cson_value * json_page_stat(){
i64 t, fsize;
int n, m;
int full;
| < | 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 |
** Implementation of the /json/stat page/command.
**
*/
cson_value * json_page_stat(){
i64 t, fsize;
int n, m;
int full;
enum { BufLen = 1000 };
char zBuf[BufLen];
cson_value * jv = NULL;
cson_object * jo = NULL;
cson_value * jv2 = NULL;
cson_object * jo2 = NULL;
char * zTmp = NULL;
|
| ︙ | ︙ | |||
1987 1988 1989 1990 1991 1992 1993 |
jv2 = cson_value_new_object();
jo2 = cson_value_get_object(jv2);
cson_object_set(jo, "sqlite", jv2);
sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
SETBUF(jo2, "version");
| < | | | | | | 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 |
jv2 = cson_value_new_object();
jo2 = cson_value_get_object(jv2);
cson_object_set(jo, "sqlite", jv2);
sqlite3_snprintf(BufLen, zBuf, "%.19s [%.10s] (%s)",
sqlite3_sourceid(), &sqlite3_sourceid()[20], sqlite3_libversion());
SETBUF(jo2, "version");
cson_object_set(jo2, "pageCount", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA repository.page_count")));
cson_object_set(jo2, "pageSize", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA repository.page_size")));
cson_object_set(jo2, "freeList", cson_value_new_integer((cson_int_t)db_int(0, "PRAGMA repository.freelist_count")));
sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA repository.encoding"));
SETBUF(jo2, "encoding");
sqlite3_snprintf(BufLen, zBuf, "%s", db_text(0, "PRAGMA repository.journal_mode"));
cson_object_set(jo2, "journalMode", *zBuf ? cson_value_new_string(zBuf, strlen(zBuf)) : cson_value_null());
return jv;
#undef SETBUF
}
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
172 173 174 175 176 177 178 |
}
/*
** Make sure the accesslog table exists. Create it if it does not
*/
void create_accesslog_table(void){
db_multi_exec(
| | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
}
/*
** Make sure the accesslog table exists. Create it if it does not
*/
void create_accesslog_table(void){
db_multi_exec(
"CREATE TABLE IF NOT EXISTS repository.accesslog("
" uname TEXT,"
" ipaddr TEXT,"
" success BOOLEAN,"
" mtime TIMESTAMP"
");"
);
}
/*
** Make a record of a login attempt, if login record keeping is enabled.
*/
static void record_login_attempt(
|
| ︙ | ︙ | |||
1564 1565 1566 1567 1568 1569 1570 | char *zSelfRepo; /* Name of our repository */ char *zSelfLabel; /* Project-name for our repository */ char *zSelfProjCode; /* Our project-code */ char *zSql; /* SQL to run on all peers */ const char *zSelf; /* The ATTACH name of our repository */ *pzErrMsg = 0; /* Default to no errors */ | | | 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 | char *zSelfRepo; /* Name of our repository */ char *zSelfLabel; /* Project-name for our repository */ char *zSelfProjCode; /* Our project-code */ char *zSql; /* SQL to run on all peers */ const char *zSelf; /* The ATTACH name of our repository */ *pzErrMsg = 0; /* Default to no errors */ zSelf = "repository"; /* Get the full pathname of the other repository */ file_canonical_name(zRepo, &fullName, 0); zRepo = fossil_strdup(blob_str(&fullName)); blob_reset(&fullName); /* Get the full pathname for our repository. Also the project code |
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
126 127 128 129 130 131 132 | char *nameOfExe; /* Full path of executable. */ const char *zErrlog; /* Log errors to this file, if not NULL */ int isConst; /* True if the output is unchanging & cacheable */ const char *zVfsName; /* The VFS to use for database connections */ sqlite3 *db; /* The connection to the databases */ sqlite3 *dbConfig; /* Separate connection for global_config table */ char *zAuxSchema; /* Main repository aux-schema */ | < | | < < | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | char *nameOfExe; /* Full path of executable. */ const char *zErrlog; /* Log errors to this file, if not NULL */ int isConst; /* True if the output is unchanging & cacheable */ const char *zVfsName; /* The VFS to use for database connections */ sqlite3 *db; /* The connection to the databases */ sqlite3 *dbConfig; /* Separate connection for global_config table */ char *zAuxSchema; /* Main repository aux-schema */ int dbIgnoreErrors; /* Ignore database errors if true */ const char *zConfigDbName;/* Path of the config database. NULL if not open */ sqlite3_int64 now; /* Seconds since 1970 */ int repositoryOpen; /* True if the main repository database is open */ char *zRepositoryOption; /* Most recent cached repository option value */ char *zRepositoryName; /* Name of the repository database file */ char *zLocalDbName; /* Name of the local database file */ char *zOpenRevision; /* Check-in version to use during database open */ int localOpen; /* True if the local database is open */ char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ |
| ︙ | ︙ |
Changes to src/moderate.c.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 |
/*
** Create a table to represent pending moderation requests, if the
** table does not already exist.
*/
void moderation_table_create(void){
db_multi_exec(
| | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/*
** Create a table to represent pending moderation requests, if the
** table does not already exist.
*/
void moderation_table_create(void){
db_multi_exec(
"CREATE TABLE IF NOT EXISTS repository.modreq(\n"
" objid INTEGER PRIMARY KEY,\n" /* Record pending approval */
" attachRid INT,\n" /* Object attached */
" tktid TEXT\n" /* Associated ticket id */
");\n"
);
}
/*
** Return TRUE if the modreq table exists
*/
int moderation_table_exists(void){
|
| ︙ | ︙ |
Changes to src/purge.c.
| ︙ | ︙ | |||
140 141 142 143 144 145 146 |
}
db_finalize(&q);
/* Construct the graveyard and copy the artifacts to be purged into the
** graveyard */
if( purgeFlags & PURGE_MOVETO_GRAVEYARD ){
db_multi_exec(zPurgeInit /*works-like:"%w%w"*/,
| | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
}
db_finalize(&q);
/* Construct the graveyard and copy the artifacts to be purged into the
** graveyard */
if( purgeFlags & PURGE_MOVETO_GRAVEYARD ){
db_multi_exec(zPurgeInit /*works-like:"%w%w"*/,
"repository", "repository");
db_multi_exec(
"INSERT INTO purgeevent(ctime,pnotes) VALUES(now(),%Q)", zNote
);
peid = db_last_insert_rowid();
db_prepare(&q, "SELECT rid FROM delta WHERE rid IN \"%w\""
" AND srcid NOT IN \"%w\"", zTab, zTab);
while( db_step(&q)==SQLITE_ROW ){
|
| ︙ | ︙ |
Changes to src/search.c.
| ︙ | ︙ | |||
1341 1342 1343 1344 1345 1346 1347 | blob_reset(&out); } /* The schema for the full-text index */ static const char zFtsSchema[] = @ -- One entry for each possible search result | | | | | | | | | < | < < | | 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 |
blob_reset(&out);
}
/* The schema for the full-text index
*/
static const char zFtsSchema[] =
@ -- One entry for each possible search result
@ CREATE TABLE IF NOT EXISTS repository.ftsdocs(
@ rowid INTEGER PRIMARY KEY, -- Maps to the ftsidx.docid
@ type CHAR(1), -- Type of document
@ rid INTEGER, -- BLOB.RID or TAG.TAGID for the document
@ name TEXT, -- Additional document description
@ idxed BOOLEAN, -- True if currently in the index
@ label TEXT, -- Label to print on search results
@ url TEXT, -- URL to access this document
@ mtime DATE, -- Date when document created
@ bx TEXT, -- Temporary "body" content cache
@ UNIQUE(type,rid)
@ );
@ CREATE INDEX repository.ftsdocIdxed ON ftsdocs(type,rid,name) WHERE idxed==0;
@ CREATE INDEX repository.ftsdocName ON ftsdocs(name) WHERE type='w';
@ CREATE VIEW IF NOT EXISTS repository.ftscontent AS
@ SELECT rowid, type, rid, name, idxed, label, url, mtime,
@ title(type,rid,name) AS 'title', body(type,rid,name) AS 'body'
@ FROM ftsdocs;
@ CREATE VIRTUAL TABLE IF NOT EXISTS repository.ftsidx
@ USING fts4(content="ftscontent", title, body%s);
;
static const char zFtsDrop[] =
@ DROP TABLE IF EXISTS repository.ftsidx;
@ DROP VIEW IF EXISTS repository.ftscontent;
@ DROP TABLE IF EXISTS repository.ftsdocs;
;
/*
** Create or drop the tables associated with a full-text index.
*/
static int searchIdxExists = -1;
void search_create_index(void){
int useStemmer = db_get_boolean("search-stemmer",0);
const char *zExtra = useStemmer ? ",tokenize=porter" : "";
search_sql_setup(g.db);
db_multi_exec(zFtsSchema/*works-like:"%s"*/, zExtra/*safe-for-%s*/);
searchIdxExists = 1;
}
void search_drop_index(void){
db_multi_exec(zFtsDrop/*works-like:""*/);
searchIdxExists = 0;
}
/*
** Return true if the full-text search index exists
*/
int search_index_exists(void){
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
1924 1925 1926 1927 1928 1929 1930 | @ <p><b>Caution:</b> There are no restrictions on the SQL that can be @ run by this page. You can do serious and irrepairable damage to the @ repository. Proceed with extreme caution.</p> @ @ <p>Only the first statement in the entry box will be run. @ Any subsequent statements will be silently ignored.</p> @ | | | | | < | | < | 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 |
@ <p><b>Caution:</b> There are no restrictions on the SQL that can be
@ run by this page. You can do serious and irrepairable damage to the
@ repository. Proceed with extreme caution.</p>
@
@ <p>Only the first statement in the entry box will be run.
@ Any subsequent statements will be silently ignored.</p>
@
@ <p>Database names:<ul><li>repository
if( g.zConfigDbName ){
@ <li>configdb
}
if( g.localOpen ){
@ <li>localdb
}
@ </ul></p>
@
@ <form method="post" action="%s(g.zTop)/admin_sql">
login_insert_csrf_secret();
@ SQL:<br />
@ <textarea name="q" rows="5" cols="80">%h(zQ)</textarea><br />
@ <input type="submit" name="go" value="Run SQL">
@ <input type="submit" name="schema" value="Show Schema">
@ <input type="submit" name="tablelist" value="List Tables">
@ </form>
if( P("schema") ){
zQ = sqlite3_mprintf(
"SELECT sql FROM repository.sqlite_master WHERE sql IS NOT NULL");
go = 1;
}else if( P("tablelist") ){
zQ = sqlite3_mprintf(
"SELECT name FROM repository.sqlite_master WHERE type='table'"
" ORDER BY name");
go = 1;
}
if( go ){
sqlite3_stmt *pStmt;
int rc;
const char *zTail;
int nCol;
|
| ︙ | ︙ |
Changes to src/sqlcmd.c.
| ︙ | ︙ | |||
136 137 138 139 140 141 142 143 144 145 146 |
** database connection to be more useful to the human operator.
*/
static int sqlcmd_autoinit(
sqlite3 *db,
const char **pzErrMsg,
const void *notUsed
){
add_content_sql_commands(db);
db_add_aux_functions(db);
re_add_sql_func(db);
search_sql_setup(db);
| > < | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
** database connection to be more useful to the human operator.
*/
static int sqlcmd_autoinit(
sqlite3 *db,
const char **pzErrMsg,
const void *notUsed
){
/* db_set_main_schemaname(db, "repository"); */
add_content_sql_commands(db);
db_add_aux_functions(db);
re_add_sql_func(db);
search_sql_setup(db);
foci_register(db);
g.repositoryOpen = 1;
g.db = db;
return SQLITE_OK;
}
/*
|
| ︙ | ︙ | |||
221 222 223 224 225 226 227 |
** This routine closes the Fossil databases and/or invalidates the global
** state variables that keep track of them.
*/
void fossil_close(int bDb, int noRepository){
if( bDb ) db_close(1);
if( noRepository ) g.zRepositoryName = 0;
g.db = 0;
| < | 221 222 223 224 225 226 227 228 229 230 |
** This routine closes the Fossil databases and/or invalidates the global
** state variables that keep track of them.
*/
void fossil_close(int bDb, int noRepository){
if( bDb ) db_close(1);
if( noRepository ) g.zRepositoryName = 0;
g.db = 0;
g.repositoryOpen = 0;
g.localOpen = 0;
}
|
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.15.0. 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 |
| ︙ | ︙ | |||
376 377 378 379 380 381 382 | ** 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()]. */ | | | | | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 | ** 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.15.0" #define SQLITE_VERSION_NUMBER 3015000 #define SQLITE_SOURCE_ID "2016-08-22 20:10:01 7839519349c7371cdb4e16a215eacd27004cbc62" /* ** 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 |
| ︙ | ︙ | |||
2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 | ** C-API or the SQL function. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. ** </dd> ** ** </dl> */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ | > > > > > > > > > > | 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 | ** C-API or the SQL function. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. ** </dd> ** ** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> ** <dd> ^This option is used to change the name of the "main" database ** schema. ^The sole argument is a pointer to a constant UTF8 string ** which will become the new schema name in place of "main". ^SQLite ** does not make a copy of the new main schema name string, so the application ** must ensure that the argument passed into this DBCONFIG option is unchanged ** until after the database connection closes. ** </dd> ** ** </dl> */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ |
| ︙ | ︙ | |||
13692 13693 13694 13695 13696 13697 13698 |
** Each database file to be accessed by the system is an instance
** of the following structure. There are normally two of these structures
** in the sqlite.aDb[] array. aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables. Additional
** databases may be attached.
*/
struct Db {
| | | 13702 13703 13704 13705 13706 13707 13708 13709 13710 13711 13712 13713 13714 13715 13716 |
** Each database file to be accessed by the system is an instance
** of the following structure. There are normally two of these structures
** in the sqlite.aDb[] array. aDb[0] is the main database file and
** aDb[1] is the database file used to hold temporary tables. Additional
** databases may be attached.
*/
struct Db {
char *zDbSName; /* Name of this database. (schema name, not filename) */
Btree *pBt; /* The B*Tree structure for this database file */
u8 safety_level; /* How aggressive at syncing data to disk */
u8 bSyncSet; /* True if "PRAGMA synchronous=N" has been run */
Schema *pSchema; /* Pointer to database schema (possibly shared) */
};
/*
|
| ︙ | ︙ | |||
16296 16297 16298 16299 16300 16301 16302 | #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); | | | | 16306 16307 16308 16309 16310 16311 16312 16313 16314 16315 16316 16317 16318 16319 16320 16321 | #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*); SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int); SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int); SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int); SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); |
| ︙ | ︙ | |||
34849 34850 34851 34852 34853 34854 34855 34856 34857 34858 34859 34860 34861 34862 |
}
}
unixLeaveMutex();
}
#endif /* if !OS_VXWORKS */
return pUnused;
}
/*
** This function is called by unixOpen() to determine the unix permissions
** to create new files with. If no error occurs, then SQLITE_OK is returned
** and a value suitable for passing as the third argument to open(2) is
** written to *pMode. If an IO error occurs, an SQLite error code is
** returned and the value of *pMode is not modified.
| > > > > > > > > > > > > > > > > > > > > > | 34859 34860 34861 34862 34863 34864 34865 34866 34867 34868 34869 34870 34871 34872 34873 34874 34875 34876 34877 34878 34879 34880 34881 34882 34883 34884 34885 34886 34887 34888 34889 34890 34891 34892 34893 |
}
}
unixLeaveMutex();
}
#endif /* if !OS_VXWORKS */
return pUnused;
}
/*
** Find the mode, uid and gid of file zFile.
*/
static int getFileMode(
const char *zFile, /* File name */
mode_t *pMode, /* OUT: Permissions of zFile */
uid_t *pUid, /* OUT: uid of zFile. */
gid_t *pGid /* OUT: gid of zFile. */
){
struct stat sStat; /* Output of stat() on database file */
int rc = SQLITE_OK;
if( 0==osStat(zFile, &sStat) ){
*pMode = sStat.st_mode & 0777;
*pUid = sStat.st_uid;
*pGid = sStat.st_gid;
}else{
rc = SQLITE_IOERR_FSTAT;
}
return rc;
}
/*
** This function is called by unixOpen() to determine the unix permissions
** to create new files with. If no error occurs, then SQLITE_OK is returned
** and a value suitable for passing as the third argument to open(2) is
** written to *pMode. If an IO error occurs, an SQLite error code is
** returned and the value of *pMode is not modified.
|
| ︙ | ︙ | |||
34885 34886 34887 34888 34889 34890 34891 |
int rc = SQLITE_OK; /* Return Code */
*pMode = 0;
*pUid = 0;
*pGid = 0;
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
char zDb[MAX_PATHNAME+1]; /* Database file path */
int nDb; /* Number of valid bytes in zDb */
| < | 34916 34917 34918 34919 34920 34921 34922 34923 34924 34925 34926 34927 34928 34929 |
int rc = SQLITE_OK; /* Return Code */
*pMode = 0;
*pUid = 0;
*pGid = 0;
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
char zDb[MAX_PATHNAME+1]; /* Database file path */
int nDb; /* Number of valid bytes in zDb */
/* zPath is a path to a WAL or journal file. The following block derives
** the path to the associated database file from zPath. This block handles
** the following naming conventions:
**
** "<path to db>-journal"
** "<path to db>-wal"
|
| ︙ | ︙ | |||
34916 34917 34918 34919 34920 34921 34922 |
if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
#endif
nDb--;
}
memcpy(zDb, zPath, nDb);
zDb[nDb] = '\0';
| | < < < < < < > > > > > > > > > | 34946 34947 34948 34949 34950 34951 34952 34953 34954 34955 34956 34957 34958 34959 34960 34961 34962 34963 34964 34965 34966 34967 34968 34969 34970 34971 |
if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
#endif
nDb--;
}
memcpy(zDb, zPath, nDb);
zDb[nDb] = '\0';
rc = getFileMode(zDb, pMode, pUid, pGid);
}else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
*pMode = 0600;
}else if( flags & SQLITE_OPEN_URI ){
/* If this is a main database file and the file was opened using a URI
** filename, check for the "modeof" parameter. If present, interpret
** its value as a filename and try to copy the mode, uid and gid from
** that file. */
const char *z = sqlite3_uri_parameter(zPath, "modeof");
if( z ){
rc = getFileMode(z, pMode, pUid, pGid);
}
}
return rc;
}
/*
** Open the file zPath.
**
|
| ︙ | ︙ | |||
75439 75440 75441 75442 75443 75444 75445 |
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
int nEntry;
sqlite3BtreeEnter(pBt);
nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
| | | 75472 75473 75474 75475 75476 75477 75478 75479 75480 75481 75482 75483 75484 75485 75486 |
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
int nEntry;
sqlite3BtreeEnter(pBt);
nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
}
}
}
#endif
return rc;
}
|
| ︙ | ︙ | |||
81470 81471 81472 81473 81474 81475 81476 |
assert( pOp->opcode==OP_InsertInt );
x.nKey = pOp->p3;
}
if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
assert( pC->isTable );
assert( pC->iDb>=0 );
| | | 81503 81504 81505 81506 81507 81508 81509 81510 81511 81512 81513 81514 81515 81516 81517 |
assert( pOp->opcode==OP_InsertInt );
x.nKey = pOp->p3;
}
if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
assert( pC->isTable );
assert( pC->iDb>=0 );
zDb = db->aDb[pC->iDb].zDbSName;
pTab = pOp->p4.pTab;
assert( HasRowid(pTab) );
op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
}else{
pTab = 0; /* Not needed. Silence a comiler warning. */
zDb = 0; /* Not needed. Silence a compiler warning. */
}
|
| ︙ | ︙ | |||
81587 81588 81589 81590 81591 81592 81593 |
** the name of the db to pass as to it. Also set local pTab to a copy
** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
** last moved with OP_Next or OP_Prev, not Seek or NotFound, set
** VdbeCursor.movetoTarget to the current rowid. */
if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
assert( pC->iDb>=0 );
assert( pOp->p4.pTab!=0 );
| | | 81620 81621 81622 81623 81624 81625 81626 81627 81628 81629 81630 81631 81632 81633 81634 |
** the name of the db to pass as to it. Also set local pTab to a copy
** of p4.pTab. Finally, if p5 is true, indicating that this cursor was
** last moved with OP_Next or OP_Prev, not Seek or NotFound, set
** VdbeCursor.movetoTarget to the current rowid. */
if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
assert( pC->iDb>=0 );
assert( pOp->p4.pTab!=0 );
zDb = db->aDb[pC->iDb].zDbSName;
pTab = pOp->p4.pTab;
if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
}
}else{
zDb = 0; /* Not needed. Silence a compiler warning. */
pTab = 0; /* Not needed. Silence a compiler warning. */
|
| ︙ | ︙ | |||
82557 82558 82559 82560 82561 82562 82563 |
/* Used to be a conditional */ {
zMaster = SCHEMA_TABLE(iDb);
initData.db = db;
initData.iDb = pOp->p1;
initData.pzErrMsg = &p->zErrMsg;
zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
| | | 82590 82591 82592 82593 82594 82595 82596 82597 82598 82599 82600 82601 82602 82603 82604 |
/* Used to be a conditional */ {
zMaster = SCHEMA_TABLE(iDb);
initData.db = db;
initData.iDb = pOp->p1;
initData.pzErrMsg = &p->zErrMsg;
zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
db->aDb[iDb].zDbSName, zMaster, pOp->p4.z);
if( zSql==0 ){
rc = SQLITE_NOMEM_BKPT;
}else{
assert( db->init.busy==0 );
db->init.busy = 1;
initData.rc = SQLITE_OK;
assert( !db->mallocFailed );
|
| ︙ | ︙ | |||
83386 83387 83388 83389 83390 83391 83392 | sqlite3VdbeChangeEncoding(pOut, encoding); if( rc ) goto abort_due_to_error; break; }; #endif /* SQLITE_OMIT_PRAGMA */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) | | | | < | | 83419 83420 83421 83422 83423 83424 83425 83426 83427 83428 83429 83430 83431 83432 83433 83434 83435 83436 83437 83438 83439 83440 |
sqlite3VdbeChangeEncoding(pOut, encoding);
if( rc ) goto abort_due_to_error;
break;
};
#endif /* SQLITE_OMIT_PRAGMA */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/* Opcode: Vacuum P1 * * * *
**
** Vacuum the entire database P1. P1 is 0 for "main", and 2 or more
** for an attached database. The "temp" database may not be vacuumed.
*/
case OP_Vacuum: {
assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1);
if( rc ) goto abort_due_to_error;
break;
}
#endif
#if !defined(SQLITE_OMIT_AUTOVACUUM)
/* Opcode: IncrVacuum P1 P2 * * *
|
| ︙ | ︙ | |||
83941 83942 83943 83944 83945 83946 83947 |
}
#ifdef SQLITE_USE_FCNTL_TRACE
zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
if( zTrace ){
int i;
for(i=0; i<db->nDb; i++){
if( DbMaskTest(p->btreeMask, i)==0 ) continue;
| | | 83973 83974 83975 83976 83977 83978 83979 83980 83981 83982 83983 83984 83985 83986 83987 |
}
#ifdef SQLITE_USE_FCNTL_TRACE
zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
if( zTrace ){
int i;
for(i=0; i<db->nDb; i++){
if( DbMaskTest(p->btreeMask, i)==0 ) continue;
sqlite3_file_control(db, db->aDb[i].zDbSName, SQLITE_FCNTL_TRACE, zTrace);
}
}
#endif /* SQLITE_USE_FCNTL_TRACE */
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
|
| ︙ | ︙ | |||
84277 84278 84279 84280 84281 84282 84283 |
pParse->zErrMsg = 0;
}
rc = SQLITE_ERROR;
sqlite3BtreeLeaveAll(db);
goto blob_open_out;
}
pBlob->pTab = pTab;
| | | 84309 84310 84311 84312 84313 84314 84315 84316 84317 84318 84319 84320 84321 84322 84323 |
pParse->zErrMsg = 0;
}
rc = SQLITE_ERROR;
sqlite3BtreeLeaveAll(db);
goto blob_open_out;
}
pBlob->pTab = pTab;
pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
/* Now search pTab for the exact column. */
for(iCol=0; iCol<pTab->nCol; iCol++) {
if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){
break;
}
}
|
| ︙ | ︙ | |||
87829 87830 87831 87832 87833 87834 87835 |
** and WRC_Continue to continue.
*/
static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
int rc;
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
| < | | | | | | | | < | | 87861 87862 87863 87864 87865 87866 87867 87868 87869 87870 87871 87872 87873 87874 87875 87876 87877 87878 87879 87880 87881 87882 87883 |
** and WRC_Continue to continue.
*/
static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){
int rc;
testcase( ExprHasProperty(pExpr, EP_TokenOnly) );
testcase( ExprHasProperty(pExpr, EP_Reduced) );
rc = pWalker->xExprCallback(pWalker, pExpr);
if( rc || ExprHasProperty(pExpr,EP_TokenOnly) ) return rc & WRC_Abort;
if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
if( pExpr->pRight && walkExpr(pWalker, pExpr->pRight) ) return WRC_Abort;
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
}else{
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
}
return WRC_Continue;
}
SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){
return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue;
}
/*
** Call sqlite3WalkExpr() for every expression in list p or until
|
| ︙ | ︙ | |||
88173 88174 88175 88176 88177 88178 88179 |
/* Silently ignore database qualifiers inside CHECK constraints and
** partial indices. Do not raise errors because that might break
** legacy and because it does not hurt anything to just ignore the
** database name. */
zDb = 0;
}else{
for(i=0; i<db->nDb; i++){
| | | | 88203 88204 88205 88206 88207 88208 88209 88210 88211 88212 88213 88214 88215 88216 88217 88218 |
/* Silently ignore database qualifiers inside CHECK constraints and
** partial indices. Do not raise errors because that might break
** legacy and because it does not hurt anything to just ignore the
** database name. */
zDb = 0;
}else{
for(i=0; i<db->nDb; i++){
assert( db->aDb[i].zDbSName );
if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){
pSchema = db->aDb[i].pSchema;
break;
}
}
}
}
|
| ︙ | ︙ | |||
94247 94248 94249 94250 94251 94252 94253 | if( NEVER(db->mallocFailed) ) goto exit_rename_table; assert( pSrc->nSrc==1 ); assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_rename_table; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); | | | 94277 94278 94279 94280 94281 94282 94283 94284 94285 94286 94287 94288 94289 94290 94291 | if( NEVER(db->mallocFailed) ) goto exit_rename_table; assert( pSrc->nSrc==1 ); assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_rename_table; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); zDb = db->aDb[iDb].zDbSName; db->flags |= SQLITE_PreferBuiltin; /* Get a NULL terminated version of the new table name. */ zName = sqlite3NameFromToken(db, pName); if( !zName ) goto exit_rename_table; /* Check that a table or index named 'zName' does not already exist |
| ︙ | ︙ | |||
94445 94446 94447 94448 94449 94450 94451 | if( pParse->nErr || db->mallocFailed ) return; assert( v!=0 ); pNew = pParse->pNewTable; assert( pNew ); assert( sqlite3BtreeHoldsAllMutexes(db) ); iDb = sqlite3SchemaToIndex(db, pNew->pSchema); | | | 94475 94476 94477 94478 94479 94480 94481 94482 94483 94484 94485 94486 94487 94488 94489 | if( pParse->nErr || db->mallocFailed ) return; assert( v!=0 ); pNew = pParse->pNewTable; assert( pNew ); assert( sqlite3BtreeHoldsAllMutexes(db) ); iDb = sqlite3SchemaToIndex(db, pNew->pSchema); zDb = db->aDb[iDb].zDbSName; zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ pCol = &pNew->aCol[pNew->nCol-1]; pDflt = pCol->pDflt; pTab = sqlite3FindTable(db, zTab, zDb); assert( pTab ); #ifndef SQLITE_OMIT_AUTHORIZATION |
| ︙ | ︙ | |||
94855 94856 94857 94858 94859 94860 94861 |
/* Create new statistic tables if they do not exist, or clear them
** if they do already exist.
*/
for(i=0; i<ArraySize(aTable); i++){
const char *zTab = aTable[i].zName;
Table *pStat;
| | | | | 94885 94886 94887 94888 94889 94890 94891 94892 94893 94894 94895 94896 94897 94898 94899 94900 94901 94902 94903 94904 94905 94906 94907 94908 94909 94910 94911 94912 94913 94914 94915 94916 94917 94918 94919 94920 94921 |
/* Create new statistic tables if they do not exist, or clear them
** if they do already exist.
*/
for(i=0; i<ArraySize(aTable); i++){
const char *zTab = aTable[i].zName;
Table *pStat;
if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
if( aTable[i].zCols ){
/* The sqlite_statN table does not exist. Create it. Note that a
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
** because the OpenWrite opcode below will be needing it. */
sqlite3NestedParse(pParse,
"CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
);
aRoot[i] = pParse->regRoot;
aCreateTbl[i] = OPFLAG_P2ISREG;
}
}else{
/* The table already exists. If zWhere is not NULL, delete all entries
** associated with the table zWhere. If zWhere is NULL, delete the
** entire contents of the table. */
aRoot[i] = pStat->tnum;
aCreateTbl[i] = 0;
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
if( zWhere ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q",
pDb->zDbSName, zTab, zWhereType, zWhere
);
}else{
/* The sqlite_stat[134] table already exists. Delete all rows. */
sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
}
}
}
|
| ︙ | ︙ | |||
95639 95640 95641 95642 95643 95644 95645 | } assert( sqlite3BtreeHoldsAllMutexes(db) ); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, | | | 95669 95670 95671 95672 95673 95674 95675 95676 95677 95678 95679 95680 95681 95682 95683 |
}
assert( sqlite3BtreeHoldsAllMutexes(db) );
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb>=0 );
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
db->aDb[iDb].zDbSName ) ){
return;
}
#endif
/* Establish a read-lock on the table at the shared-cache level.
** Open a read-only cursor on the table. Also allocate a cursor number
** to use for scanning indexes (iIdxCur). No index cursor is opened at
|
| ︙ | ︙ | |||
96029 96030 96031 96032 96033 96034 96035 |
sqlite3DbFree(db, z);
}
}
}else{
/* Form 3: Analyze the fully qualified table name */
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
if( iDb>=0 ){
| | | 96059 96060 96061 96062 96063 96064 96065 96066 96067 96068 96069 96070 96071 96072 96073 |
sqlite3DbFree(db, z);
}
}
}else{
/* Form 3: Analyze the fully qualified table name */
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName);
if( iDb>=0 ){
zDb = db->aDb[iDb].zDbSName;
z = sqlite3NameFromToken(db, pTableName);
if( z ){
if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){
analyzeTable(pParse, pIdx->pTable, pIdx);
}else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){
analyzeTable(pParse, pTab, 0);
}
|
| ︙ | ︙ | |||
96489 96490 96491 96492 96493 96494 96495 |
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
}
/* Load new statistics out of the sqlite_stat1 table */
sInfo.db = db;
| | | 96519 96520 96521 96522 96523 96524 96525 96526 96527 96528 96529 96530 96531 96532 96533 |
sqlite3DeleteIndexSamples(db, pIdx);
pIdx->aSample = 0;
#endif
}
/* Load new statistics out of the sqlite_stat1 table */
sInfo.db = db;
sInfo.zDatabase = db->aDb[iDb].zDbSName;
if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){
zSql = sqlite3MPrintf(db,
"SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
if( zSql==0 ){
rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
|
| ︙ | ︙ | |||
96632 96633 96634 96635 96636 96637 96638 |
goto attach_error;
}
if( !db->autoCommit ){
zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction");
goto attach_error;
}
for(i=0; i<db->nDb; i++){
| | | 96662 96663 96664 96665 96666 96667 96668 96669 96670 96671 96672 96673 96674 96675 96676 |
goto attach_error;
}
if( !db->autoCommit ){
zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction");
goto attach_error;
}
for(i=0; i<db->nDb; i++){
char *z = db->aDb[i].zDbSName;
assert( z && zName );
if( sqlite3StrICmp(z, zName)==0 ){
zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
goto attach_error;
}
}
|
| ︙ | ︙ | |||
96697 96698 96699 96700 96701 96702 96703 |
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
sqlite3BtreeSetPagerFlags(aNew->pBt,
PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK));
#endif
sqlite3BtreeLeave(aNew->pBt);
}
aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
| | | | 96727 96728 96729 96730 96731 96732 96733 96734 96735 96736 96737 96738 96739 96740 96741 96742 |
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
sqlite3BtreeSetPagerFlags(aNew->pBt,
PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK));
#endif
sqlite3BtreeLeave(aNew->pBt);
}
aNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
aNew->zDbSName = sqlite3DbStrDup(db, zName);
if( rc==SQLITE_OK && aNew->zDbSName==0 ){
rc = SQLITE_NOMEM_BKPT;
}
#ifdef SQLITE_HAS_CODEC
if( rc==SQLITE_OK ){
extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
|
| ︙ | ︙ | |||
96810 96811 96812 96813 96814 96815 96816 |
UNUSED_PARAMETER(NotUsed);
if( zName==0 ) zName = "";
for(i=0; i<db->nDb; i++){
pDb = &db->aDb[i];
if( pDb->pBt==0 ) continue;
| | | 96840 96841 96842 96843 96844 96845 96846 96847 96848 96849 96850 96851 96852 96853 96854 |
UNUSED_PARAMETER(NotUsed);
if( zName==0 ) zName = "";
for(i=0; i<db->nDb; i++){
pDb = &db->aDb[i];
if( pDb->pBt==0 ) continue;
if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break;
}
if( i>=db->nDb ){
sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
goto detach_error;
}
if( i<2 ){
|
| ︙ | ︙ | |||
96968 96969 96970 96971 96972 96973 96974 |
const Token *pName /* Name of the view, trigger, or index */
){
sqlite3 *db;
db = pParse->db;
assert( db->nDb>iDb );
pFix->pParse = pParse;
| | | 96998 96999 97000 97001 97002 97003 97004 97005 97006 97007 97008 97009 97010 97011 97012 |
const Token *pName /* Name of the view, trigger, or index */
){
sqlite3 *db;
db = pParse->db;
assert( db->nDb>iDb );
pFix->pParse = pParse;
pFix->zDb = db->aDb[iDb].zDbSName;
pFix->pSchema = db->aDb[iDb].pSchema;
pFix->zType = zType;
pFix->pName = pName;
pFix->bVarOnly = (iDb==1);
}
/*
|
| ︙ | ︙ | |||
97226 97227 97228 97229 97230 97231 97232 |
*/
SQLITE_PRIVATE int sqlite3AuthReadCol(
Parse *pParse, /* The parser context */
const char *zTab, /* Table name */
const char *zCol, /* Column name */
int iDb /* Index of containing database. */
){
| | | | | 97256 97257 97258 97259 97260 97261 97262 97263 97264 97265 97266 97267 97268 97269 97270 97271 97272 |
*/
SQLITE_PRIVATE int sqlite3AuthReadCol(
Parse *pParse, /* The parser context */
const char *zTab, /* Table name */
const char *zCol, /* Column name */
int iDb /* Index of containing database. */
){
sqlite3 *db = pParse->db; /* Database handle */
char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */
int rc; /* Auth callback return code */
if( db->init.busy ) return SQLITE_OK;
rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
#ifdef SQLITE_USER_AUTHENTICATION
,db->auth.zAuthUser
#endif
);
|
| ︙ | ︙ | |||
97701 97702 97703 97704 97705 97706 97707 |
** exists */
if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){
return 0;
}
#endif
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
| | | | | > | 97731 97732 97733 97734 97735 97736 97737 97738 97739 97740 97741 97742 97743 97744 97745 97746 97747 97748 97749 |
** exists */
if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){
return 0;
}
#endif
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
if( p ) break;
}
}
return p;
}
/*
** Locate the in-memory structure that describes a particular database
** table given the name of that table and (optionally) the name of the
|
| ︙ | ︙ | |||
97778 97779 97780 97781 97782 97783 97784 |
u32 flags,
struct SrcList_item *p
){
const char *zDb;
assert( p->pSchema==0 || p->zDatabase==0 );
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
| | | 97809 97810 97811 97812 97813 97814 97815 97816 97817 97818 97819 97820 97821 97822 97823 |
u32 flags,
struct SrcList_item *p
){
const char *zDb;
assert( p->pSchema==0 || p->zDatabase==0 );
if( p->pSchema ){
int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema);
zDb = pParse->db->aDb[iDb].zDbSName;
}else{
zDb = p->zDatabase;
}
return sqlite3LocateTable(pParse, flags, p->zName, zDb);
}
/*
|
| ︙ | ︙ | |||
97806 97807 97808 97809 97810 97811 97812 |
int i;
/* All mutexes are required for schema access. Make sure we hold them. */
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
assert( pSchema );
| | | 97837 97838 97839 97840 97841 97842 97843 97844 97845 97846 97847 97848 97849 97850 97851 |
int i;
/* All mutexes are required for schema access. Make sure we hold them. */
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
Schema *pSchema = db->aDb[j].pSchema;
assert( pSchema );
if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
p = sqlite3HashFind(&pSchema->idxHash, zName);
if( p ) break;
}
return p;
}
|
| ︙ | ︙ | |||
97875 97876 97877 97878 97879 97880 97881 |
** 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 ){
| | | | 97906 97907 97908 97909 97910 97911 97912 97913 97914 97915 97916 97917 97918 97919 97920 97921 |
** 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->zDbSName);
pDb->zDbSName = 0;
continue;
}
if( j<i ){
db->aDb[j] = db->aDb[i];
}
j++;
}
|
| ︙ | ︙ | |||
98096 98097 98098 98099 98100 98101 98102 |
** -1 if the named db cannot be found.
*/
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){
int i = -1; /* Database number */
if( zName ){
Db *pDb;
for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
| | | 98127 98128 98129 98130 98131 98132 98133 98134 98135 98136 98137 98138 98139 98140 98141 |
** -1 if the named db cannot be found.
*/
SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){
int i = -1; /* Database number */
if( zName ){
Db *pDb;
for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){
if( 0==sqlite3StrICmp(pDb->zDbSName, zName) ) break;
}
}
return i;
}
/*
** The token *pName contains the name of a database (either "main" or
|
| ︙ | ︙ | |||
98155 98156 98157 98158 98159 98160 98161 |
*pUnqual = pName2;
iDb = sqlite3FindDb(db, pName1);
if( iDb<0 ){
sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
return -1;
}
}else{
| | | 98186 98187 98188 98189 98190 98191 98192 98193 98194 98195 98196 98197 98198 98199 98200 |
*pUnqual = pName2;
iDb = sqlite3FindDb(db, pName1);
if( iDb<0 ){
sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
return -1;
}
}else{
assert( db->init.iDb==0 || db->init.busy || (db->flags & SQLITE_Vacuum)!=0);
iDb = db->init.iDb;
*pUnqual = pName1;
}
return iDb;
}
/*
|
| ︙ | ︙ | |||
98266 98267 98268 98269 98270 98271 98272 |
{
static const u8 aCode[] = {
SQLITE_CREATE_TABLE,
SQLITE_CREATE_TEMP_TABLE,
SQLITE_CREATE_VIEW,
SQLITE_CREATE_TEMP_VIEW
};
| | | | 98297 98298 98299 98300 98301 98302 98303 98304 98305 98306 98307 98308 98309 98310 98311 98312 98313 98314 98315 98316 98317 98318 98319 98320 98321 98322 98323 98324 98325 98326 98327 98328 98329 98330 |
{
static const u8 aCode[] = {
SQLITE_CREATE_TABLE,
SQLITE_CREATE_TEMP_TABLE,
SQLITE_CREATE_VIEW,
SQLITE_CREATE_TEMP_VIEW
};
char *zDb = db->aDb[iDb].zDbSName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
goto begin_table_error;
}
if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView],
zName, 0, zDb) ){
goto begin_table_error;
}
}
#endif
/* Make sure the new table name does not collide with an existing
** index or table name in the same database. Issue an error message if
** it does. The exception is if the statement being parsed was passed
** to an sqlite3_declare_vtab() call. In that case only the column names
** and types will be used, so there is no need to test for namespace
** collisions.
*/
if( !IN_DECLARE_VTAB ){
char *zDb = db->aDb[iDb].zDbSName;
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
goto begin_table_error;
}
pTable = sqlite3FindTable(db, zName, zDb);
if( pTable ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "table %T already exists", pName);
|
| ︙ | ︙ | |||
99378 99379 99380 99381 99382 99383 99384 |
** SQLITE_MASTER table. We just need to update that slot with all
** the information we've collected.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s "
"SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
"WHERE rowid=#%d",
| | | | | 99409 99410 99411 99412 99413 99414 99415 99416 99417 99418 99419 99420 99421 99422 99423 99424 99425 99426 99427 99428 99429 99430 99431 99432 99433 99434 99435 99436 99437 99438 99439 99440 99441 99442 99443 99444 |
** SQLITE_MASTER table. We just need to update that slot with all
** the information we've collected.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s "
"SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q "
"WHERE rowid=#%d",
db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb),
zType,
p->zName,
p->zName,
pParse->regRoot,
zStmt,
pParse->regRowid
);
sqlite3DbFree(db, zStmt);
sqlite3ChangeCookie(pParse, iDb);
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Check to see if we need to create an sqlite_sequence table for
** keeping track of autoincrement keys.
*/
if( (p->tabFlags & TF_Autoincrement)!=0 ){
Db *pDb = &db->aDb[iDb];
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( pDb->pSchema->pSeqTab==0 ){
sqlite3NestedParse(pParse,
"CREATE TABLE %Q.sqlite_sequence(name,seq)",
pDb->zDbSName
);
}
}
#endif
/* Reparse everything to update our internal data structures */
sqlite3VdbeAddParseSchemaOp(v, iDb,
|
| ︙ | ︙ | |||
99713 99714 99715 99716 99717 99718 99719 |
**
** The "#NNN" in the SQL is a special constant that means whatever value
** is in register NNN. See grammar rules associated with the TK_REGISTER
** token for additional information.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
| | | 99744 99745 99746 99747 99748 99749 99750 99751 99752 99753 99754 99755 99756 99757 99758 |
**
** The "#NNN" in the SQL is a special constant that means whatever value
** is in register NNN. See grammar rules associated with the TK_REGISTER
** token for additional information.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
pParse->db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), iTable, r1, r1);
#endif
sqlite3ReleaseTempReg(pParse, r1);
}
/*
** Write VDBE code to erase table pTab and all associated indices on disk.
** Code to update the sqlite_master tables and internal schema definitions
|
| ︙ | ︙ | |||
99789 99790 99791 99792 99793 99794 99795 |
static void sqlite3ClearStatTables(
Parse *pParse, /* The parsing context */
int iDb, /* The database number */
const char *zType, /* "idx" or "tbl" */
const char *zName /* Name of index or table */
){
int i;
| | | 99820 99821 99822 99823 99824 99825 99826 99827 99828 99829 99830 99831 99832 99833 99834 |
static void sqlite3ClearStatTables(
Parse *pParse, /* The parsing context */
int iDb, /* The database number */
const char *zType, /* "idx" or "tbl" */
const char *zName /* Name of index or table */
){
int i;
const char *zDbName = pParse->db->aDb[iDb].zDbSName;
for(i=1; i<=4; i++){
char zTab[24];
sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
if( sqlite3FindTable(pParse->db, zTab, zDbName) ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q",
zDbName, zTab, zType, zName
|
| ︙ | ︙ | |||
99842 99843 99844 99845 99846 99847 99848 |
** the table being dropped. This is done before the table is dropped
** at the btree level, in case the sqlite_sequence table needs to
** move as a result of the drop (can happen in auto-vacuum mode).
*/
if( pTab->tabFlags & TF_Autoincrement ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
| | | | 99873 99874 99875 99876 99877 99878 99879 99880 99881 99882 99883 99884 99885 99886 99887 99888 99889 99890 99891 99892 99893 99894 99895 99896 99897 99898 99899 99900 99901 |
** the table being dropped. This is done before the table is dropped
** at the btree level, in case the sqlite_sequence table needs to
** move as a result of the drop (can happen in auto-vacuum mode).
*/
if( pTab->tabFlags & TF_Autoincrement ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
pDb->zDbSName, pTab->zName
);
}
#endif
/* Drop all SQLITE_MASTER table and index entries that refer to the
** table. The program name loops through the master table and deletes
** every row that refers to a table of the same name as the one being
** dropped. Triggers are handled separately because a trigger can be
** created in the temp database that refers to a table in another
** database.
*/
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
pDb->zDbSName, SCHEMA_TABLE(iDb), pTab->zName);
if( !isView && !IsVirtual(pTab) ){
destroyTable(pParse, pTab);
}
/* Remove the table entry from SQLite's internal schema and modify
** the schema cookie.
*/
|
| ︙ | ︙ | |||
99910 99911 99912 99913 99914 99915 99916 |
if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){
goto exit_drop_table;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code;
const char *zTab = SCHEMA_TABLE(iDb);
| | | 99941 99942 99943 99944 99945 99946 99947 99948 99949 99950 99951 99952 99953 99954 99955 |
if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){
goto exit_drop_table;
}
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code;
const char *zTab = SCHEMA_TABLE(iDb);
const char *zDb = db->aDb[iDb].zDbSName;
const char *zArg2 = 0;
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){
goto exit_drop_table;
}
if( isView ){
if( !OMIT_TEMPDB && iDb==1 ){
code = SQLITE_DROP_TEMP_VIEW;
|
| ︙ | ︙ | |||
100151 100152 100153 100154 100155 100156 100157 | KeyInfo *pKey; /* KeyInfo for index */ int regRecord; /* Register holding assembled index record */ sqlite3 *db = pParse->db; /* The database connection */ int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, | | | 100182 100183 100184 100185 100186 100187 100188 100189 100190 100191 100192 100193 100194 100195 100196 |
KeyInfo *pKey; /* KeyInfo for index */
int regRecord; /* Register holding assembled index record */
sqlite3 *db = pParse->db; /* The database connection */
int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0,
db->aDb[iDb].zDbSName ) ){
return;
}
#endif
/* Require a write-lock on the table to perform this operation */
sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName);
|
| ︙ | ︙ | |||
100403 100404 100405 100406 100407 100408 100409 |
}
if( !db->init.busy ){
if( sqlite3FindTable(db, zName, 0)!=0 ){
sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
}
}
| | | 100434 100435 100436 100437 100438 100439 100440 100441 100442 100443 100444 100445 100446 100447 100448 |
}
if( !db->init.busy ){
if( sqlite3FindTable(db, zName, 0)!=0 ){
sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
goto exit_create_index;
}
}
if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
if( !ifNotExist ){
sqlite3ErrorMsg(pParse, "index %s already exists", zName);
}else{
assert( !db->init.busy );
sqlite3CodeVerifySchema(pParse, iDb);
}
goto exit_create_index;
|
| ︙ | ︙ | |||
100433 100434 100435 100436 100437 100438 100439 |
if( IN_DECLARE_VTAB ) zName[7]++;
}
/* Check for authorization to create an index.
*/
#ifndef SQLITE_OMIT_AUTHORIZATION
{
| | | 100464 100465 100466 100467 100468 100469 100470 100471 100472 100473 100474 100475 100476 100477 100478 |
if( IN_DECLARE_VTAB ) zName[7]++;
}
/* Check for authorization to create an index.
*/
#ifndef SQLITE_OMIT_AUTHORIZATION
{
const char *zDb = pDb->zDbSName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){
goto exit_create_index;
}
i = SQLITE_CREATE_INDEX;
if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX;
if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){
goto exit_create_index;
|
| ︙ | ︙ | |||
100748 100749 100750 100751 100752 100753 100754 |
zStmt = 0;
}
/* Add an entry in sqlite_master for this index
*/
sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
| | | 100779 100780 100781 100782 100783 100784 100785 100786 100787 100788 100789 100790 100791 100792 100793 |
zStmt = 0;
}
/* Add an entry in sqlite_master for this index
*/
sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);",
db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb),
pIndex->zName,
pTab->zName,
iMem,
zStmt
);
sqlite3DbFree(db, zStmt);
|
| ︙ | ︙ | |||
100882 100883 100884 100885 100886 100887 100888 |
goto exit_drop_index;
}
iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
| | | | 100913 100914 100915 100916 100917 100918 100919 100920 100921 100922 100923 100924 100925 100926 100927 100928 100929 100930 100931 100932 100933 100934 100935 100936 100937 100938 100939 100940 100941 100942 100943 100944 100945 |
goto exit_drop_index;
}
iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_INDEX;
Table *pTab = pIndex->pTable;
const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
goto exit_drop_index;
}
if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX;
if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
goto exit_drop_index;
}
}
#endif
/* Generate code to remove the index and from the master table */
v = sqlite3GetVdbe(pParse);
if( v ){
sqlite3BeginWriteOperation(pParse, 1, iDb);
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pIndex->zName
);
sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
sqlite3ChangeCookie(pParse, iDb);
destroyRootPage(pParse, pIndex->tnum, iDb);
sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0);
}
|
| ︙ | ︙ | |||
101445 101446 101447 101448 101449 101450 101451 |
** attached database. Otherwise, invoke it for the database named zDb only.
*/
SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
sqlite3 *db = pParse->db;
int i;
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
| | | 101476 101477 101478 101479 101480 101481 101482 101483 101484 101485 101486 101487 101488 101489 101490 |
** attached database. Otherwise, invoke it for the database named zDb only.
*/
SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
sqlite3 *db = pParse->db;
int i;
for(i=0; i<db->nDb; i++){
Db *pDb = &db->aDb[i];
if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){
sqlite3CodeVerifySchema(pParse, i);
}
}
}
/*
** Generate VDBE code that prepares for doing an operation that
|
| ︙ | ︙ | |||
101692 101693 101694 101695 101696 101697 101698 |
}
sqlite3DbFree(db, zColl);
}
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
if( iDb<0 ) return;
z = sqlite3NameFromToken(db, pObjName);
if( z==0 ) return;
| | | 101723 101724 101725 101726 101727 101728 101729 101730 101731 101732 101733 101734 101735 101736 101737 |
}
sqlite3DbFree(db, zColl);
}
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
if( iDb<0 ) return;
z = sqlite3NameFromToken(db, pObjName);
if( z==0 ) return;
zDb = db->aDb[iDb].zDbSName;
pTab = sqlite3FindTable(db, z, zDb);
if( pTab ){
reindexTable(pParse, pTab, 0);
sqlite3DbFree(db, z);
return;
}
pIndex = sqlite3FindIndex(db, z, zDb);
|
| ︙ | ︙ | |||
102406 102407 102408 102409 102410 102411 102412 |
sqlite3 *db = pParse->db;
int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
pWhere = sqlite3ExprDup(db, pWhere, 0);
pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
| | | 102437 102438 102439 102440 102441 102442 102443 102444 102445 102446 102447 102448 102449 102450 102451 |
sqlite3 *db = pParse->db;
int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
pWhere = sqlite3ExprDup(db, pWhere, 0);
pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
assert( pFrom->a[0].pOn==0 );
assert( pFrom->a[0].pUsing==0 );
}
pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0,
SF_IncludeHidden, 0, 0);
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pSel, &dest);
|
| ︙ | ︙ | |||
102593 102594 102595 102596 102597 102598 102599 |
}
if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
goto delete_from_cleanup;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
| | | 102624 102625 102626 102627 102628 102629 102630 102631 102632 102633 102634 102635 102636 102637 102638 |
}
if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
goto delete_from_cleanup;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
zDb = db->aDb[iDb].zDbSName;
rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb);
assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE );
if( rcauth==SQLITE_DENY ){
goto delete_from_cleanup;
}
assert(!isView || pTrigger);
|
| ︙ | ︙ | |||
105925 105926 105927 105928 105929 105930 105931 | /* Exactly one of regOld and regNew should be non-zero. */ assert( (regOld==0)!=(regNew==0) ); /* If foreign-keys are disabled, this function is a no-op. */ if( (db->flags&SQLITE_ForeignKeys)==0 ) return; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | | | 105956 105957 105958 105959 105960 105961 105962 105963 105964 105965 105966 105967 105968 105969 105970 |
/* Exactly one of regOld and regNew should be non-zero. */
assert( (regOld==0)!=(regNew==0) );
/* If foreign-keys are disabled, this function is a no-op. */
if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
zDb = db->aDb[iDb].zDbSName;
/* Loop through all the foreign key constraints for which pTab is the
** child table (the table that the foreign key definition is part of). */
for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){
Table *pTo; /* Parent table of foreign key pFKey */
Index *pIdx = 0; /* Index on key columns in pTo */
int *aiFree = 0;
|
| ︙ | ︙ | |||
106665 106666 106667 106668 106669 106670 106671 | return 0; } #ifndef SQLITE_OMIT_AUTOINCREMENT /* ** Locate or create an AutoincInfo structure associated with table pTab ** which is in database iDb. Return the register number for the register | | > > | 106696 106697 106698 106699 106700 106701 106702 106703 106704 106705 106706 106707 106708 106709 106710 106711 106712 | return 0; } #ifndef SQLITE_OMIT_AUTOINCREMENT /* ** Locate or create an AutoincInfo structure associated with table pTab ** which is in database iDb. Return the register number for the register ** that holds the maximum rowid. Return zero if pTab is not an AUTOINCREMENT ** table. (Also return zero when doing a VACUUM since we do not want to ** update the AUTOINCREMENT counters during a VACUUM.) ** ** There is at most one AutoincInfo structure per table even if the ** same table is autoincremented multiple times due to inserts within ** triggers. A new AutoincInfo structure is created if this is the ** first use of table pTab. On 2nd and subsequent uses, the original ** AutoincInfo structure is used. ** |
| ︙ | ︙ | |||
106688 106689 106690 106691 106692 106693 106694 |
*/
static int autoIncBegin(
Parse *pParse, /* Parsing context */
int iDb, /* Index of the database holding pTab */
Table *pTab /* The table we are writing to */
){
int memId = 0; /* Register holding maximum rowid */
| | > > | 106721 106722 106723 106724 106725 106726 106727 106728 106729 106730 106731 106732 106733 106734 106735 106736 106737 |
*/
static int autoIncBegin(
Parse *pParse, /* Parsing context */
int iDb, /* Index of the database holding pTab */
Table *pTab /* The table we are writing to */
){
int memId = 0; /* Register holding maximum rowid */
if( (pTab->tabFlags & TF_Autoincrement)!=0
&& (pParse->db->flags & SQLITE_Vacuum)==0
){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
AutoincInfo *pInfo;
pInfo = pToplevel->pAinc;
while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; }
if( pInfo==0 ){
pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo));
|
| ︙ | ︙ | |||
107012 107013 107014 107015 107016 107017 107018 |
pTab = sqlite3SrcListLookup(pParse, pTabList);
if( pTab==0 ){
goto insert_cleanup;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
pDb = &db->aDb[iDb];
| | | 107047 107048 107049 107050 107051 107052 107053 107054 107055 107056 107057 107058 107059 107060 107061 |
pTab = sqlite3SrcListLookup(pParse, pTabList);
if( pTab==0 ){
goto insert_cleanup;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( iDb<db->nDb );
pDb = &db->aDb[iDb];
zDb = pDb->zDbSName;
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, zDb) ){
goto insert_cleanup;
}
withoutRowid = !HasRowid(pTab);
/* Figure out if we have any triggers and if the table being
** inserted into is a view
|
| ︙ | ︙ | |||
110970 110971 110972 110973 110974 110975 110976 |
if( minusFlag ){
zRight = sqlite3MPrintf(db, "-%T", pValue);
}else{
zRight = sqlite3NameFromToken(db, pValue);
}
assert( pId2 );
| | | 111005 111006 111007 111008 111009 111010 111011 111012 111013 111014 111015 111016 111017 111018 111019 |
if( minusFlag ){
zRight = sqlite3MPrintf(db, "-%T", pValue);
}else{
zRight = sqlite3NameFromToken(db, pValue);
}
assert( pId2 );
zDb = pId2->n>0 ? pDb->zDbSName : 0;
if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){
goto pragma_out;
}
/* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS
** connection. If it returns SQLITE_OK, then assume that the VFS
** handled the pragma and generate a no-op prepared statement.
|
| ︙ | ︙ | |||
111823 111824 111825 111826 111827 111828 111829 |
case PragTyp_DATABASE_LIST: {
static const char *azCol[] = { "seq", "name", "file" };
int i;
pParse->nMem = 3;
setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt==0 ) continue;
| | | | 111858 111859 111860 111861 111862 111863 111864 111865 111866 111867 111868 111869 111870 111871 111872 111873 111874 111875 |
case PragTyp_DATABASE_LIST: {
static const char *azCol[] = { "seq", "name", "file" };
int i;
pParse->nMem = 3;
setAllColumnNames(v, 3, azCol); assert( 3==ArraySize(azCol) );
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt==0 ) continue;
assert( db->aDb[i].zDbSName!=0 );
sqlite3VdbeMultiLoad(v, 1, "iss",
i,
db->aDb[i].zDbSName,
sqlite3BtreeGetFilename(db->aDb[i].pBt));
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
}
}
break;
case PragTyp_COLLATION_LIST: {
|
| ︙ | ︙ | |||
112115 112116 112117 112118 112119 112120 112121 |
pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
sqlite3VdbeChangeP5(v, (u8)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
| | | 112150 112151 112152 112153 112154 112155 112156 112157 112158 112159 112160 112161 112162 112163 112164 |
pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY);
sqlite3VdbeChangeP5(v, (u8)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
P4_DYNAMIC);
sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
sqlite3VdbeJumpHere(v, addr);
/* Make sure all the indices are constructed correctly.
|
| ︙ | ︙ | |||
112554 112555 112556 112557 112558 112559 112560 |
int i;
setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
pParse->nMem = 2;
for(i=0; i<db->nDb; i++){
Btree *pBt;
const char *zState = "unknown";
int j;
| | | | | 112589 112590 112591 112592 112593 112594 112595 112596 112597 112598 112599 112600 112601 112602 112603 112604 112605 112606 112607 112608 112609 112610 112611 |
int i;
setAllColumnNames(v, 2, azCol); assert( 2==ArraySize(azCol) );
pParse->nMem = 2;
for(i=0; i<db->nDb; i++){
Btree *pBt;
const char *zState = "unknown";
int j;
if( db->aDb[i].zDbSName==0 ) continue;
pBt = db->aDb[i].pBt;
if( pBt==0 || sqlite3BtreePager(pBt)==0 ){
zState = "closed";
}else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0,
SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){
zState = azLockName[j];
}
sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState);
sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 2);
}
break;
}
#endif
#ifdef SQLITE_HAS_CODEC
|
| ︙ | ︙ | |||
112698 112699 112700 112701 112702 112703 112704 112705 112706 112707 112708 112709 112710 112711 112712 112713 112714 |
}else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because db->init.busy is set to 1, no VDBE code is generated
** or executed. All the parser does is build the internal data
** structures that describe the table, index, or view.
*/
int rc;
sqlite3_stmt *pStmt;
TESTONLY(int rcp); /* Return code from sqlite3_prepare() */
assert( db->init.busy );
db->init.iDb = iDb;
db->init.newTnum = sqlite3Atoi(argv[1]);
db->init.orphanTrigger = 0;
TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
| > | > | 112733 112734 112735 112736 112737 112738 112739 112740 112741 112742 112743 112744 112745 112746 112747 112748 112749 112750 112751 112752 112753 112754 112755 112756 112757 112758 112759 |
}else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
/* Call the parser to process a CREATE TABLE, INDEX or VIEW.
** But because db->init.busy is set to 1, no VDBE code is generated
** or executed. All the parser does is build the internal data
** structures that describe the table, index, or view.
*/
int rc;
u8 saved_iDb = db->init.iDb;
sqlite3_stmt *pStmt;
TESTONLY(int rcp); /* Return code from sqlite3_prepare() */
assert( db->init.busy );
db->init.iDb = iDb;
db->init.newTnum = sqlite3Atoi(argv[1]);
db->init.orphanTrigger = 0;
TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
rc = db->errCode;
assert( (rc&0xFF)==(rcp&0xFF) );
db->init.iDb = saved_iDb;
assert( saved_iDb==0 || (db->flags & SQLITE_Vacuum)!=0 );
if( SQLITE_OK!=rc ){
if( db->init.orphanTrigger ){
assert( iDb==1 );
}else{
pData->rc = rc;
if( rc==SQLITE_NOMEM ){
sqlite3OomFault(db);
|
| ︙ | ︙ | |||
112732 112733 112734 112735 112736 112737 112738 |
/* If the SQL column is blank it means this is an index that
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
** constraint for a CREATE TABLE. The index should have already
** been created when we processed the CREATE TABLE. All we have
** to do here is record the root page number for that index.
*/
Index *pIndex;
| | | 112769 112770 112771 112772 112773 112774 112775 112776 112777 112778 112779 112780 112781 112782 112783 |
/* If the SQL column is blank it means this is an index that
** was created to be the PRIMARY KEY or to fulfill a UNIQUE
** constraint for a CREATE TABLE. The index should have already
** been created when we processed the CREATE TABLE. All we have
** to do here is record the root page number for that index.
*/
Index *pIndex;
pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zDbSName);
if( pIndex==0 ){
/* This can occur if there exists an index on a TEMP table which
** has the same name as another index on a permanent index. Since
** the permanent table is hidden by the TEMP table, we can also
** safely ignore the index on the permanent table.
*/
/* Do Nothing */;
|
| ︙ | ︙ | |||
112911 112912 112913 112914 112915 112916 112917 |
/* Read the schema information out of the schema tables
*/
assert( db->init.busy );
{
char *zSql;
zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid",
| | | 112948 112949 112950 112951 112952 112953 112954 112955 112956 112957 112958 112959 112960 112961 112962 |
/* Read the schema information out of the schema tables
*/
assert( db->init.busy );
{
char *zSql;
zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM \"%w\".%s ORDER BY rowid",
db->aDb[iDb].zDbSName, zMasterName);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
sqlite3_xauth xAuth;
xAuth = db->xAuth;
db->xAuth = 0;
#endif
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
|
| ︙ | ︙ | |||
113186 113187 113188 113189 113190 113191 113192 |
*/
for(i=0; i<db->nDb; i++) {
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
assert( sqlite3BtreeHoldsMutex(pBt) );
rc = sqlite3BtreeSchemaLocked(pBt);
if( rc ){
| | | 113223 113224 113225 113226 113227 113228 113229 113230 113231 113232 113233 113234 113235 113236 113237 |
*/
for(i=0; i<db->nDb; i++) {
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
assert( sqlite3BtreeHoldsMutex(pBt) );
rc = sqlite3BtreeSchemaLocked(pBt);
if( rc ){
const char *zDb = db->aDb[i].zDbSName;
sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
testcase( db->flags & SQLITE_ReadUncommitted );
goto end_prepare;
}
}
}
|
| ︙ | ︙ | |||
114942 114943 114944 114945 114946 114947 114948 |
zOrigCol = pTab->aCol[iCol].zName;
zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
estWidth = pTab->aCol[iCol].szEst;
}
zOrigTab = pTab->zName;
if( pNC->pParse ){
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
| | | 114979 114980 114981 114982 114983 114984 114985 114986 114987 114988 114989 114990 114991 114992 114993 |
zOrigCol = pTab->aCol[iCol].zName;
zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
estWidth = pTab->aCol[iCol].szEst;
}
zOrigTab = pTab->zName;
if( pNC->pParse ){
int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName;
}
#else
if( iCol<0 ){
zType = "INTEGER";
}else{
zType = sqlite3ColumnType(&pTab->aCol[iCol],0);
estWidth = pTab->aCol[iCol].szEst;
|
| ︙ | ︙ | |||
117898 117899 117900 117901 117902 117903 117904 |
if( db->mallocFailed ) break;
if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
pSub = 0;
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
continue;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
| | | 117935 117936 117937 117938 117939 117940 117941 117942 117943 117944 117945 117946 117947 117948 117949 |
if( db->mallocFailed ) break;
if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
pSub = 0;
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
continue;
}
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
}
for(j=0; j<pTab->nCol; j++){
char *zName = pTab->aCol[j].zName;
char *zColname; /* The computed column name */
char *zToFree; /* Malloced string that needs to be freed */
Token sColname; /* Computed column name as a token */
|
| ︙ | ︙ | |||
119610 119611 119612 119613 119614 119615 119616 |
goto trigger_cleanup;
}
iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_CREATE_TRIGGER;
| | | | 119647 119648 119649 119650 119651 119652 119653 119654 119655 119656 119657 119658 119659 119660 119661 119662 |
goto trigger_cleanup;
}
iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_CREATE_TRIGGER;
const char *zDb = db->aDb[iTabDb].zDbSName;
const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb;
if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER;
if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){
goto trigger_cleanup;
}
if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){
goto trigger_cleanup;
}
|
| ︙ | ︙ | |||
119705 119706 119707 119708 119709 119710 119711 |
/* Make an entry in the sqlite_master table */
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto triggerfinish_cleanup;
sqlite3BeginWriteOperation(pParse, 0, iDb);
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
| | | 119742 119743 119744 119745 119746 119747 119748 119749 119750 119751 119752 119753 119754 119755 119756 |
/* Make an entry in the sqlite_master table */
v = sqlite3GetVdbe(pParse);
if( v==0 ) goto triggerfinish_cleanup;
sqlite3BeginWriteOperation(pParse, 0, iDb);
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), zName,
pTrig->table, z);
sqlite3DbFree(db, z);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddParseSchemaOp(v, iDb,
sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName));
}
|
| ︙ | ︙ | |||
119894 119895 119896 119897 119898 119899 119900 |
assert( pName->nSrc==1 );
zDb = pName->a[0].zDatabase;
zName = pName->a[0].zName;
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
| | | 119931 119932 119933 119934 119935 119936 119937 119938 119939 119940 119941 119942 119943 119944 119945 |
assert( pName->nSrc==1 );
zDb = pName->a[0].zDatabase;
zName = pName->a[0].zName;
assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
for(i=OMIT_TEMPDB; i<db->nDb; i++){
int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue;
assert( sqlite3SchemaMutexHeld(db, j, 0) );
pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
if( pTrigger ) break;
}
if( !pTrigger ){
if( !noErr ){
sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
|
| ︙ | ︙ | |||
119940 119941 119942 119943 119944 119945 119946 |
assert( iDb>=0 && iDb<db->nDb );
pTable = tableOfTrigger(pTrigger);
assert( pTable );
assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_TRIGGER;
| | | | 119977 119978 119979 119980 119981 119982 119983 119984 119985 119986 119987 119988 119989 119990 119991 119992 119993 119994 119995 119996 119997 119998 119999 120000 120001 120002 120003 120004 120005 120006 120007 |
assert( iDb>=0 && iDb<db->nDb );
pTable = tableOfTrigger(pTrigger);
assert( pTable );
assert( pTable->pSchema==pTrigger->pSchema || iDb==1 );
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int code = SQLITE_DROP_TRIGGER;
const char *zDb = db->aDb[iDb].zDbSName;
const char *zTab = SCHEMA_TABLE(iDb);
if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER;
if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) ||
sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){
return;
}
}
#endif
/* Generate code to destroy the database record of the trigger.
*/
assert( pTable!=0 );
if( (v = sqlite3GetVdbe(pParse))!=0 ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb), pTrigger->zName
);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
}
}
/*
|
| ︙ | ︙ | |||
120059 120060 120061 120062 120063 120064 120065 120066 |
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
assert( iDb<db->nDb );
| > > | | 120096 120097 120098 120099 120100 120101 120102 120103 120104 120105 120106 120107 120108 120109 120110 120111 120112 120113 |
pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
const char *zDb;
assert( iDb<db->nDb );
zDb = db->aDb[iDb].zDbSName;
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, zDb);
}
}
return pSrc;
}
/*
** Generate VDBE code for the statements inside the body of a single
|
| ︙ | ︙ | |||
120747 120748 120749 120750 120751 120752 120753 |
}
}
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int rc;
rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
j<0 ? "ROWID" : pTab->aCol[j].zName,
| | | 120786 120787 120788 120789 120790 120791 120792 120793 120794 120795 120796 120797 120798 120799 120800 |
}
}
#ifndef SQLITE_OMIT_AUTHORIZATION
{
int rc;
rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName,
j<0 ? "ROWID" : pTab->aCol[j].zName,
db->aDb[iDb].zDbSName);
if( rc==SQLITE_DENY ){
goto update_cleanup;
}else if( rc==SQLITE_IGNORE ){
aXRef[j] = -1;
}
}
#endif
|
| ︙ | ︙ | |||
121349 121350 121351 121352 121353 121354 121355 | ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) | < < < < < < < < < | < < < | > > > > > > > | | > > > > > > > > > | | > > | > < | < | < < < < < | | > | | < | | | < | | < < < < | 121388 121389 121390 121391 121392 121393 121394 121395 121396 121397 121398 121399 121400 121401 121402 121403 121404 121405 121406 121407 121408 121409 121410 121411 121412 121413 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 |
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
*/
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */
#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/*
** Execute zSql on database db.
**
** If zSql returns rows, then each row will have exactly one
** column. (This will only happen if zSql begins with "SELECT".)
** Take each row of result and call execSql() again recursively.
**
** The execSqlF() routine does the same thing, except it accepts
** a format string as its third argument
*/
static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
sqlite3_stmt *pStmt;
int rc;
/* printf("SQL: [%s]\n", zSql); fflush(stdout); */
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
if( rc!=SQLITE_OK ) return rc;
while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
if( zSubSql ){
assert( zSubSql[0]!='S' );
rc = execSql(db, pzErrMsg, zSubSql);
if( rc!=SQLITE_OK ) break;
}
}
assert( rc!=SQLITE_ROW );
if( rc==SQLITE_DONE ) rc = SQLITE_OK;
if( rc ){
sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
}
(void)sqlite3_finalize(pStmt);
return rc;
}
static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){
char *z;
va_list ap;
int rc;
va_start(ap, zSql);
z = sqlite3VMPrintf(db, zSql, ap);
va_end(ap);
if( z==0 ) return SQLITE_NOMEM;
rc = execSql(db, pzErrMsg, z);
sqlite3DbFree(db, z);
return rc;
}
/*
** The VACUUM command is used to clean up the database,
** collapse free space, etc. It is modelled after the VACUUM command
** in PostgreSQL. The VACUUM command works as follows:
**
|
| ︙ | ︙ | |||
121432 121433 121434 121435 121436 121437 121438 | ** the copy of step (3) were replaced by deleting the original database ** and renaming the transient database as the original. But that will ** not work if other processes are attached to the original database. ** And a power loss in between deleting the original and renaming the ** transient would cause the database file to appear to be deleted ** following reboot. */ | | > | | | | < > | > | > | < < < < < | > | | | < < | | | < | | 121466 121467 121468 121469 121470 121471 121472 121473 121474 121475 121476 121477 121478 121479 121480 121481 121482 121483 121484 121485 121486 121487 121488 121489 121490 121491 121492 121493 121494 121495 121496 121497 121498 121499 121500 121501 121502 121503 121504 121505 121506 121507 121508 121509 121510 121511 121512 121513 121514 121515 121516 121517 121518 121519 121520 121521 121522 121523 121524 121525 121526 121527 121528 121529 121530 121531 121532 121533 121534 121535 121536 121537 121538 121539 121540 121541 121542 121543 121544 121545 121546 121547 121548 121549 121550 121551 121552 121553 121554 121555 121556 121557 121558 121559 121560 121561 121562 121563 121564 121565 121566 121567 121568 121569 121570 121571 121572 121573 121574 121575 121576 121577 121578 121579 121580 121581 |
** the copy of step (3) were replaced by deleting the original database
** and renaming the transient database as the original. But that will
** not work if other processes are attached to the original database.
** And a power loss in between deleting the original and renaming the
** transient would cause the database file to appear to be deleted
** following reboot.
*/
SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm){
Vdbe *v = sqlite3GetVdbe(pParse);
int iDb = pNm ? sqlite3TwoPartName(pParse, pNm, pNm, &pNm) : 0;
if( v && (iDb>=2 || iDb==0) ){
sqlite3VdbeAddOp1(v, OP_Vacuum, iDb);
sqlite3VdbeUsesBtree(v, iDb);
}
return;
}
/*
** This routine implements the OP_Vacuum opcode of the VDBE.
*/
SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db, int iDb){
int rc = SQLITE_OK; /* Return code from service routines */
Btree *pMain; /* The database being vacuumed */
Btree *pTemp; /* The temporary database we vacuum into */
int saved_flags; /* Saved value of the db->flags */
int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */
u8 saved_mTrace; /* Saved trace settings */
Db *pDb = 0; /* Database to detach at end of vacuum */
int isMemDb; /* True if vacuuming a :memory: database */
int nRes; /* Bytes of reserved space at the end of each page */
int nDb; /* Number of attached databases */
const char *zDbMain; /* Schema name of database to vacuum */
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
return SQLITE_ERROR;
}
if( db->nVdbeActive>1 ){
sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
return SQLITE_ERROR;
}
/* Save the current value of the database flags so that it can be
** restored before returning. Then set the writable-schema flag, and
** disable CHECK and foreign key constraints. */
saved_flags = db->flags;
saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange;
saved_mTrace = db->mTrace;
db->flags |= (SQLITE_WriteSchema | SQLITE_IgnoreChecks
| SQLITE_PreferBuiltin | SQLITE_Vacuum);
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);
db->mTrace = 0;
zDbMain = db->aDb[iDb].zDbSName;
pMain = db->aDb[iDb].pBt;
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
** can be set to 'off' for this file, as it is not recovered if a crash
** occurs anyway. The integrity of the database is maintained by a
** (possibly synchronous) transaction opened on the main database before
** sqlite3BtreeCopyFile() is called.
**
** An optimisation would be to use a non-journaled pager.
** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
** that actually made the VACUUM run slower. Very little journalling
** actually occurs when doing a vacuum since the vacuum_db is initially
** empty. Only the journal header is written. Apparently it takes more
** time to parse and run the PRAGMA to turn journalling off than it does
** to write the journal header file.
*/
nDb = db->nDb;
rc = execSql(db, pzErrMsg, "ATTACH''AS vacuum_db");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
assert( (db->nDb-1)==nDb );
pDb = &db->aDb[nDb];
assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
pTemp = pDb->pBt;
/* The call to execSql() to attach the temp database has left the file
** locked (as there was more than one active statement when the transaction
** to read the schema was concluded. Unlock it here so that this doesn't
** cause problems for the call to BtreeSetPageSize() below. */
sqlite3BtreeCommit(pTemp);
nRes = sqlite3BtreeGetOptimalReserve(pMain);
/* A VACUUM cannot change the pagesize of an encrypted database. */
#ifdef SQLITE_HAS_CODEC
if( db->nextPagesize ){
extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
int nKey;
char *zKey;
sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
if( nKey ) db->nextPagesize = 0;
}
#endif
sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size);
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF);
/* Begin a transaction and take an exclusive lock on the main database
** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below,
** to ensure that we do not try to change the page-size on a WAL database.
*/
rc = execSql(db, pzErrMsg, "BEGIN");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = sqlite3BtreeBeginTrans(pMain, 2);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Do not attempt to change the page size for a WAL database */
if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
==PAGER_JOURNALMODE_WAL ){
|
| ︙ | ︙ | |||
121564 121565 121566 121567 121568 121569 121570 |
sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
sqlite3BtreeGetAutoVacuum(pMain));
#endif
/* Query the schema of the main database. Create a mirror schema
** in the temporary database.
*/
| > | | | | > | | | > > | < < < < < | | | | < | > < < < < < < < < < < < < < < < | | < | | | > | 121594 121595 121596 121597 121598 121599 121600 121601 121602 121603 121604 121605 121606 121607 121608 121609 121610 121611 121612 121613 121614 121615 121616 121617 121618 121619 121620 121621 121622 121623 121624 121625 121626 121627 121628 121629 121630 121631 121632 121633 121634 121635 121636 121637 121638 121639 121640 121641 121642 121643 121644 121645 121646 121647 121648 121649 |
sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac :
sqlite3BtreeGetAutoVacuum(pMain));
#endif
/* Query the schema of the main database. Create a mirror schema
** in the temporary database.
*/
db->init.iDb = nDb; /* force new CREATE statements into vacuum_db */
rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_master"
" WHERE type='table'AND name<>'sqlite_sequence'"
" AND coalesce(rootpage,1)>0",
zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = execSqlF(db, pzErrMsg,
"SELECT sql FROM \"%w\".sqlite_master"
" WHERE type='index' AND length(sql)>10",
zDbMain
);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
db->init.iDb = 0;
/* Loop through the tables in the main database. For each, do
** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
** the contents to the temporary database.
*/
rc = execSqlF(db, pzErrMsg,
"SELECT'INSERT INTO vacuum_db.'||quote(name)"
"||' SELECT*FROM\"%w\".'||quote(name)"
"FROM vacuum_db.sqlite_master "
"WHERE type='table'AND coalesce(rootpage,1)>0",
zDbMain
);
assert( (db->flags & SQLITE_Vacuum)!=0 );
db->flags &= ~SQLITE_Vacuum;
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Copy the triggers, views, and virtual tables from the main database
** over to the temporary database. None of these objects has any
** associated storage, so all we have to do is copy their entries
** from the SQLITE_MASTER table.
*/
rc = execSqlF(db, pzErrMsg,
"INSERT INTO vacuum_db.sqlite_master"
" SELECT*FROM \"%w\".sqlite_master"
" WHERE type IN('view','trigger')"
" OR(type='table'AND rootpage=0)",
zDbMain
);
if( rc ) goto end_of_vacuum;
/* At this point, there is a write transaction open on both the
** vacuum database and the main database. Assuming no error occurs,
** both transactions are closed by this block - the main database
** transaction by sqlite3BtreeCopyFile() and the other by an explicit
|
| ︙ | ︙ | |||
121675 121676 121677 121678 121679 121680 121681 121682 121683 121684 121685 121686 121687 121688 | } assert( rc==SQLITE_OK ); rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1); end_of_vacuum: /* Restore the original value of db->flags */ db->flags = saved_flags; db->nChange = saved_nChange; db->nTotalChange = saved_nTotalChange; db->mTrace = saved_mTrace; sqlite3BtreeSetPageSize(pMain, -1, -1, 1); /* Currently there is an SQL level transaction open on the vacuum | > | 121689 121690 121691 121692 121693 121694 121695 121696 121697 121698 121699 121700 121701 121702 121703 | } assert( rc==SQLITE_OK ); rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1); end_of_vacuum: /* Restore the original value of db->flags */ db->init.iDb = 0; db->flags = saved_flags; db->nChange = saved_nChange; db->nTotalChange = saved_nTotalChange; db->mTrace = saved_mTrace; sqlite3BtreeSetPageSize(pMain, -1, -1, 1); /* Currently there is an SQL level transaction open on the vacuum |
| ︙ | ︙ | |||
122053 122054 122055 122056 122057 122058 122059 |
/* Creating a virtual table invokes the authorization callback twice.
** The first invocation, to obtain permission to INSERT a row into the
** sqlite_master table, has already been made by sqlite3StartTable().
** The second call, to obtain permission to create the table, is made now.
*/
if( pTable->azModuleArg ){
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
| | | 122068 122069 122070 122071 122072 122073 122074 122075 122076 122077 122078 122079 122080 122081 122082 |
/* Creating a virtual table invokes the authorization callback twice.
** The first invocation, to obtain permission to INSERT a row into the
** sqlite_master table, has already been made by sqlite3StartTable().
** The second call, to obtain permission to create the table, is made now.
*/
if( pTable->azModuleArg ){
sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName,
pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName);
}
#endif
}
/*
** This routine takes the module argument that has been accumulating
** in pParse->zArg[] and appends it to the list of arguments on the
|
| ︙ | ︙ | |||
122117 122118 122119 122120 122121 122122 122123 |
** by sqlite3StartTable().
*/
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3NestedParse(pParse,
"UPDATE %Q.%s "
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
"WHERE rowid=#%d",
| | | 122132 122133 122134 122135 122136 122137 122138 122139 122140 122141 122142 122143 122144 122145 122146 |
** by sqlite3StartTable().
*/
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3NestedParse(pParse,
"UPDATE %Q.%s "
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
"WHERE rowid=#%d",
db->aDb[iDb].zDbSName, SCHEMA_TABLE(iDb),
pTab->zName,
pTab->zName,
zStmt,
pParse->regRowid
);
sqlite3DbFree(db, zStmt);
v = sqlite3GetVdbe(pParse);
|
| ︙ | ︙ | |||
122227 122228 122229 122230 122231 122232 122233 |
sqlite3DbFree(db, zModuleName);
return SQLITE_NOMEM_BKPT;
}
pVTable->db = db;
pVTable->pMod = pMod;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
| | | 122242 122243 122244 122245 122246 122247 122248 122249 122250 122251 122252 122253 122254 122255 122256 |
sqlite3DbFree(db, zModuleName);
return SQLITE_NOMEM_BKPT;
}
pVTable->db = db;
pVTable->pMod = pMod;
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
pTab->azModuleArg[1] = db->aDb[iDb].zDbSName;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
assert( xConstruct );
sCtx.pTab = pTab;
sCtx.pVTable = pVTable;
sCtx.pPrior = db->pVtabCtx;
|
| ︙ | ︙ | |||
122391 122392 122393 122394 122395 122396 122397 |
*/
SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
int rc = SQLITE_OK;
Table *pTab;
Module *pMod;
const char *zMod;
| | | 122406 122407 122408 122409 122410 122411 122412 122413 122414 122415 122416 122417 122418 122419 122420 |
*/
SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
int rc = SQLITE_OK;
Table *pTab;
Module *pMod;
const char *zMod;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable );
/* Locate the required virtual table module */
zMod = pTab->azModuleArg[0];
pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
/* If the module has been registered and includes a Create method,
|
| ︙ | ︙ | |||
122515 122516 122517 122518 122519 122520 122521 |
**
** This call is a no-op if zTab is not a virtual table.
*/
SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
int rc = SQLITE_OK;
Table *pTab;
| | | 122530 122531 122532 122533 122534 122535 122536 122537 122538 122539 122540 122541 122542 122543 122544 |
**
** This call is a no-op if zTab is not a virtual table.
*/
SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
int rc = SQLITE_OK;
Table *pTab;
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){
VTable *p;
int (*xDestroy)(sqlite3_vtab *);
for(p=pTab->pVTable; p; p=p->pNext){
assert( p->pVtab );
if( p->pVtab->nRef>0 ){
return SQLITE_LOCKED;
|
| ︙ | ︙ | |||
125628 125629 125630 125631 125632 125633 125634 |
**
** If it is then return TRUE. If not, return FALSE.
*/
static int isMatchOfColumn(
Expr *pExpr, /* Test this expression */
unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */
){
| | | 125643 125644 125645 125646 125647 125648 125649 125650 125651 125652 125653 125654 125655 125656 125657 |
**
** If it is then return TRUE. If not, return FALSE.
*/
static int isMatchOfColumn(
Expr *pExpr, /* Test this expression */
unsigned char *peOp2 /* OUT: 0 for MATCH, or else an op2 value */
){
static const struct Op2 {
const char *zOp;
unsigned char eOp2;
} aOp[] = {
{ "match", SQLITE_INDEX_CONSTRAINT_MATCH },
{ "glob", SQLITE_INDEX_CONSTRAINT_GLOB },
{ "like", SQLITE_INDEX_CONSTRAINT_LIKE },
{ "regexp", SQLITE_INDEX_CONSTRAINT_REGEXP }
|
| ︙ | ︙ | |||
126613 126614 126615 126616 126617 126618 126619 |
/*
** These routines walk (recursively) an expression tree and generate
** a bitmask indicating which tables are used in that expression
** tree.
*/
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
| | > | | 126628 126629 126630 126631 126632 126633 126634 126635 126636 126637 126638 126639 126640 126641 126642 126643 126644 126645 126646 126647 126648 126649 |
/*
** These routines walk (recursively) an expression tree and generate
** a bitmask indicating which tables are used in that expression
** tree.
*/
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
Bitmask mask;
if( p==0 ) return 0;
if( p->op==TK_COLUMN ){
mask = sqlite3WhereGetMask(pMaskSet, p->iTable);
return mask;
}
assert( !ExprHasProperty(p, EP_TokenOnly) );
mask = p->pRight ? sqlite3WhereExprUsage(pMaskSet, p->pRight) : 0;
if( p->pLeft ) mask |= sqlite3WhereExprUsage(pMaskSet, p->pLeft);
if( ExprHasProperty(p, EP_xIsSelect) ){
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
}else if( p->x.pList ){
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
}
return mask;
|
| ︙ | ︙ | |||
131866 131867 131868 131869 131870 131871 131872 | ** token onto the stack and goto state N. ** ** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then ** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. ** ** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE ** and YY_MAX_REDUCE | | | | > > | | | < > > > | | 131882 131883 131884 131885 131886 131887 131888 131889 131890 131891 131892 131893 131894 131895 131896 131897 131898 131899 131900 131901 131902 131903 131904 131905 131906 131907 131908 131909 131910 131911 131912 131913 131914 131915 131916 131917 131918 | ** token onto the stack and goto state N. ** ** N between YY_MIN_SHIFTREDUCE Shift to an arbitrary state then ** and YY_MAX_SHIFTREDUCE reduce by rule N-YY_MIN_SHIFTREDUCE. ** ** N between YY_MIN_REDUCE Reduce by rule N-YY_MIN_REDUCE ** and YY_MAX_REDUCE ** ** N == YY_ERROR_ACTION A syntax error has occurred. ** ** N == YY_ACCEPT_ACTION The parser accepts its input. ** ** N == YY_NO_ACTION No such action. Denotes unused ** slots in the yy_action[] table. ** ** The action table is constructed as a single large table named yy_action[]. ** Given state S and lookahead X, the action is computed as either: ** ** (A) N = yy_action[ yy_shift_ofst[S] + X ] ** (B) N = yy_default[S] ** ** The (A) formula is preferred. The B formula is used instead if: ** (1) The yy_shift_ofst[S]+X value is out of range, or ** (2) yy_lookahead[yy_shift_ofst[S]+X] is not equal to X, or ** (3) yy_shift_ofst[S] equal YY_SHIFT_USE_DFLT. ** (Implementation note: YY_SHIFT_USE_DFLT is chosen so that ** YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X. ** Hence only tests (1) and (2) need to be evaluated.) ** ** The formulas above are for computing the action when the lookahead is ** a terminal symbol. If the lookahead is a non-terminal (as occurs after ** a reduce action) then the yy_reduce_ofst[] array is used in place of ** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of ** YY_SHIFT_USE_DFLT. ** ** The following are the tables generated in this section: ** |
| ︙ | ︙ | |||
132209 132210 132211 132212 132213 132214 132215 | /* 1450 */ 22, 58, 23, 22, 79, 22, 249, 249, 246, 79, /* 1460 */ 23, 23, 23, 116, 68, 22, 26, 23, 22, 56, /* 1470 */ 122, 23, 23, 64, 22, 124, 26, 26, 64, 64, /* 1480 */ 23, 23, 23, 23, 11, 23, 22, 26, 23, 22, /* 1490 */ 24, 1, 23, 22, 26, 122, 24, 23, 22, 122, /* 1500 */ 23, 23, 22, 122, 122, 23, 15, }; | | | | | | | | | | | 132229 132230 132231 132232 132233 132234 132235 132236 132237 132238 132239 132240 132241 132242 132243 132244 132245 132246 132247 132248 132249 132250 132251 132252 132253 132254 132255 132256 132257 132258 132259 132260 132261 132262 132263 132264 132265 132266 132267 132268 132269 132270 132271 132272 132273 132274 132275 132276 132277 132278 132279 |
/* 1450 */ 22, 58, 23, 22, 79, 22, 249, 249, 246, 79,
/* 1460 */ 23, 23, 23, 116, 68, 22, 26, 23, 22, 56,
/* 1470 */ 122, 23, 23, 64, 22, 124, 26, 26, 64, 64,
/* 1480 */ 23, 23, 23, 23, 11, 23, 22, 26, 23, 22,
/* 1490 */ 24, 1, 23, 22, 26, 122, 24, 23, 22, 122,
/* 1500 */ 23, 23, 22, 122, 122, 23, 15,
};
#define YY_SHIFT_USE_DFLT (1507)
#define YY_SHIFT_COUNT (442)
#define YY_SHIFT_MIN (-94)
#define YY_SHIFT_MAX (1491)
static const short yy_shift_ofst[] = {
/* 0 */ 40, 564, 869, 577, 725, 725, 725, 725, 690, -19,
/* 10 */ 16, 16, 100, 725, 725, 725, 725, 725, 725, 725,
/* 20 */ 841, 841, 538, 507, 684, 565, 61, 137, 172, 207,
/* 30 */ 242, 277, 312, 347, 382, 424, 424, 424, 424, 424,
/* 40 */ 424, 424, 424, 424, 424, 424, 424, 424, 424, 424,
/* 50 */ 459, 424, 494, 529, 529, 670, 725, 725, 725, 725,
/* 60 */ 725, 725, 725, 725, 725, 725, 725, 725, 725, 725,
/* 70 */ 725, 725, 725, 725, 725, 725, 725, 725, 725, 725,
/* 80 */ 725, 725, 725, 725, 821, 725, 725, 725, 725, 725,
/* 90 */ 725, 725, 725, 725, 725, 725, 725, 725, 952, 711,
/* 100 */ 711, 711, 711, 711, 766, 23, 32, 924, 637, 825,
/* 110 */ 837, 837, 924, 73, 183, -51, 1507, 1507, 1507, 501,
/* 120 */ 501, 501, 903, 903, 632, 205, 241, 924, 924, 924,
/* 130 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
/* 140 */ 924, 924, 924, 924, 924, 924, 924, 192, 1027, 1106,
/* 150 */ 1106, 183, 176, 176, 176, 176, 176, 176, 1507, 1507,
/* 160 */ 1507, 880, -94, -94, 578, 734, 99, 730, 769, 349,
/* 170 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
/* 180 */ 924, 924, 924, 924, 924, 924, 924, 954, 954, 954,
/* 190 */ 924, 924, 622, 924, 924, 924, -18, 924, 924, 914,
/* 200 */ 924, 924, 924, 924, 924, 924, 924, 924, 924, 924,
/* 210 */ 441, 1020, 1107, 1107, 1107, 569, 45, 217, 510, 423,
/* 220 */ 834, 834, 1156, 423, 1156, 1144, 1187, 359, 1051, 834,
/* 230 */ -17, 1051, 1051, 1099, 469, 1192, 1229, 1176, 1176, 1233,
/* 240 */ 1233, 1176, 1277, 1285, 1183, 1296, 1296, 1296, 1296, 1176,
/* 250 */ 1297, 1183, 1277, 1285, 1285, 1183, 1176, 1297, 1182, 1250,
/* 260 */ 1176, 1176, 1297, 1311, 1176, 1297, 1176, 1297, 1311, 1234,
/* 270 */ 1234, 1234, 1267, 1311, 1234, 1244, 1234, 1267, 1234, 1234,
/* 280 */ 1232, 1247, 1232, 1247, 1232, 1247, 1232, 1247, 1176, 1334,
/* 290 */ 1176, 1235, 1311, 1318, 1318, 1311, 1248, 1253, 1245, 1249,
/* 300 */ 1183, 1355, 1357, 1368, 1368, 1378, 1378, 1378, 1378, 1507,
/* 310 */ 1507, 1507, 1507, 1507, 1507, 1507, 1507, 451, 936, 816,
/* 320 */ 888, 1069, 799, 1111, 1197, 1193, 1201, 1202, 1203, 1213,
/* 330 */ 1134, 1117, 1230, 497, 1218, 1219, 1154, 1223, 1115, 1120,
/* 340 */ 1231, 1164, 1160, 1392, 1394, 1376, 1257, 1385, 1307, 1386,
/* 350 */ 1383, 1388, 1292, 1282, 1303, 1294, 1395, 1293, 1403, 1419,
/* 360 */ 1298, 1291, 1389, 1390, 1314, 1372, 1365, 1308, 1430, 1427,
/* 370 */ 1411, 1327, 1295, 1356, 1412, 1359, 1350, 1369, 1333, 1418,
/* 380 */ 1423, 1425, 1335, 1340, 1424, 1370, 1426, 1428, 1429, 1431,
|
| ︙ | ︙ | |||
133198 133199 133200 133201 133202 133203 133204 |
int i;
int stateno = pParser->yytos->stateno;
if( stateno>=YY_MIN_REDUCE ) return stateno;
assert( stateno <= YY_SHIFT_COUNT );
do{
i = yy_shift_ofst[stateno];
| < < | | | | | | | | | | | | | | | | | | | | | | | | | | < | 133218 133219 133220 133221 133222 133223 133224 133225 133226 133227 133228 133229 133230 133231 133232 133233 133234 133235 133236 133237 133238 133239 133240 133241 133242 133243 133244 133245 133246 133247 133248 133249 133250 133251 133252 133253 133254 133255 133256 133257 133258 133259 133260 133261 133262 133263 133264 133265 133266 133267 133268 133269 133270 133271 133272 |
int i;
int stateno = pParser->yytos->stateno;
if( stateno>=YY_MIN_REDUCE ) return stateno;
assert( stateno <= YY_SHIFT_COUNT );
do{
i = yy_shift_ofst[stateno];
assert( iLookAhead!=YYNOCODE );
i += iLookAhead;
if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
#ifdef YYFALLBACK
YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
&& (iFallback = yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
}
#endif
assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
iLookAhead = iFallback;
continue;
}
#endif
#ifdef YYWILDCARD
{
int j = i - iLookAhead + YYWILDCARD;
if(
#if YY_SHIFT_MIN+YYWILDCARD<0
j>=0 &&
#endif
#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
j<YY_ACTTAB_COUNT &&
#endif
yy_lookahead[j]==YYWILDCARD && iLookAhead>0
){
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
yyTracePrompt, yyTokenName[iLookAhead],
yyTokenName[YYWILDCARD]);
}
#endif /* NDEBUG */
return yy_action[j];
}
}
#endif /* YYWILDCARD */
return yy_default[stateno];
}else{
return yy_action[i];
}
}while(1);
}
|
| ︙ | ︙ | |||
134677 134678 134679 134680 134681 134682 134683 |
yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
}
break;
case 213: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
break;
case 214: /* cmd ::= VACUUM */
| > > | | | 134694 134695 134696 134697 134698 134699 134700 134701 134702 134703 134704 134705 134706 134707 134708 134709 134710 134711 |
yymsp[-2].minor.yy148 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy194, yymsp[0].minor.yy194); /*A-overwrites-Y*/
}
break;
case 213: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);}
break;
case 214: /* cmd ::= VACUUM */
{sqlite3Vacuum(pParse,0);}
break;
case 215: /* cmd ::= VACUUM nm */
{sqlite3Vacuum(pParse,&yymsp[0].minor.yy0);}
break;
case 216: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
case 217: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
|
| ︙ | ︙ | |||
136004 136005 136006 136007 136008 136009 136010 |
return SQLITE_NOMEM_BKPT;
}
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
assert( pParse->nzVar==0 );
assert( pParse->azVar==0 );
| | > | | | | | | > > > > > > > > > > > < < < < < < < < < | 136023 136024 136025 136026 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 |
return SQLITE_NOMEM_BKPT;
}
assert( pParse->pNewTable==0 );
assert( pParse->pNewTrigger==0 );
assert( pParse->nVar==0 );
assert( pParse->nzVar==0 );
assert( pParse->azVar==0 );
while( 1 ){
assert( i>=0 );
if( zSql[i]!=0 ){
pParse->sLastToken.z = &zSql[i];
pParse->sLastToken.n = sqlite3GetToken((u8*)&zSql[i],&tokenType);
i += pParse->sLastToken.n;
if( i>mxSqlLen ){
pParse->rc = SQLITE_TOOBIG;
break;
}
}else{
/* Upon reaching the end of input, call the parser two more times
** with tokens TK_SEMI and 0, in that order. */
if( lastTokenParsed==TK_SEMI ){
tokenType = 0;
}else if( lastTokenParsed==0 ){
break;
}else{
tokenType = TK_SEMI;
}
}
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
if( db->u1.isInterrupted ){
pParse->rc = SQLITE_INTERRUPT;
break;
}
if( tokenType==TK_ILLEGAL ){
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
&pParse->sLastToken);
break;
}
}else{
sqlite3Parser(pEngine, tokenType, pParse->sLastToken, pParse);
lastTokenParsed = tokenType;
if( pParse->rc!=SQLITE_OK || db->mallocFailed ) break;
}
}
assert( nErr==0 );
pParse->zTail = &zSql[i];
#ifdef YYTRACKMAXSTACKDEPTH
sqlite3_mutex_enter(sqlite3MallocMutex());
sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK,
sqlite3ParserStackPeak(pEngine)
);
sqlite3_mutex_leave(sqlite3MallocMutex());
#endif /* YYDEBUG */
|
| ︙ | ︙ | |||
137280 137281 137282 137283 137284 137285 137286 137287 137288 137289 137290 137291 137292 137293 |
** Configuration settings for an individual database connection
*/
SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
va_list ap;
int rc;
va_start(ap, op);
switch( op ){
case SQLITE_DBCONFIG_LOOKASIDE: {
void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
rc = setupLookaside(db, pBuf, sz, cnt);
break;
}
| > > > > > | 137302 137303 137304 137305 137306 137307 137308 137309 137310 137311 137312 137313 137314 137315 137316 137317 137318 137319 137320 |
** Configuration settings for an individual database connection
*/
SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
va_list ap;
int rc;
va_start(ap, op);
switch( op ){
case SQLITE_DBCONFIG_MAINDBNAME: {
db->aDb[0].zDbSName = va_arg(ap,char*);
rc = SQLITE_OK;
break;
}
case SQLITE_DBCONFIG_LOOKASIDE: {
void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */
int sz = va_arg(ap, int); /* IMP: R-47871-25994 */
int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
rc = setupLookaside(db, pBuf, sz, cnt);
break;
}
|
| ︙ | ︙ | |||
139423 139424 139425 139426 139427 139428 139429 | if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db); sqlite3BtreeLeave(db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); /* The default safety_level for the main database is FULL; for the temp ** database it is OFF. This matches the pager layer defaults. */ | | | | 139450 139451 139452 139453 139454 139455 139456 139457 139458 139459 139460 139461 139462 139463 139464 139465 139466 |
if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
sqlite3BtreeLeave(db->aDb[0].pBt);
db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
/* The default safety_level for the main database is FULL; for the temp
** database it is OFF. This matches the pager layer defaults.
*/
db->aDb[0].zDbSName = "main";
db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1;
db->aDb[1].zDbSName = "temp";
db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF;
db->magic = SQLITE_MAGIC_OPEN;
if( db->mallocFailed ){
goto opendb_out;
}
|
| ︙ | ︙ | |||
140386 140387 140388 140389 140390 140391 140392 |
/*
** Return the Btree pointer identified by zDbName. Return NULL if not found.
*/
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
int i;
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt
| | | 140413 140414 140415 140416 140417 140418 140419 140420 140421 140422 140423 140424 140425 140426 140427 |
/*
** Return the Btree pointer identified by zDbName. Return NULL if not found.
*/
SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
int i;
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt
&& (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zDbSName)==0)
){
return db->aDb[i].pBt;
}
}
return 0;
}
|
| ︙ | ︙ | |||
164752 164753 164754 164755 164756 164757 164758 | ); /* ** Open an RBU handle to perform an RBU vacuum on database file zTarget. ** An RBU vacuum is similar to SQLite's built-in VACUUM command, except ** that it can be suspended and resumed like an RBU update. ** | | | | | | > > > > > > | 164779 164780 164781 164782 164783 164784 164785 164786 164787 164788 164789 164790 164791 164792 164793 164794 164795 164796 164797 164798 164799 164800 164801 164802 164803 164804 164805 164806 164807 | ); /* ** Open an RBU handle to perform an RBU vacuum on database file zTarget. ** An RBU vacuum is similar to SQLite's built-in VACUUM command, except ** that it can be suspended and resumed like an RBU update. ** ** The second argument to this function identifies a database in which ** to store the state of the RBU vacuum operation if it is suspended. The ** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum ** operation, the state database should either not exist or be empty ** (contain no tables). If an RBU vacuum is suspended by calling ** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has ** returned SQLITE_DONE, the vacuum state is stored in the state database. ** The vacuum can be resumed by calling this function to open a new RBU ** handle specifying the same target and state databases. ** ** If the second argument passed to this function is NULL, then the ** name of the state database is "<database>-vacuum", where <database> ** is the name of the target database file. In this case, on UNIX, if the ** state database is not already present in the file-system, it is created ** with the same permissions as the target db is made. ** ** This function does not delete the state database after an RBU vacuum ** is completed, even if it created it. However, if the call to ** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents ** of the state tables within the state database are zeroed. This way, ** the next call to sqlite3rbu_vacuum() opens a handle that starts a ** new RBU vacuum operation. |
| ︙ | ︙ | |||
167253 167254 167255 167256 167257 167258 167259 |
/*
** Open the database handle and attach the RBU database as "rbu". If an
** error occurs, leave an error code and message in the RBU handle.
*/
static void rbuOpenDatabase(sqlite3rbu *p){
| < | | > > > > | 167286 167287 167288 167289 167290 167291 167292 167293 167294 167295 167296 167297 167298 167299 167300 167301 167302 167303 167304 167305 167306 167307 167308 167309 167310 167311 |
/*
** Open the database handle and attach the RBU database as "rbu". If an
** error occurs, leave an error code and message in the RBU handle.
*/
static void rbuOpenDatabase(sqlite3rbu *p){
assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
/* Open the RBU database */
p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
if( p->zState==0 ){
const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile);
}
}
/* If using separate RBU and state databases, attach the state database to
** the RBU db handle now. */
if( p->zState ){
rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState);
memcpy(p->zStateDb, "stat", 4);
|
| ︙ | ︙ | |||
168396 168397 168398 168399 168400 168401 168402 |
const char *zTarget,
const char *zRbu,
const char *zState
){
sqlite3rbu *p;
size_t nTarget = zTarget ? strlen(zTarget) : 0;
size_t nRbu = strlen(zRbu);
| < | | 168432 168433 168434 168435 168436 168437 168438 168439 168440 168441 168442 168443 168444 168445 168446 |
const char *zTarget,
const char *zRbu,
const char *zState
){
sqlite3rbu *p;
size_t nTarget = zTarget ? strlen(zTarget) : 0;
size_t nRbu = strlen(zRbu);
size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1;
p = (sqlite3rbu*)sqlite3_malloc64(nByte);
if( p ){
RbuState *pState = 0;
/* Create the custom VFS. */
memset(p, 0, sizeof(sqlite3rbu));
|
| ︙ | ︙ | |||
168419 168420 168421 168422 168423 168424 168425 |
memcpy(p->zTarget, zTarget, nTarget+1);
pCsr += nTarget+1;
}
p->zRbu = pCsr;
memcpy(p->zRbu, zRbu, nRbu+1);
pCsr += nRbu+1;
if( zState ){
| | < | 168454 168455 168456 168457 168458 168459 168460 168461 168462 168463 168464 168465 168466 168467 168468 |
memcpy(p->zTarget, zTarget, nTarget+1);
pCsr += nTarget+1;
}
p->zRbu = pCsr;
memcpy(p->zRbu, zRbu, nRbu+1);
pCsr += nRbu+1;
if( zState ){
p->zState = rbuMPrintf(p, "%s", zState);
}
rbuOpenDatabase(p);
}
if( p->rc==SQLITE_OK ){
pState = rbuLoadState(p);
assert( pState || p->rc!=SQLITE_OK );
|
| ︙ | ︙ | |||
168529 168530 168531 168532 168533 168534 168535 168536 168537 168538 168539 168540 168541 168542 168543 168544 168545 168546 168547 168548 168549 168550 168551 168552 168553 168554 168555 168556 168557 168558 168559 168560 168561 168562 |
}
rbuFreeState(pState);
}
return p;
}
/*
** Open and return a new RBU handle.
*/
SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
const char *zTarget,
const char *zRbu,
const char *zState
){
/* TODO: Check that zTarget and zRbu are non-NULL */
return openRbuHandle(zTarget, zRbu, zState);
}
/*
** Open a handle to begin or resume an RBU VACUUM operation.
*/
SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_vacuum(
const char *zTarget,
const char *zState
){
/* TODO: Check that both arguments are non-NULL */
return openRbuHandle(0, zTarget, zState);
}
/*
** Return the database handle used by pRbu.
*/
| > > > > > > > > > > > > > > > > | 168563 168564 168565 168566 168567 168568 168569 168570 168571 168572 168573 168574 168575 168576 168577 168578 168579 168580 168581 168582 168583 168584 168585 168586 168587 168588 168589 168590 168591 168592 168593 168594 168595 168596 168597 168598 168599 168600 168601 168602 168603 168604 168605 168606 168607 168608 168609 168610 168611 168612 |
}
rbuFreeState(pState);
}
return p;
}
/*
** Allocate and return an RBU handle with all fields zeroed except for the
** error code, which is set to SQLITE_MISUSE.
*/
static sqlite3rbu *rbuMisuseError(void){
sqlite3rbu *pRet;
pRet = sqlite3_malloc64(sizeof(sqlite3rbu));
if( pRet ){
memset(pRet, 0, sizeof(sqlite3rbu));
pRet->rc = SQLITE_MISUSE;
}
return pRet;
}
/*
** Open and return a new RBU handle.
*/
SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open(
const char *zTarget,
const char *zRbu,
const char *zState
){
if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
/* TODO: Check that zTarget and zRbu are non-NULL */
return openRbuHandle(zTarget, zRbu, zState);
}
/*
** Open a handle to begin or resume an RBU VACUUM operation.
*/
SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_vacuum(
const char *zTarget,
const char *zState
){
if( zTarget==0 ){ return rbuMisuseError(); }
/* TODO: Check that both arguments are non-NULL */
return openRbuHandle(0, zTarget, zState);
}
/*
** Return the database handle used by pRbu.
*/
|
| ︙ | ︙ | |||
168626 168627 168628 168629 168630 168631 168632 168633 168634 168635 168636 168637 168638 168639 |
rbuDeleteVfs(p);
sqlite3_free(p->aBuf);
sqlite3_free(p->aFrame);
rbuEditErrmsg(p);
rc = p->rc;
*pzErrmsg = p->zErrmsg;
sqlite3_free(p);
}else{
rc = SQLITE_NOMEM;
*pzErrmsg = 0;
}
return rc;
}
| > | 168676 168677 168678 168679 168680 168681 168682 168683 168684 168685 168686 168687 168688 168689 168690 |
rbuDeleteVfs(p);
sqlite3_free(p->aBuf);
sqlite3_free(p->aFrame);
rbuEditErrmsg(p);
rc = p->rc;
*pzErrmsg = p->zErrmsg;
sqlite3_free(p->zState);
sqlite3_free(p);
}else{
rc = SQLITE_NOMEM;
*pzErrmsg = 0;
}
return rc;
}
|
| ︙ | ︙ | |||
170237 170238 170239 170240 170241 170242 170243 |
pCsr->pStmt = 0;
zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master";
zSql = sqlite3_mprintf(
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
" UNION ALL "
"SELECT name, rootpage, type"
" FROM \"%w\".%s WHERE rootpage!=0"
| | | 170288 170289 170290 170291 170292 170293 170294 170295 170296 170297 170298 170299 170300 170301 170302 |
pCsr->pStmt = 0;
zMaster = pCsr->iDb==1 ? "sqlite_temp_master" : "sqlite_master";
zSql = sqlite3_mprintf(
"SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
" UNION ALL "
"SELECT name, rootpage, type"
" FROM \"%w\".%s WHERE rootpage!=0"
" ORDER BY name", pTab->db->aDb[pCsr->iDb].zDbSName, zMaster);
if( zSql==0 ){
return SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
sqlite3_free(zSql);
}
|
| ︙ | ︙ | |||
170291 170292 170293 170294 170295 170296 170297 |
break;
case 9: /* pgsize */
sqlite3_result_int(ctx, pCsr->szPage);
break;
default: { /* schema */
sqlite3 *db = sqlite3_context_db_handle(ctx);
int iDb = pCsr->iDb;
| | | 170342 170343 170344 170345 170346 170347 170348 170349 170350 170351 170352 170353 170354 170355 170356 |
break;
case 9: /* pgsize */
sqlite3_result_int(ctx, pCsr->szPage);
break;
default: { /* schema */
sqlite3 *db = sqlite3_context_db_handle(ctx);
int iDb = pCsr->iDb;
sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC);
break;
}
}
return SQLITE_OK;
}
static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
|
| ︙ | ︙ | |||
178528 178529 178530 178531 178532 178533 178534 178535 178536 178537 178538 178539 178540 178541 | static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*); static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*); static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*); static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*); static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); /* ** End of interface to code in fts5_expr.c. **************************************************************************/ | > | 178579 178580 178581 178582 178583 178584 178585 178586 178587 178588 178589 178590 178591 178592 178593 | static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*); static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*); static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*); static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*); static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*); static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); /* ** End of interface to code in fts5_expr.c. **************************************************************************/ |
| ︙ | ︙ | |||
178585 178586 178587 178588 178589 178590 178591 | #define FTS5_OR 1 #define FTS5_AND 2 #define FTS5_NOT 3 #define FTS5_TERM 4 #define FTS5_COLON 5 #define FTS5_LP 6 #define FTS5_RP 7 | > | | | | | | | 178637 178638 178639 178640 178641 178642 178643 178644 178645 178646 178647 178648 178649 178650 178651 178652 178653 178654 178655 178656 178657 | #define FTS5_OR 1 #define FTS5_AND 2 #define FTS5_NOT 3 #define FTS5_TERM 4 #define FTS5_COLON 5 #define FTS5_LP 6 #define FTS5_RP 7 #define FTS5_MINUS 8 #define FTS5_LCP 9 #define FTS5_RCP 10 #define FTS5_STRING 11 #define FTS5_COMMA 12 #define FTS5_PLUS 13 #define FTS5_STAR 14 /* ** 2000-05-29 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** |
| ︙ | ︙ | |||
178704 178705 178706 178707 178708 178709 178710 | ** fts5YY_NO_ACTION The fts5yy_action[] code for no-op */ #ifndef INTERFACE # define INTERFACE 1 #endif /************* Begin control #defines *****************************************/ #define fts5YYCODETYPE unsigned char | | | | | < | > | | | | | | | | | | | 178757 178758 178759 178760 178761 178762 178763 178764 178765 178766 178767 178768 178769 178770 178771 178772 178773 178774 178775 178776 178777 178778 178779 178780 178781 178782 178783 178784 178785 178786 178787 178788 178789 178790 178791 178792 178793 178794 178795 178796 178797 178798 178799 |
** fts5YY_NO_ACTION The fts5yy_action[] code for no-op
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/************* Begin control #defines *****************************************/
#define fts5YYCODETYPE unsigned char
#define fts5YYNOCODE 28
#define fts5YYACTIONTYPE unsigned char
#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token
typedef union {
int fts5yyinit;
sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0;
int fts5yy4;
Fts5Colset* fts5yy11;
Fts5ExprNode* fts5yy24;
Fts5ExprNearset* fts5yy46;
Fts5ExprPhrase* fts5yy53;
} fts5YYMINORTYPE;
#ifndef fts5YYSTACKDEPTH
#define fts5YYSTACKDEPTH 100
#endif
#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse;
#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse
#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse = fts5yypParser->pParse
#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse = pParse
#define fts5YYNSTATE 29
#define fts5YYNRULE 26
#define fts5YY_MAX_SHIFT 28
#define fts5YY_MIN_SHIFTREDUCE 45
#define fts5YY_MAX_SHIFTREDUCE 70
#define fts5YY_MIN_REDUCE 71
#define fts5YY_MAX_REDUCE 96
#define fts5YY_ERROR_ACTION 97
#define fts5YY_ACCEPT_ACTION 98
#define fts5YY_NO_ACTION 99
/************* End control #defines *******************************************/
/* Define the fts5yytestcase() macro to be a no-op if is not already defined
** otherwise.
**
** Applications can choose to define fts5yytestcase() in the %include section
** to a macro that can assist in verifying code coverage. For production
|
| ︙ | ︙ | |||
178764 178765 178766 178767 178768 178769 178770 | ** token onto the stack and goto state N. ** ** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then ** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE. ** ** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE ** and fts5YY_MAX_REDUCE | | | | > > | | > | < > > | | | | | | | | | | > | | | | | > | | | | | | | | | | | | | | | | | | | | | 178817 178818 178819 178820 178821 178822 178823 178824 178825 178826 178827 178828 178829 178830 178831 178832 178833 178834 178835 178836 178837 178838 178839 178840 178841 178842 178843 178844 178845 178846 178847 178848 178849 178850 178851 178852 178853 178854 178855 178856 178857 178858 178859 178860 178861 178862 178863 178864 178865 178866 178867 178868 178869 178870 178871 178872 178873 178874 178875 178876 178877 178878 178879 178880 178881 178882 178883 178884 178885 178886 178887 178888 178889 178890 178891 178892 178893 178894 178895 178896 178897 178898 178899 178900 178901 178902 178903 178904 178905 178906 178907 178908 178909 178910 178911 178912 178913 178914 |
** token onto the stack and goto state N.
**
** N between fts5YY_MIN_SHIFTREDUCE Shift to an arbitrary state then
** and fts5YY_MAX_SHIFTREDUCE reduce by rule N-fts5YY_MIN_SHIFTREDUCE.
**
** N between fts5YY_MIN_REDUCE Reduce by rule N-fts5YY_MIN_REDUCE
** and fts5YY_MAX_REDUCE
**
** N == fts5YY_ERROR_ACTION A syntax error has occurred.
**
** N == fts5YY_ACCEPT_ACTION The parser accepts its input.
**
** N == fts5YY_NO_ACTION No such action. Denotes unused
** slots in the fts5yy_action[] table.
**
** The action table is constructed as a single large table named fts5yy_action[].
** Given state S and lookahead X, the action is computed as either:
**
** (A) N = fts5yy_action[ fts5yy_shift_ofst[S] + X ]
** (B) N = fts5yy_default[S]
**
** The (A) formula is preferred. The B formula is used instead if:
** (1) The fts5yy_shift_ofst[S]+X value is out of range, or
** (2) fts5yy_lookahead[fts5yy_shift_ofst[S]+X] is not equal to X, or
** (3) fts5yy_shift_ofst[S] equal fts5YY_SHIFT_USE_DFLT.
** (Implementation note: fts5YY_SHIFT_USE_DFLT is chosen so that
** fts5YY_SHIFT_USE_DFLT+X will be out of range for all possible lookaheads X.
** Hence only tests (1) and (2) need to be evaluated.)
**
** The formulas above are for computing the action when the lookahead is
** a terminal symbol. If the lookahead is a non-terminal (as occurs after
** a reduce action) then the fts5yy_reduce_ofst[] array is used in place of
** the fts5yy_shift_ofst[] array and fts5YY_REDUCE_USE_DFLT is used in place of
** fts5YY_SHIFT_USE_DFLT.
**
** The following are the tables generated in this section:
**
** fts5yy_action[] A single table containing all actions.
** fts5yy_lookahead[] A table containing the lookahead for each entry in
** fts5yy_action. Used to detect hash collisions.
** fts5yy_shift_ofst[] For each state, the offset into fts5yy_action for
** shifting terminals.
** fts5yy_reduce_ofst[] For each state, the offset into fts5yy_action for
** shifting non-terminals after a reduce.
** fts5yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
#define fts5YY_ACTTAB_COUNT (85)
static const fts5YYACTIONTYPE fts5yy_action[] = {
/* 0 */ 98, 16, 51, 5, 53, 27, 83, 7, 26, 15,
/* 10 */ 51, 5, 53, 27, 13, 69, 26, 48, 51, 5,
/* 20 */ 53, 27, 19, 11, 26, 9, 20, 51, 5, 53,
/* 30 */ 27, 13, 22, 26, 28, 51, 5, 53, 27, 68,
/* 40 */ 1, 26, 19, 11, 17, 9, 52, 10, 53, 27,
/* 50 */ 23, 24, 26, 54, 3, 4, 2, 26, 6, 21,
/* 60 */ 49, 71, 3, 4, 2, 7, 56, 59, 55, 59,
/* 70 */ 4, 2, 12, 69, 58, 60, 18, 67, 62, 69,
/* 80 */ 25, 66, 8, 14, 2,
};
static const fts5YYCODETYPE fts5yy_lookahead[] = {
/* 0 */ 16, 17, 18, 19, 20, 21, 5, 6, 24, 17,
/* 10 */ 18, 19, 20, 21, 11, 14, 24, 17, 18, 19,
/* 20 */ 20, 21, 8, 9, 24, 11, 17, 18, 19, 20,
/* 30 */ 21, 11, 12, 24, 17, 18, 19, 20, 21, 26,
/* 40 */ 6, 24, 8, 9, 22, 11, 18, 11, 20, 21,
/* 50 */ 24, 25, 24, 20, 1, 2, 3, 24, 23, 24,
/* 60 */ 7, 0, 1, 2, 3, 6, 10, 11, 10, 11,
/* 70 */ 2, 3, 9, 14, 11, 11, 22, 26, 7, 14,
/* 80 */ 13, 11, 5, 11, 3,
};
#define fts5YY_SHIFT_USE_DFLT (85)
#define fts5YY_SHIFT_COUNT (28)
#define fts5YY_SHIFT_MIN (0)
#define fts5YY_SHIFT_MAX (81)
static const unsigned char fts5yy_shift_ofst[] = {
/* 0 */ 34, 34, 34, 34, 34, 14, 20, 3, 36, 1,
/* 10 */ 59, 64, 64, 65, 65, 53, 61, 56, 58, 63,
/* 20 */ 68, 67, 70, 67, 71, 72, 67, 77, 81,
};
#define fts5YY_REDUCE_USE_DFLT (-17)
#define fts5YY_REDUCE_COUNT (14)
#define fts5YY_REDUCE_MIN (-16)
#define fts5YY_REDUCE_MAX (54)
static const signed char fts5yy_reduce_ofst[] = {
/* 0 */ -16, -8, 0, 9, 17, 28, 26, 35, 33, 13,
/* 10 */ 13, 22, 54, 13, 51,
};
static const fts5YYACTIONTYPE fts5yy_default[] = {
/* 0 */ 97, 97, 97, 97, 97, 76, 91, 97, 97, 96,
/* 10 */ 96, 97, 97, 96, 96, 97, 97, 97, 97, 97,
/* 20 */ 73, 89, 97, 90, 97, 97, 87, 97, 72,
};
/********** End of lemon-generated parsing tables *****************************/
/* The next table maps tokens (terminal symbols) into fallback tokens.
** If a construct like the following:
**
** %fallback ID X Y Z.
|
| ︙ | ︙ | |||
178948 178949 178950 178951 178952 178953 178954 |
#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const fts5yyTokenName[] = {
"$", "OR", "AND", "NOT",
"TERM", "COLON", "LP", "RP",
| | | | | | | | > > | | | | | | | | | | | | | 179007 179008 179009 179010 179011 179012 179013 179014 179015 179016 179017 179018 179019 179020 179021 179022 179023 179024 179025 179026 179027 179028 179029 179030 179031 179032 179033 179034 179035 179036 179037 179038 179039 179040 179041 179042 179043 179044 179045 179046 179047 179048 179049 179050 179051 179052 179053 179054 179055 179056 179057 179058 |
#ifndef NDEBUG
/* For tracing shifts, the names of all terminals and nonterminals
** are required. The following table supplies these names */
static const char *const fts5yyTokenName[] = {
"$", "OR", "AND", "NOT",
"TERM", "COLON", "LP", "RP",
"MINUS", "LCP", "RCP", "STRING",
"COMMA", "PLUS", "STAR", "error",
"input", "expr", "cnearset", "exprlist",
"nearset", "colset", "colsetlist", "nearphrases",
"phrase", "neardist_opt", "star_opt",
};
#endif /* NDEBUG */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const fts5yyRuleName[] = {
/* 0 */ "input ::= expr",
/* 1 */ "expr ::= expr AND expr",
/* 2 */ "expr ::= expr OR expr",
/* 3 */ "expr ::= expr NOT expr",
/* 4 */ "expr ::= LP expr RP",
/* 5 */ "expr ::= exprlist",
/* 6 */ "exprlist ::= cnearset",
/* 7 */ "exprlist ::= exprlist cnearset",
/* 8 */ "cnearset ::= nearset",
/* 9 */ "cnearset ::= colset COLON nearset",
/* 10 */ "colset ::= MINUS LCP colsetlist RCP",
/* 11 */ "colset ::= LCP colsetlist RCP",
/* 12 */ "colset ::= STRING",
/* 13 */ "colset ::= MINUS STRING",
/* 14 */ "colsetlist ::= colsetlist STRING",
/* 15 */ "colsetlist ::= STRING",
/* 16 */ "nearset ::= phrase",
/* 17 */ "nearset ::= STRING LP nearphrases neardist_opt RP",
/* 18 */ "nearphrases ::= phrase",
/* 19 */ "nearphrases ::= nearphrases phrase",
/* 20 */ "neardist_opt ::=",
/* 21 */ "neardist_opt ::= COMMA STRING",
/* 22 */ "phrase ::= phrase PLUS STRING star_opt",
/* 23 */ "phrase ::= STRING star_opt",
/* 24 */ "star_opt ::= STAR",
/* 25 */ "star_opt ::=",
};
#endif /* NDEBUG */
#if fts5YYSTACKDEPTH<=0
/*
** Try to increase the size of the parser stack. Return the number
|
| ︙ | ︙ | |||
179093 179094 179095 179096 179097 179098 179099 |
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
| | | | | | | | | | | | | | | 179154 179155 179156 179157 179158 179159 179160 179161 179162 179163 179164 179165 179166 179167 179168 179169 179170 179171 179172 179173 179174 179175 179176 179177 179178 179179 179180 179181 179182 179183 179184 179185 179186 179187 179188 179189 179190 179191 179192 179193 179194 |
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
case 16: /* input */
{
(void)pParse;
}
break;
case 17: /* expr */
case 18: /* cnearset */
case 19: /* exprlist */
{
sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24));
}
break;
case 20: /* nearset */
case 23: /* nearphrases */
{
sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46));
}
break;
case 21: /* colset */
case 22: /* colsetlist */
{
sqlite3_free((fts5yypminor->fts5yy11));
}
break;
case 24: /* phrase */
{
sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53));
}
break;
/********* End destructor definitions *****************************************/
default: break; /* If no destructor action specified: do nothing */
}
}
|
| ︙ | ︙ | |||
179196 179197 179198 179199 179200 179201 179202 |
int i;
int stateno = pParser->fts5yytos->stateno;
if( stateno>=fts5YY_MIN_REDUCE ) return stateno;
assert( stateno <= fts5YY_SHIFT_COUNT );
do{
i = fts5yy_shift_ofst[stateno];
| < < | | | | | | | | | | | | | | | | | | | | | | | | | | < | 179257 179258 179259 179260 179261 179262 179263 179264 179265 179266 179267 179268 179269 179270 179271 179272 179273 179274 179275 179276 179277 179278 179279 179280 179281 179282 179283 179284 179285 179286 179287 179288 179289 179290 179291 179292 179293 179294 179295 179296 179297 179298 179299 179300 179301 179302 179303 179304 179305 179306 179307 179308 179309 179310 179311 |
int i;
int stateno = pParser->fts5yytos->stateno;
if( stateno>=fts5YY_MIN_REDUCE ) return stateno;
assert( stateno <= fts5YY_SHIFT_COUNT );
do{
i = fts5yy_shift_ofst[stateno];
assert( iLookAhead!=fts5YYNOCODE );
i += iLookAhead;
if( i<0 || i>=fts5YY_ACTTAB_COUNT || fts5yy_lookahead[i]!=iLookAhead ){
#ifdef fts5YYFALLBACK
fts5YYCODETYPE iFallback; /* Fallback token */
if( iLookAhead<sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])
&& (iFallback = fts5yyFallback[iLookAhead])!=0 ){
#ifndef NDEBUG
if( fts5yyTraceFILE ){
fprintf(fts5yyTraceFILE, "%sFALLBACK %s => %s\n",
fts5yyTracePrompt, fts5yyTokenName[iLookAhead], fts5yyTokenName[iFallback]);
}
#endif
assert( fts5yyFallback[iFallback]==0 ); /* Fallback loop must terminate */
iLookAhead = iFallback;
continue;
}
#endif
#ifdef fts5YYWILDCARD
{
int j = i - iLookAhead + fts5YYWILDCARD;
if(
#if fts5YY_SHIFT_MIN+fts5YYWILDCARD<0
j>=0 &&
#endif
#if fts5YY_SHIFT_MAX+fts5YYWILDCARD>=fts5YY_ACTTAB_COUNT
j<fts5YY_ACTTAB_COUNT &&
#endif
fts5yy_lookahead[j]==fts5YYWILDCARD && iLookAhead>0
){
#ifndef NDEBUG
if( fts5yyTraceFILE ){
fprintf(fts5yyTraceFILE, "%sWILDCARD %s => %s\n",
fts5yyTracePrompt, fts5yyTokenName[iLookAhead],
fts5yyTokenName[fts5YYWILDCARD]);
}
#endif /* NDEBUG */
return fts5yy_action[j];
}
}
#endif /* fts5YYWILDCARD */
return fts5yy_default[stateno];
}else{
return fts5yy_action[i];
}
}while(1);
}
|
| ︙ | ︙ | |||
179366 179367 179368 179369 179370 179371 179372 |
/* The following table contains information about every rule that
** is used during the reduce.
*/
static const struct {
fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} fts5yyRuleInfo[] = {
| | | | | | | | | | | > | | > | | | | | | | | | | | | 179424 179425 179426 179427 179428 179429 179430 179431 179432 179433 179434 179435 179436 179437 179438 179439 179440 179441 179442 179443 179444 179445 179446 179447 179448 179449 179450 179451 179452 179453 179454 179455 179456 179457 179458 179459 179460 179461 179462 179463 |
/* The following table contains information about every rule that
** is used during the reduce.
*/
static const struct {
fts5YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} fts5yyRuleInfo[] = {
{ 16, 1 },
{ 17, 3 },
{ 17, 3 },
{ 17, 3 },
{ 17, 3 },
{ 17, 1 },
{ 19, 1 },
{ 19, 2 },
{ 18, 1 },
{ 18, 3 },
{ 21, 4 },
{ 21, 3 },
{ 21, 1 },
{ 21, 2 },
{ 22, 2 },
{ 22, 1 },
{ 20, 1 },
{ 20, 5 },
{ 23, 1 },
{ 23, 2 },
{ 25, 0 },
{ 25, 2 },
{ 24, 4 },
{ 24, 2 },
{ 26, 1 },
{ 26, 0 },
};
static void fts5yy_accept(fts5yyParser*); /* Forward Declaration */
/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
|
| ︙ | ︙ | |||
179454 179455 179456 179457 179458 179459 179460 |
** { ... } // User supplied code
** #line <lineno> <thisfile>
** break;
*/
/********** Begin reduce actions **********************************************/
fts5YYMINORTYPE fts5yylhsminor;
case 0: /* input ::= expr */
| | | | | | | | | | | | | | | | | | > > > > > | | | | | | | > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 179514 179515 179516 179517 179518 179519 179520 179521 179522 179523 179524 179525 179526 179527 179528 179529 179530 179531 179532 179533 179534 179535 179536 179537 179538 179539 179540 179541 179542 179543 179544 179545 179546 179547 179548 179549 179550 179551 179552 179553 179554 179555 179556 179557 179558 179559 179560 179561 179562 179563 179564 179565 179566 179567 179568 179569 179570 179571 179572 179573 179574 179575 179576 179577 179578 179579 179580 179581 179582 179583 179584 179585 179586 179587 179588 179589 179590 179591 179592 179593 179594 179595 179596 179597 179598 179599 179600 179601 179602 179603 179604 179605 179606 179607 179608 179609 179610 179611 179612 179613 179614 179615 179616 179617 179618 179619 179620 179621 179622 179623 179624 179625 179626 179627 179628 179629 179630 179631 179632 179633 179634 179635 179636 179637 179638 179639 179640 179641 179642 179643 179644 179645 179646 179647 179648 179649 179650 179651 179652 |
** { ... } // User supplied code
** #line <lineno> <thisfile>
** break;
*/
/********** Begin reduce actions **********************************************/
fts5YYMINORTYPE fts5yylhsminor;
case 0: /* input ::= expr */
{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); }
break;
case 1: /* expr ::= expr AND expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 2: /* expr ::= expr OR expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 3: /* expr ::= expr NOT expr */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 4: /* expr ::= LP expr RP */
{fts5yymsp[-2].minor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24;}
break;
case 5: /* expr ::= exprlist */
case 6: /* exprlist ::= cnearset */ fts5yytestcase(fts5yyruleno==6);
{fts5yylhsminor.fts5yy24 = fts5yymsp[0].minor.fts5yy24;}
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 7: /* exprlist ::= exprlist cnearset */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24);
}
fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 8: /* cnearset ::= nearset */
{
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
}
fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 9: /* cnearset ::= colset COLON nearset */
{
sqlite3Fts5ParseSetColset(pParse, fts5yymsp[0].minor.fts5yy46, fts5yymsp[-2].minor.fts5yy11);
fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46);
}
fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24;
break;
case 10: /* colset ::= MINUS LCP colsetlist RCP */
{
fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
}
break;
case 11: /* colset ::= LCP colsetlist RCP */
{ fts5yymsp[-2].minor.fts5yy11 = fts5yymsp[-1].minor.fts5yy11; }
break;
case 12: /* colset ::= STRING */
{
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
}
fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
break;
case 13: /* colset ::= MINUS STRING */
{
fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11);
}
break;
case 14: /* colsetlist ::= colsetlist STRING */
{
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); }
fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
break;
case 15: /* colsetlist ::= STRING */
{
fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0);
}
fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11;
break;
case 16: /* nearset ::= phrase */
{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); }
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
case 17: /* nearset ::= STRING LP nearphrases neardist_opt RP */
{
sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0);
sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0);
fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46;
}
fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
case 18: /* nearphrases ::= phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53);
}
fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
case 19: /* nearphrases ::= nearphrases phrase */
{
fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53);
}
fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46;
break;
case 20: /* neardist_opt ::= */
{ fts5yymsp[1].minor.fts5yy0.p = 0; fts5yymsp[1].minor.fts5yy0.n = 0; }
break;
case 21: /* neardist_opt ::= COMMA STRING */
{ fts5yymsp[-1].minor.fts5yy0 = fts5yymsp[0].minor.fts5yy0; }
break;
case 22: /* phrase ::= phrase PLUS STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
case 23: /* phrase ::= STRING star_opt */
{
fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4);
}
fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53;
break;
case 24: /* star_opt ::= STAR */
{ fts5yymsp[0].minor.fts5yy4 = 1; }
break;
case 25: /* star_opt ::= */
{ fts5yymsp[1].minor.fts5yy4 = 0; }
break;
default:
break;
/********** End reduce actions ************************************************/
};
assert( fts5yyruleno<sizeof(fts5yyRuleInfo)/sizeof(fts5yyRuleInfo[0]) );
fts5yygoto = fts5yyRuleInfo[fts5yyruleno].lhs;
|
| ︙ | ︙ | |||
180025 180026 180027 180028 180029 180030 180031 |
rc = fts5CInstIterNext(&p->iter);
}
}
if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){
fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
p->iOff = iEndOff;
| | | 180096 180097 180098 180099 180100 180101 180102 180103 180104 180105 180106 180107 180108 180109 180110 |
rc = fts5CInstIterNext(&p->iter);
}
}
if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){
fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
p->iOff = iEndOff;
if( iPos>=p->iter.iStart && iPos<p->iter.iEnd ){
fts5HighlightAppend(&rc, p, p->zClose, -1);
}
}
return rc;
}
|
| ︙ | ︙ | |||
180186 180187 180188 180189 180190 180191 180192 180193 180194 180195 180196 180197 180198 180199 |
ctx.iRangeStart = iBestStart;
ctx.iRangeEnd = iBestStart + nToken - 1;
if( iBestStart>0 ){
fts5HighlightAppend(&rc, &ctx, zEllips, -1);
}
if( rc==SQLITE_OK ){
rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
}
if( ctx.iRangeEnd>=(nColSize-1) ){
fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
}else{
fts5HighlightAppend(&rc, &ctx, zEllips, -1);
| > > > > > > > | 180257 180258 180259 180260 180261 180262 180263 180264 180265 180266 180267 180268 180269 180270 180271 180272 180273 180274 180275 180276 180277 |
ctx.iRangeStart = iBestStart;
ctx.iRangeEnd = iBestStart + nToken - 1;
if( iBestStart>0 ){
fts5HighlightAppend(&rc, &ctx, zEllips, -1);
}
/* Advance iterator ctx.iter so that it points to the first coalesced
** phrase instance at or following position iBestStart. */
while( ctx.iter.iStart>=0 && ctx.iter.iStart<iBestStart && rc==SQLITE_OK ){
rc = fts5CInstIterNext(&ctx.iter);
}
if( rc==SQLITE_OK ){
rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb);
}
if( ctx.iRangeEnd>=(nColSize-1) ){
fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff);
}else{
fts5HighlightAppend(&rc, &ctx, zEllips, -1);
|
| ︙ | ︙ | |||
181921 181922 181923 181924 181925 181926 181927 181928 181929 181930 181931 181932 181933 181934 |
case ')': tok = FTS5_RP; break;
case '{': tok = FTS5_LCP; break;
case '}': tok = FTS5_RCP; break;
case ':': tok = FTS5_COLON; break;
case ',': tok = FTS5_COMMA; break;
case '+': tok = FTS5_PLUS; break;
case '*': tok = FTS5_STAR; break;
case '\0': tok = FTS5_EOF; break;
case '"': {
const char *z2;
tok = FTS5_STRING;
for(z2=&z[1]; 1; z2++){
| > | 181999 182000 182001 182002 182003 182004 182005 182006 182007 182008 182009 182010 182011 182012 182013 |
case ')': tok = FTS5_RP; break;
case '{': tok = FTS5_LCP; break;
case '}': tok = FTS5_RCP; break;
case ':': tok = FTS5_COLON; break;
case ',': tok = FTS5_COMMA; break;
case '+': tok = FTS5_PLUS; break;
case '*': tok = FTS5_STAR; break;
case '-': tok = FTS5_MINUS; break;
case '\0': tok = FTS5_EOF; break;
case '"': {
const char *z2;
tok = FTS5_STRING;
for(z2=&z[1]; 1; z2++){
|
| ︙ | ︙ | |||
183412 183413 183414 183415 183416 183417 183418 |
if( rc==SQLITE_OK ){
pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
}
if( rc==SQLITE_OK ){
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
if( pColsetOrig ){
| | | 183491 183492 183493 183494 183495 183496 183497 183498 183499 183500 183501 183502 183503 183504 183505 |
if( rc==SQLITE_OK ){
pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
}
if( rc==SQLITE_OK ){
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
if( pColsetOrig ){
int nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
if( pColset ){
memcpy(pColset, pColsetOrig, nByte);
}
pNew->pRoot->pNear->pColset = pColset;
}
}
|
| ︙ | ︙ | |||
183546 183547 183548 183549 183550 183551 183552 183553 183554 183555 183556 183557 183558 183559 |
/* Check that the array is in order and contains no duplicate entries. */
for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
#endif
}
return pNew;
}
static Fts5Colset *sqlite3Fts5ParseColset(
Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
Fts5Colset *pColset, /* Existing colset object */
Fts5Token *p
){
Fts5Colset *pRet = 0;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 183625 183626 183627 183628 183629 183630 183631 183632 183633 183634 183635 183636 183637 183638 183639 183640 183641 183642 183643 183644 183645 183646 183647 183648 183649 183650 183651 183652 183653 183654 183655 183656 183657 183658 183659 183660 183661 183662 183663 183664 183665 183666 |
/* Check that the array is in order and contains no duplicate entries. */
for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
#endif
}
return pNew;
}
/*
** Allocate and return an Fts5Colset object specifying the inverse of
** the colset passed as the second argument. Free the colset passed
** as the second argument before returning.
*/
static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){
Fts5Colset *pRet;
int nCol = pParse->pConfig->nCol;
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc,
sizeof(Fts5Colset) + sizeof(int)*nCol
);
if( pRet ){
int i;
int iOld = 0;
for(i=0; i<nCol; i++){
if( iOld>=p->nCol || p->aiCol[iOld]!=i ){
pRet->aiCol[pRet->nCol++] = i;
}else{
iOld++;
}
}
}
sqlite3_free(p);
return pRet;
}
static Fts5Colset *sqlite3Fts5ParseColset(
Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */
Fts5Colset *pColset, /* Existing colset object */
Fts5Token *p
){
Fts5Colset *pRet = 0;
|
| ︙ | ︙ | |||
185642 185643 185644 185645 185646 185647 185648 |
p->nRead++;
}
assert( (pRet==0)==(p->rc!=SQLITE_OK) );
return pRet;
}
| < > > > > > > > > > > > > | 185749 185750 185751 185752 185753 185754 185755 185756 185757 185758 185759 185760 185761 185762 185763 185764 185765 185766 185767 185768 185769 185770 185771 185772 185773 185774 185775 185776 185777 185778 185779 185780 185781 |
p->nRead++;
}
assert( (pRet==0)==(p->rc!=SQLITE_OK) );
return pRet;
}
/*
** Release a reference to data record returned by an earlier call to
** fts5DataRead().
*/
static void fts5DataRelease(Fts5Data *pData){
sqlite3_free(pData);
}
static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){
Fts5Data *pRet = fts5DataRead(p, iRowid);
if( pRet ){
if( pRet->szLeaf>pRet->nn ){
p->rc = FTS5_CORRUPT;
fts5DataRelease(pRet);
pRet = 0;
}
}
return pRet;
}
static int fts5IndexPrepareStmt(
Fts5Index *p,
sqlite3_stmt **ppStmt,
char *zSql
){
if( p->rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
186459 186460 186461 186462 186463 186464 186465 |
Fts5StructureSegment *pSeg = pIter->pSeg;
fts5DataRelease(pIter->pLeaf);
pIter->iLeafPgno++;
if( pIter->pNextLeaf ){
pIter->pLeaf = pIter->pNextLeaf;
pIter->pNextLeaf = 0;
}else if( pIter->iLeafPgno<=pSeg->pgnoLast ){
| | | 186577 186578 186579 186580 186581 186582 186583 186584 186585 186586 186587 186588 186589 186590 186591 |
Fts5StructureSegment *pSeg = pIter->pSeg;
fts5DataRelease(pIter->pLeaf);
pIter->iLeafPgno++;
if( pIter->pNextLeaf ){
pIter->pLeaf = pIter->pNextLeaf;
pIter->pNextLeaf = 0;
}else if( pIter->iLeafPgno<=pSeg->pgnoLast ){
pIter->pLeaf = fts5LeafRead(p,
FTS5_SEGMENT_ROWID(pSeg->iSegid, pIter->iLeafPgno)
);
}else{
pIter->pLeaf = 0;
}
pLeaf = pIter->pLeaf;
|
| ︙ | ︙ | |||
186962 186963 186964 186965 186966 186967 186968 |
if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOff<pLeaf->szLeaf ){
iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
if( pLeaf->nn>pLeaf->szLeaf ){
pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
&pLeaf->p[pLeaf->szLeaf], pIter->iEndofDoclist
| | < | 187080 187081 187082 187083 187084 187085 187086 187087 187088 187089 187090 187091 187092 187093 187094 187095 |
if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOff<pLeaf->szLeaf ){
iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid);
pIter->iLeafOffset = iOff;
if( pLeaf->nn>pLeaf->szLeaf ){
pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
&pLeaf->p[pLeaf->szLeaf], pIter->iEndofDoclist
);
}
}
else if( pLeaf->nn>pLeaf->szLeaf ){
pIter->iPgidxOff = pLeaf->szLeaf + fts5GetVarint32(
&pLeaf->p[pLeaf->szLeaf], iOff
);
pIter->iLeafOffset = iOff;
pIter->iEndofDoclist = iOff;
|
| ︙ | ︙ | |||
187208 187209 187210 187211 187212 187213 187214 187215 187216 187217 187218 187219 187220 187221 |
bEndOfPage = 1;
break;
}
iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
iTermOff += nKeep;
iOff = iTermOff;
/* Read the nKeep field of the next term. */
fts5FastGetVarint32(a, iOff, nKeep);
}
search_failed:
if( bGe==0 ){
| > > > > > | 187325 187326 187327 187328 187329 187330 187331 187332 187333 187334 187335 187336 187337 187338 187339 187340 187341 187342 187343 |
bEndOfPage = 1;
break;
}
iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
iTermOff += nKeep;
iOff = iTermOff;
if( iOff>=n ){
p->rc = FTS5_CORRUPT;
return;
}
/* Read the nKeep field of the next term. */
fts5FastGetVarint32(a, iOff, nKeep);
}
search_failed:
if( bGe==0 ){
|
| ︙ | ︙ | |||
188134 188135 188136 188137 188138 188139 188140 188141 188142 188143 188144 188145 188146 188147 |
** Fts5Iter.poslist buffer and then set the output pointer to point
** to this buffer. */
fts5BufferZero(&pIter->poslist);
fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
pIter->base.pData = pIter->poslist.p;
}
}
/*
** xSetOutputs callback used by detail=col when there is a column filter
** and there are 100 or more columns. Also called as a fallback from
** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
*/
static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
| > > > > > > > > > | 188256 188257 188258 188259 188260 188261 188262 188263 188264 188265 188266 188267 188268 188269 188270 188271 188272 188273 188274 188275 188276 188277 188278 |
** Fts5Iter.poslist buffer and then set the output pointer to point
** to this buffer. */
fts5BufferZero(&pIter->poslist);
fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
pIter->base.pData = pIter->poslist.p;
}
}
/*
** xSetOutputs callback used when the Fts5Colset object has nCol==0 (match
** against no columns at all).
*/
static void fts5IterSetOutputs_ZeroColset(Fts5Iter *pIter, Fts5SegIter *pSeg){
UNUSED_PARAM(pSeg);
pIter->base.nData = 0;
}
/*
** xSetOutputs callback used by detail=col when there is a column filter
** and there are 100 or more columns. Also called as a fallback from
** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
*/
static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
|
| ︙ | ︙ | |||
188239 188240 188241 188242 188243 188244 188245 188246 188247 188248 188249 188250 188251 188252 |
if( pConfig->eDetail==FTS5_DETAIL_NONE ){
pIter->xSetOutputs = fts5IterSetOutputs_None;
}
else if( pIter->pColset==0 ){
pIter->xSetOutputs = fts5IterSetOutputs_Nocolset;
}
else if( pConfig->eDetail==FTS5_DETAIL_FULL ){
pIter->xSetOutputs = fts5IterSetOutputs_Full;
}
else{
assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS );
| > > > > | 188370 188371 188372 188373 188374 188375 188376 188377 188378 188379 188380 188381 188382 188383 188384 188385 188386 188387 |
if( pConfig->eDetail==FTS5_DETAIL_NONE ){
pIter->xSetOutputs = fts5IterSetOutputs_None;
}
else if( pIter->pColset==0 ){
pIter->xSetOutputs = fts5IterSetOutputs_Nocolset;
}
else if( pIter->pColset->nCol==0 ){
pIter->xSetOutputs = fts5IterSetOutputs_ZeroColset;
}
else if( pConfig->eDetail==FTS5_DETAIL_FULL ){
pIter->xSetOutputs = fts5IterSetOutputs_Full;
}
else{
assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS );
|
| ︙ | ︙ | |||
194016 194017 194018 194019 194020 194021 194022 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 194151 194152 194153 194154 194155 194156 194157 194158 194159 194160 194161 194162 194163 194164 194165 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2016-08-20 18:06:14 9041ee4a6f0e8389297f887f1431ab5cfe783390", -1, SQLITE_TRANSIENT);
}
static int fts5Init(sqlite3 *db){
static const sqlite3_module fts5Mod = {
/* iVersion */ 2,
/* xCreate */ fts5CreateMethod,
/* xConnect */ fts5ConnectMethod,
|
| ︙ | ︙ |
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
116 117 118 119 120 121 122 | ** 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()]. */ | | | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | ** 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.15.0" #define SQLITE_VERSION_NUMBER 3015000 #define SQLITE_SOURCE_ID "2016-08-22 20:10:01 7839519349c7371cdb4e16a215eacd27004cbc62" /* ** 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 |
| ︙ | ︙ | |||
1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 | ** C-API or the SQL function. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. ** </dd> ** ** </dl> */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ | > > > > > > > > > > | 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 | ** C-API or the SQL function. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. ** </dd> ** ** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> ** <dd> ^This option is used to change the name of the "main" database ** schema. ^The sole argument is a pointer to a constant UTF8 string ** which will become the new schema name in place of "main". ^SQLite ** does not make a copy of the new main schema name string, so the application ** must ensure that the argument passed into this DBCONFIG option is unchanged ** until after the database connection closes. ** </dd> ** ** </dl> */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ |
| ︙ | ︙ |
Changes to src/stash.c.
| ︙ | ︙ | |||
21 22 23 24 25 26 27 | #include <assert.h> /* ** SQL code to implement the tables needed by the stash. */ static const char zStashInit[] = | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include <assert.h> /* ** SQL code to implement the tables needed by the stash. */ static const char zStashInit[] = @ CREATE TABLE IF NOT EXISTS localdb.stash( @ stashid INTEGER PRIMARY KEY, -- Unique stash identifier @ vid INTEGER, -- The baseline check-out for this stash @ comment TEXT, -- Comment for this stash. Or NULL @ ctime TIMESTAMP -- When the stash was created @ ); @ CREATE TABLE IF NOT EXISTS localdb.stashfile( @ stashid INTEGER REFERENCES stash, -- Stash that contains this file @ rid INTEGER, -- Baseline content in BLOB table or 0. @ isAdded BOOLEAN, -- True if this is an added file @ isRemoved BOOLEAN, -- True if this file is deleted @ isExec BOOLEAN, -- True if file is executable @ isLink BOOLEAN, -- True if file is a symlink @ origname TEXT, -- Original filename |
| ︙ | ︙ | |||
470 471 472 473 474 475 476 |
** fossil stash pop
** fossil stash apply ?STASHID?
** fossil stash goto ?STASHID?
** fossil stash rm|drop ?STASHID? ?-a|--all?
** fossil stash [g]diff ?STASHID? ?DIFF-OPTIONS?
*/
void stash_cmd(void){
| < < | | 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
** fossil stash pop
** fossil stash apply ?STASHID?
** fossil stash goto ?STASHID?
** fossil stash rm|drop ?STASHID? ?-a|--all?
** fossil stash [g]diff ?STASHID? ?DIFF-OPTIONS?
*/
void stash_cmd(void){
const char *zCmd;
int nCmd;
int stashid = 0;
undo_capture_command_line();
db_must_be_within_tree();
db_open_config(0, 0);
db_begin_transaction();
db_multi_exec(zStashInit /*works-like:""*/);
if( g.argc<=2 ){
zCmd = "save";
}else{
zCmd = g.argv[2];
}
nCmd = strlen(zCmd);
if( memcmp(zCmd, "save", nCmd)==0 ){
|
| ︙ | ︙ |
Changes to src/stat.c.
| ︙ | ︙ | |||
59 60 61 62 63 64 65 |
**
** Show statistics and global information about the repository.
*/
void stat_page(void){
i64 t, fsize;
int n, m;
int szMax, szAvg;
| < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
**
** Show statistics and global information about the repository.
*/
void stat_page(void){
i64 t, fsize;
int n, m;
int szMax, szAvg;
int brief;
char zBuf[100];
const char *p;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
brief = P("brief")!=0;
|
| ︙ | ︙ | |||
186 187 188 189 190 191 192 |
@ <tr><th>SQLite Version:</th><td>%.19s(sqlite3_sourceid())
@ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))</td></tr>
@ <tr><th>Schema Version:</th><td>%h(g.zAuxSchema)</td></tr>
@ <tr><th>Repository Rebuilt:</th><td>
@ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
@ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
@ <tr><th>Database Stats:</th><td>
| < | | | | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
@ <tr><th>SQLite Version:</th><td>%.19s(sqlite3_sourceid())
@ [%.10s(&sqlite3_sourceid()[20])] (%s(sqlite3_libversion()))</td></tr>
@ <tr><th>Schema Version:</th><td>%h(g.zAuxSchema)</td></tr>
@ <tr><th>Repository Rebuilt:</th><td>
@ %h(db_get_mtime("rebuilt","%Y-%m-%d %H:%M:%S","Never"))
@ By Fossil %h(db_get("rebuilt","Unknown"))</td></tr>
@ <tr><th>Database Stats:</th><td>
@ %d(db_int(0, "PRAGMA repository.page_count")) pages,
@ %d(db_int(0, "PRAGMA repository.page_size")) bytes/page,
@ %d(db_int(0, "PRAGMA repository.freelist_count")) free pages,
@ %s(db_text(0, "PRAGMA repository.encoding")),
@ %s(db_text(0, "PRAGMA repository.journal_mode")) mode
@ </td></tr>
@ </table>
style_footer();
}
/*
|
| ︙ | ︙ | |||
215 216 217 218 219 220 221 |
** --db-check Run a PRAGMA quick_check on the repository database
** --omit-version-info Omit the SQLite and Fossil version information
*/
void dbstat_cmd(void){
i64 t, fsize;
int n, m;
int szMax, szAvg;
| < | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
** --db-check Run a PRAGMA quick_check on the repository database
** --omit-version-info Omit the SQLite and Fossil version information
*/
void dbstat_cmd(void){
i64 t, fsize;
int n, m;
int szMax, szAvg;
int brief;
int omitVers; /* Omit Fossil and SQLite version information */
int dbCheck; /* True for the --db-check option */
char zBuf[100];
const int colWidth = -19 /* printf alignment/width for left column */;
const char *p, *z;
|
| ︙ | ︙ | |||
314 315 316 317 318 319 320 |
MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
COMPILER_NAME);
fossil_print("%*s%.19s [%.10s] (%s)\n",
colWidth, "sqlite-version:",
sqlite3_sourceid(), &sqlite3_sourceid()[20],
sqlite3_libversion());
}
| < | | | | | | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
COMPILER_NAME);
fossil_print("%*s%.19s [%.10s] (%s)\n",
colWidth, "sqlite-version:",
sqlite3_sourceid(), &sqlite3_sourceid()[20],
sqlite3_libversion());
}
fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
"%s, %s mode\n",
colWidth, "database-stats:",
db_int(0, "PRAGMA repository.page_count"),
db_int(0, "PRAGMA repository.page_size"),
db_int(0, "PRAGMA repository.freelist_count"),
db_text(0, "PRAGMA repository.encoding"),
db_text(0, "PRAGMA repository.journal_mode"));
if( dbCheck ){
fossil_print("%*s%s\n", colWidth, "database-check:",
db_text(0, "PRAGMA quick_check(1)"));
}
}
/*
|
| ︙ | ︙ | |||
394 395 396 397 398 399 400 |
style_header("Repository Schema");
style_adunit_config(ADUNIT_RIGHT_OK);
style_submenu_element("Stat", "Repository Stats", "stat");
style_submenu_element("URLs", "URLs and Checkouts", "urllist");
if( sqlite3_compileoption_used("ENABLE_DBSTAT_VTAB") ){
style_submenu_element("Table Sizes", 0, "repo-tabsize");
}
| | | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
style_header("Repository Schema");
style_adunit_config(ADUNIT_RIGHT_OK);
style_submenu_element("Stat", "Repository Stats", "stat");
style_submenu_element("URLs", "URLs and Checkouts", "urllist");
if( sqlite3_compileoption_used("ENABLE_DBSTAT_VTAB") ){
style_submenu_element("Table Sizes", 0, "repo-tabsize");
}
db_prepare(&q,
"SELECT sql FROM repository.sqlite_master WHERE sql IS NOT NULL");
@ <pre>
while( db_step(&q)==SQLITE_ROW ){
@ %h(db_column_text(&q, 0));
}
@ </pre>
db_finalize(&q);
style_footer();
|
| ︙ | ︙ | |||
424 425 426 427 428 429 430 |
style_header("Repository Table Sizes");
style_adunit_config(ADUNIT_RIGHT_OK);
style_submenu_element("Stat", "Repository Stats", "stat");
if( g.perm.Admin ){
style_submenu_element("Schema", "Repository Schema", "repo_schema");
}
db_multi_exec(
| | | | < | | | | < | | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 |
style_header("Repository Table Sizes");
style_adunit_config(ADUNIT_RIGHT_OK);
style_submenu_element("Stat", "Repository Stats", "stat");
if( g.perm.Admin ){
style_submenu_element("Schema", "Repository Schema", "repo_schema");
}
db_multi_exec(
"CREATE VIRTUAL TABLE temp.dbx USING dbstat(repository);"
"CREATE TEMP TABLE trans(name TEXT PRIMARY KEY,tabname TEXT)WITHOUT ROWID;"
"INSERT INTO trans(name,tabname)"
" SELECT name, tbl_name FROM repository.sqlite_master;"
"CREATE TEMP TABLE piechart(amt REAL, label TEXT);"
"INSERT INTO piechart(amt,label)"
" SELECT count(*), "
" coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
" FROM dbx"
" GROUP BY 2 ORDER BY 2;"
);
nPageFree = db_int(0, "PRAGMA repository.freelist_count");
if( nPageFree>0 ){
db_multi_exec(
"INSERT INTO piechart(amt,label) VALUES(%d,'freelist')",
nPageFree
);
}
fsize = file_size(g.zRepositoryName);
approxSizeName(sizeof(zBuf), zBuf, fsize);
@ <h2>Repository Size: %s(zBuf)</h2>
@ <center><svg width='800' height='500'>
piechart_render(800,500,PIE_OTHER|PIE_PERCENT);
@ </svg></center>
if( g.localOpen ){
db_multi_exec(
"DROP TABLE temp.dbx;"
"CREATE VIRTUAL TABLE temp.dbx USING dbstat(localdb);"
"DELETE FROM trans;"
"INSERT INTO trans(name,tabname)"
" SELECT name, tbl_name FROM localdb.sqlite_master;"
"DELETE FROM piechart;"
"INSERT INTO piechart(amt,label)"
" SELECT count(*), "
" coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
" FROM dbx"
" GROUP BY 2 ORDER BY 2;"
);
nPageFree = db_int(0, "PRAGMA localdb.freelist_count");
if( nPageFree>0 ){
db_multi_exec(
"INSERT INTO piechart(amt,label) VALUES(%d,'freelist')",
nPageFree
);
}
fsize = file_size(g.zLocalDbName);
|
| ︙ | ︙ |
Changes to src/undo.c.
| ︙ | ︙ | |||
223 224 225 226 227 228 229 |
}
/*
** Begin capturing a snapshot that can be undone.
*/
void undo_begin(void){
int cid;
| < | | | | | 223 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 250 251 |
}
/*
** Begin capturing a snapshot that can be undone.
*/
void undo_begin(void){
int cid;
static const char zSql[] =
@ CREATE TABLE localdb.undo(
@ pathname TEXT UNIQUE, -- Name of the file
@ redoflag BOOLEAN, -- 0 for undoable. 1 for redoable
@ existsflag BOOLEAN, -- True if the file exists
@ isExe BOOLEAN, -- True if the file is executable
@ isLink BOOLEAN, -- True if the file is symlink
@ content BLOB -- Saved content
@ );
@ CREATE TABLE localdb.undo_vfile AS SELECT * FROM vfile;
@ CREATE TABLE localdb.undo_vmerge AS SELECT * FROM vmerge;
;
if( undoDisable ) return;
undo_reset();
db_multi_exec(zSql/*works-like:""*/);
cid = db_lget_int("checkout", 0);
db_lset_int("undo_checkout", cid);
db_lset_int("undo_available", 1);
db_lset("undo_cmdline", undoCmd);
undoActive = 1;
}
|
| ︙ | ︙ | |||
375 376 377 378 379 380 381 |
return zRc;
}
/*
** Make the current state of stashid undoable.
*/
void undo_save_stash(int stashid){
| < | | | | | 374 375 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 |
return zRc;
}
/*
** Make the current state of stashid undoable.
*/
void undo_save_stash(int stashid){
db_multi_exec(
"CREATE TABLE IF NOT EXISTS localdb.undo_stash"
" AS SELECT * FROM stash WHERE 0;"
"INSERT INTO undo_stash"
" SELECT * FROM stash WHERE stashid=%d;",
stashid
);
db_multi_exec(
"CREATE TABLE IF NOT EXISTS localdb.undo_stashfile"
" AS SELECT * FROM stashfile WHERE 0;"
"INSERT INTO undo_stashfile"
" SELECT * FROM stashfile WHERE stashid=%d;",
stashid
);
}
/*
** Complete the undo process is one is currently in process.
*/
void undo_finish(void){
|
| ︙ | ︙ |
Changes to src/unversioned.c.
| ︙ | ︙ | |||
28 29 30 31 32 33 34 | #include "unversioned.h" #include <time.h> /* ** SQL code to implement the tables needed by the unversioned. */ static const char zUnversionedInit[] = | | | | 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 |
#include "unversioned.h"
#include <time.h>
/*
** SQL code to implement the tables needed by the unversioned.
*/
static const char zUnversionedInit[] =
@ CREATE TABLE IF NOT EXISTS repository.unversioned(
@ name TEXT PRIMARY KEY, -- Name of the uv file
@ rcvid INTEGER, -- Where received from
@ mtime DATETIME, -- timestamp. Seconds since 1970.
@ hash TEXT, -- Content hash. NULL if a delete marker
@ sz INTEGER, -- size of content after decompression
@ encoding INT, -- 0: plaintext. 1: zlib compressed
@ content BLOB -- content of the file. NULL if oversized
@ ) WITHOUT ROWID;
;
/*
** Make sure the unversioned table exists in the repository.
*/
void unversioned_schema(void){
if( !db_table_exists("repository", "unversioned") ){
db_multi_exec(zUnversionedInit/*works-like:""*/);
}
}
/*
** Return a string which is the hash of the unversioned content.
** This is the hash used by repositories to compare content before
** exchanging a catalog. So all repositories must compute this hash
|
| ︙ | ︙ |