Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Use the new SQLITE_DBCONFIG_MAINDBNAME feature of SQLite to eliminate the need for the db_name() hack. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | omit-db_name |
| Files: | files | file ages | folders |
| SHA1: |
d858f3da52969aab1f881d517519ffe6 |
| User & Date: | drh 2016-08-19 00:13:01.436 |
Context
|
2016-08-19
| ||
| 09:14 | Clarification of comments on the db_set_main_schemaname() routine. check-in: 81184a02a5 user: drh tags: omit-db_name | |
| 00:13 | Use the new SQLITE_DBCONFIG_MAINDBNAME feature of SQLite to eliminate the need for the db_name() hack. check-in: d858f3da52 user: drh tags: omit-db_name | |
|
2016-08-18
| ||
| 19:16 | Fix typos in the Unversioned Content document. check-in: 1a7656469a user: drh tags: trunk | |
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 |
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 from "main" to zLabel.
** zLabel must be a static string that is unchanged for the life of
** the database connection.
*/
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.");
}
}
/*
** 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);
}
}
/*
** 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;
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;
}
/*
** 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 ){
| | < < | | < | | < | | | | | | | 1099 1100 1101 1102 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 |
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);
| | | | | < | 1308 1309 1310 1311 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 |
#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");
}
}
}
| < < < < < < < < < < < < | | 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 |
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;
}
| | | 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 |
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);
}
/*
|
| ︙ | ︙ | |||
1504 1505 1506 1507 1508 1509 1510 | db_end_transaction(1); pStmt = 0; db_close_config(); /* If the localdb (the check-out database) is open and if it has ** a lot of unused free space, then VACUUM it as we shut down. */ | | | | > < < < | 1511 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 |
db_end_transaction(1);
pStmt = 0;
db_close_config();
/* If the localdb (the check-out database) is open and if it 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 ){
sqlite3_db_config(g.db, SQLITE_DBCONFIG_MAINDBNAME, "main");
db_multi_exec("VACUUM;");
}
}
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;
| < < < | 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 |
** 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++){
| | | 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 |
*/
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(
| | | | 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 |
** 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); |
| ︙ | ︙ | |||
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");
| < | | | | | | 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 |
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-18 22:44:22 d6e3d5796c9991ca0af45ed92ce36f55efc02348" /* ** 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) */
};
/*
|
| ︙ | ︙ | |||
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 );
|
| ︙ | ︙ | |||
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;
| | | 83974 83975 83976 83977 83978 83979 83980 83981 83982 83983 83984 83985 83986 83987 83988 |
}
#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;
| | | 84310 84311 84312 84313 84314 84315 84316 84317 84318 84319 84320 84321 84322 84323 84324 |
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);
| < | | | | | | | | < | | 87862 87863 87864 87865 87866 87867 87868 87869 87870 87871 87872 87873 87874 87875 87876 87877 87878 87879 87880 87881 87882 87883 87884 |
** 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++){
| | | | 88204 88205 88206 88207 88208 88209 88210 88211 88212 88213 88214 88215 88216 88217 88218 88219 |
/* 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); | | | 94278 94279 94280 94281 94282 94283 94284 94285 94286 94287 94288 94289 94290 94291 94292 | 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); | | | 94476 94477 94478 94479 94480 94481 94482 94483 94484 94485 94486 94487 94488 94489 94490 | 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;
| | | | | 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 94922 |
/* 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, | | | 95670 95671 95672 95673 95674 95675 95676 95677 95678 95679 95680 95681 95682 95683 95684 |
}
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 ){
| | | 96060 96061 96062 96063 96064 96065 96066 96067 96068 96069 96070 96071 96072 96073 96074 |
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;
| | | 96520 96521 96522 96523 96524 96525 96526 96527 96528 96529 96530 96531 96532 96533 96534 |
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++){
| | | 96663 96664 96665 96666 96667 96668 96669 96670 96671 96672 96673 96674 96675 96676 96677 |
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;
| | | | 96728 96729 96730 96731 96732 96733 96734 96735 96736 96737 96738 96739 96740 96741 96742 96743 |
#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;
| | | 96841 96842 96843 96844 96845 96846 96847 96848 96849 96850 96851 96852 96853 96854 96855 |
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;
| | | 96999 97000 97001 97002 97003 97004 97005 97006 97007 97008 97009 97010 97011 97012 97013 |
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. */
){
| | | | | 97257 97258 97259 97260 97261 97262 97263 97264 97265 97266 97267 97268 97269 97270 97271 97272 97273 |
*/
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 */
| | | | | > | 97732 97733 97734 97735 97736 97737 97738 97739 97740 97741 97742 97743 97744 97745 97746 97747 97748 97749 97750 |
** 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);
| | | 97810 97811 97812 97813 97814 97815 97816 97817 97818 97819 97820 97821 97822 97823 97824 |
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 );
| | | 97838 97839 97840 97841 97842 97843 97844 97845 97846 97847 97848 97849 97850 97851 97852 |
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 ){
| | | | 97907 97908 97909 97910 97911 97912 97913 97914 97915 97916 97917 97918 97919 97920 97921 97922 |
** 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--){
| | | 98128 98129 98130 98131 98132 98133 98134 98135 98136 98137 98138 98139 98140 98141 98142 |
** -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
|
| ︙ | ︙ | |||
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
};
| | | | 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 98331 |
{
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",
| | | | 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 99445 |
** 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 ){
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",
| | | 99745 99746 99747 99748 99749 99750 99751 99752 99753 99754 99755 99756 99757 99758 99759 |
**
** 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;
| | | 99821 99822 99823 99824 99825 99826 99827 99828 99829 99830 99831 99832 99833 99834 99835 |
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",
| | | | 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 99902 |
** 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);
| | | 99942 99943 99944 99945 99946 99947 99948 99949 99950 99951 99952 99953 99954 99955 99956 |
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, | | | 100183 100184 100185 100186 100187 100188 100189 100190 100191 100192 100193 100194 100195 100196 100197 |
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;
}
}
| | | 100435 100436 100437 100438 100439 100440 100441 100442 100443 100444 100445 100446 100447 100448 100449 |
}
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
{
| | | 100465 100466 100467 100468 100469 100470 100471 100472 100473 100474 100475 100476 100477 100478 100479 |
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);",
| | | 100780 100781 100782 100783 100784 100785 100786 100787 100788 100789 100790 100791 100792 100793 100794 |
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;
| | | | 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 100946 |
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];
| | | 101477 101478 101479 101480 101481 101482 101483 101484 101485 101486 101487 101488 101489 101490 101491 |
** 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;
| | | 101724 101725 101726 101727 101728 101729 101730 101731 101732 101733 101734 101735 101736 101737 101738 |
}
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);
| | | 102438 102439 102440 102441 102442 102443 102444 102445 102446 102447 102448 102449 102450 102451 102452 |
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 );
| | | 102625 102626 102627 102628 102629 102630 102631 102632 102633 102634 102635 102636 102637 102638 102639 |
}
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); | | | 105957 105958 105959 105960 105961 105962 105963 105964 105965 105966 105967 105968 105969 105970 105971 |
/* 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;
|
| ︙ | ︙ | |||
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];
| | | 107044 107045 107046 107047 107048 107049 107050 107051 107052 107053 107054 107055 107056 107057 107058 |
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 );
| | | 111002 111003 111004 111005 111006 111007 111008 111009 111010 111011 111012 111013 111014 111015 111016 |
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;
| | | | 111855 111856 111857 111858 111859 111860 111861 111862 111863 111864 111865 111866 111867 111868 111869 111870 111871 111872 |
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,
| | | 112147 112148 112149 112150 112151 112152 112153 112154 112155 112156 112157 112158 112159 112160 112161 |
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;
| | | | | 112586 112587 112588 112589 112590 112591 112592 112593 112594 112595 112596 112597 112598 112599 112600 112601 112602 112603 112604 112605 112606 112607 112608 |
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
|
| ︙ | ︙ | |||
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;
| | | 112764 112765 112766 112767 112768 112769 112770 112771 112772 112773 112774 112775 112776 112777 112778 |
/* 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",
| | | 112943 112944 112945 112946 112947 112948 112949 112950 112951 112952 112953 112954 112955 112956 112957 |
/* 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 ){
| | | 113218 113219 113220 113221 113222 113223 113224 113225 113226 113227 113228 113229 113230 113231 113232 |
*/
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);
| | | 114974 114975 114976 114977 114978 114979 114980 114981 114982 114983 114984 114985 114986 114987 114988 |
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);
| | | 117930 117931 117932 117933 117934 117935 117936 117937 117938 117939 117940 117941 117942 117943 117944 |
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;
| | | | 119642 119643 119644 119645 119646 119647 119648 119649 119650 119651 119652 119653 119654 119655 119656 119657 |
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')",
| | | 119737 119738 119739 119740 119741 119742 119743 119744 119745 119746 119747 119748 119749 119750 119751 |
/* 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 */
| | | 119926 119927 119928 119929 119930 119931 119932 119933 119934 119935 119936 119937 119938 119939 119940 |
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;
| | | | 119972 119973 119974 119975 119976 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 |
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 );
| > > | | 120091 120092 120093 120094 120095 120096 120097 120098 120099 120100 120101 120102 120103 120104 120105 120106 120107 120108 |
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,
| | | 120781 120782 120783 120784 120785 120786 120787 120788 120789 120790 120791 120792 120793 120794 120795 |
}
}
#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
|
| ︙ | ︙ | |||
121504 121505 121506 121507 121508 121509 121510 |
zSql = "ATTACH ':memory:' AS vacuum_db;";
}else{
zSql = "ATTACH '' AS vacuum_db;";
}
rc = execSql(db, pzErrMsg, zSql);
if( db->nDb>nDb ){
pDb = &db->aDb[db->nDb-1];
| | | 121538 121539 121540 121541 121542 121543 121544 121545 121546 121547 121548 121549 121550 121551 121552 |
zSql = "ATTACH ':memory:' AS vacuum_db;";
}else{
zSql = "ATTACH '' AS vacuum_db;";
}
rc = execSql(db, pzErrMsg, zSql);
if( db->nDb>nDb ){
pDb = &db->aDb[db->nDb-1];
assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
}
if( rc!=SQLITE_OK ) goto end_of_vacuum;
pTemp = db->aDb[db->nDb-1].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
|
| ︙ | ︙ | |||
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,
| | | 122087 122088 122089 122090 122091 122092 122093 122094 122095 122096 122097 122098 122099 122100 122101 |
/* 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",
| | | 122151 122152 122153 122154 122155 122156 122157 122158 122159 122160 122161 122162 122163 122164 122165 |
** 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);
| | | 122261 122262 122263 122264 122265 122266 122267 122268 122269 122270 122271 122272 122273 122274 122275 |
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;
| | | 122425 122426 122427 122428 122429 122430 122431 122432 122433 122434 122435 122436 122437 122438 122439 |
*/
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;
| | | 122549 122550 122551 122552 122553 122554 122555 122556 122557 122558 122559 122560 122561 122562 122563 |
**
** 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 */
){
| | | 125662 125663 125664 125665 125666 125667 125668 125669 125670 125671 125672 125673 125674 125675 125676 |
**
** 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){
| | > | | 126647 126648 126649 126650 126651 126652 126653 126654 126655 126656 126657 126658 126659 126660 126661 126662 126663 126664 126665 126666 126667 126668 |
/*
** 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 | | | | > > | | | < > > > | | 131901 131902 131903 131904 131905 131906 131907 131908 131909 131910 131911 131912 131913 131914 131915 131916 131917 131918 131919 131920 131921 131922 131923 131924 131925 131926 131927 131928 131929 131930 131931 131932 131933 131934 131935 131936 131937 | ** 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, }; | | | | | | | | | | | 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 132280 132281 132282 132283 132284 132285 132286 132287 132288 132289 132290 132291 132292 132293 132294 132295 132296 132297 132298 |
/* 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];
| < < | | | | | | | | | | | | | | | | | | | | | | | | | | < | 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 133273 133274 133275 133276 133277 133278 133279 133280 133281 133282 133283 133284 133285 133286 133287 133288 133289 133290 133291 |
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);
}
|
| ︙ | ︙ | |||
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 );
| | > | | | | | | > > > > > > > > > > > < < < < < < < < < | 136040 136041 136042 136043 136044 136045 136046 136047 136048 136049 136050 136051 136052 136053 136054 136055 136056 136057 136058 136059 136060 136061 136062 136063 136064 136065 136066 136067 136068 136069 136070 136071 136072 136073 136074 136075 136076 136077 136078 136079 136080 136081 136082 136083 136084 136085 136086 136087 136088 136089 136090 136091 136092 136093 |
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;
}
| > > > > > | 137319 137320 137321 137322 137323 137324 137325 137326 137327 137328 137329 137330 137331 137332 137333 137334 137335 137336 137337 |
** 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. */ | | | | 139467 139468 139469 139470 139471 139472 139473 139474 139475 139476 139477 139478 139479 139480 139481 139482 139483 |
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
| | | 140430 140431 140432 140433 140434 140435 140436 140437 140438 140439 140440 140441 140442 140443 140444 |
/*
** 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. ** | | | | | | > > > > > > | 164796 164797 164798 164799 164800 164801 164802 164803 164804 164805 164806 164807 164808 164809 164810 164811 164812 164813 164814 164815 164816 164817 164818 164819 164820 164821 164822 164823 164824 | ); /* ** 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){
| < | | > > > > | 167303 167304 167305 167306 167307 167308 167309 167310 167311 167312 167313 167314 167315 167316 167317 167318 167319 167320 167321 167322 167323 167324 167325 167326 167327 167328 |
/*
** 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);
| < | | 168449 168450 168451 168452 168453 168454 168455 168456 168457 168458 168459 168460 168461 168462 168463 |
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 ){
| | < | 168471 168472 168473 168474 168475 168476 168477 168478 168479 168480 168481 168482 168483 168484 168485 |
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.
*/
| > > > > > > > > > > > > > > > > | 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 168613 168614 168615 168616 168617 168618 168619 168620 168621 168622 168623 168624 168625 168626 168627 168628 168629 |
}
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;
}
| > | 168693 168694 168695 168696 168697 168698 168699 168700 168701 168702 168703 168704 168705 168706 168707 |
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"
| | | 170305 170306 170307 170308 170309 170310 170311 170312 170313 170314 170315 170316 170317 170318 170319 |
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;
| | | 170359 170360 170361 170362 170363 170364 170365 170366 170367 170368 170369 170370 170371 170372 170373 |
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. **************************************************************************/ | > | 178596 178597 178598 178599 178600 178601 178602 178603 178604 178605 178606 178607 178608 178609 178610 | 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 | > | | | | | | | 178654 178655 178656 178657 178658 178659 178660 178661 178662 178663 178664 178665 178666 178667 178668 178669 178670 178671 178672 178673 178674 | #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 | | | | | < | > | | | | | | | | | | | 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 178800 178801 178802 178803 178804 178805 178806 178807 178808 178809 178810 178811 178812 178813 178814 178815 178816 |
** 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 | | | | > > | | > | < > > | | | | | | | | | | > | | | | | > | | | | | | | | | | | | | | | | | | | | | 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 178915 178916 178917 178918 178919 178920 178921 178922 178923 178924 178925 178926 178927 178928 178929 178930 178931 |
** 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",
| | | | | | | | > > | | | | | | | | | | | | | 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 179059 179060 179061 179062 179063 179064 179065 179066 179067 179068 179069 179070 179071 179072 179073 179074 179075 |
#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 ***************************************/
| | | | | | | | | | | | | | | 179171 179172 179173 179174 179175 179176 179177 179178 179179 179180 179181 179182 179183 179184 179185 179186 179187 179188 179189 179190 179191 179192 179193 179194 179195 179196 179197 179198 179199 179200 179201 179202 179203 179204 179205 179206 179207 179208 179209 179210 179211 |
** 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];
| < < | | | | | | | | | | | | | | | | | | | | | | | | | | < | 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 179312 179313 179314 179315 179316 179317 179318 179319 179320 179321 179322 179323 179324 179325 179326 179327 179328 |
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[] = {
| | | | | | | | | | | > | | > | | | | | | | | | | | | 179441 179442 179443 179444 179445 179446 179447 179448 179449 179450 179451 179452 179453 179454 179455 179456 179457 179458 179459 179460 179461 179462 179463 179464 179465 179466 179467 179468 179469 179470 179471 179472 179473 179474 179475 179476 179477 179478 179479 179480 |
/* 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 */
| | | | | | | | | | | | | | | | | | > > > > > | | | | | | | > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 179653 179654 179655 179656 179657 179658 179659 179660 179661 179662 179663 179664 179665 179666 179667 179668 179669 |
** { ... } // 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;
| | | 180113 180114 180115 180116 180117 180118 180119 180120 180121 180122 180123 180124 180125 180126 180127 |
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);
| > > > > > > > | 180274 180275 180276 180277 180278 180279 180280 180281 180282 180283 180284 180285 180286 180287 180288 180289 180290 180291 180292 180293 180294 |
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++){
| > | 182016 182017 182018 182019 182020 182021 182022 182023 182024 182025 182026 182027 182028 182029 182030 |
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 ){
| | | 183508 183509 183510 183511 183512 183513 183514 183515 183516 183517 183518 183519 183520 183521 183522 |
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;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 183667 183668 183669 183670 183671 183672 183673 183674 183675 183676 183677 183678 183679 183680 183681 183682 183683 |
/* 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;
}
| < > > > > > > > > > > > > | 185766 185767 185768 185769 185770 185771 185772 185773 185774 185775 185776 185777 185778 185779 185780 185781 185782 185783 185784 185785 185786 185787 185788 185789 185790 185791 185792 185793 185794 185795 185796 185797 185798 |
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 ){
| | | 186594 186595 186596 186597 186598 186599 186600 186601 186602 186603 186604 186605 186606 186607 186608 |
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
| | < | 187097 187098 187099 187100 187101 187102 187103 187104 187105 187106 187107 187108 187109 187110 187111 187112 |
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 ){
| > > > > > | 187342 187343 187344 187345 187346 187347 187348 187349 187350 187351 187352 187353 187354 187355 187356 187357 187358 187359 187360 |
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){
| > > > > > > > > > | 188273 188274 188275 188276 188277 188278 188279 188280 188281 188282 188283 188284 188285 188286 188287 188288 188289 188290 188291 188292 188293 188294 188295 |
** 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 );
| > > > > | 188387 188388 188389 188390 188391 188392 188393 188394 188395 188396 188397 188398 188399 188400 188401 188402 188403 188404 |
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);
| | | 194168 194169 194170 194171 194172 194173 194174 194175 194176 194177 194178 194179 194180 194181 194182 |
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-18 15:21:16 4768a1066cb9c7627064d7efec44188d6755cb03", -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-18 22:44:22 d6e3d5796c9991ca0af45ed92ce36f55efc02348" /* ** 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
|
| ︙ | ︙ |