1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Provide "sqlite_schema" as an alternative name to the table that holds the

database schema.

FossilOrigin-Name: 61782a7ae3c25cf59d7a676cb295eb024d17c46e532ae78c6fe871a91d712fa9
This commit is contained in:
drh
2020-06-15 20:27:35 +00:00
parent 999429882e
commit 346a70ca1e
13 changed files with 127 additions and 89 deletions

View File

@ -1,17 +1,22 @@
B fd5abb1a7b5a55127d5c0d5ff448020d8bccab44e4f5afe1eb88fc19578af735 B fd5abb1a7b5a55127d5c0d5ff448020d8bccab44e4f5afe1eb88fc19578af735
C Fix\sthe\sCLI\sso\sthat\sinterrupts\swork\sin\scolumnar\soutput\smode. C Provide\s"sqlite_schema"\sas\san\salternative\sname\sto\sthe\stable\sthat\sholds\sthe\ndatabase\sschema.
D 2020-06-15T20:05:37.857 D 2020-06-15T20:27:35.935
F configure f594931bd7b23dad12db96b81e1dba43b41b30a4560d6eb008014e3d9f1617e8 x F configure f594931bd7b23dad12db96b81e1dba43b41b30a4560d6eb008014e3d9f1617e8 x
F configure.ac 13e4ecf89214c3aa0ba099a9e0178f13f03261ace627126737d8cee240ec5c1c F configure.ac 13e4ecf89214c3aa0ba099a9e0178f13f03261ace627126737d8cee240ec5c1c
F ext/fts3/fts3.c acc51e4378dd772251b31ead0ccd19070fc1774f6f6a55b11e00cb885e0f34bc F ext/fts3/fts3.c acc51e4378dd772251b31ead0ccd19070fc1774f6f6a55b11e00cb885e0f34bc
F src/btree.c fabc215bd1ebab0e48108e95e0f50531da9883156b95888f479f6c696db032ad F src/alter.c b8ffe4acd48b4fe793d01901f28fd4f3b037854a0e99f0c977738556c31b9d2b
F src/btree.c f3a4479b0dba3a59a1d156d973be41fc1ccb3dbdb69151c4c62a791d86c9ffe2
F src/build.c 8245e69aa1a2f8b67e76203fdbaa9f88deccd89b5ed41f7097c202b920484fd0
F src/expr.c 36bb737d2ca78ee9bd4fde46cf1e51a37e7e1b263e55fccfaef32922a19e9524 F src/expr.c 36bb737d2ca78ee9bd4fde46cf1e51a37e7e1b263e55fccfaef32922a19e9524
F src/global.c 0409ae635839e0bef26a69b68be64126ab6cba62ac19bd7694f1652e591c4c17 F src/global.c 0409ae635839e0bef26a69b68be64126ab6cba62ac19bd7694f1652e591c4c17
F src/select.c 6ddd86a7272ff1f443bd9efcbb0f5ab590674d4c732e4cb8c3d5dd8e3a70cae6 F src/select.c 6ddd86a7272ff1f443bd9efcbb0f5ab590674d4c732e4cb8c3d5dd8e3a70cae6
F src/shell.c.in 0e439519aae3c08cac2c0da84bc5899bbea4d5f273d3e970febb9bf7516d680b F src/shell.c.in c27ee0cd27e17db69257597f927301532a9f019445e3526828c78d348b6f0786
F src/sqliteInt.h abf448e9f839964086d5508ba795e948dbf36d773b6568cf4c830f6c7ad2110e F src/sqliteInt.h 0a13c93b250270c5876da65c21963eaca60c5fc55271c313d5f6cf20547134af
F src/test1.c e9f68f157f8fd027ee4c32c4b427f4eed274749bfb745427e2d954fa89d95ad3 F src/test1.c e9f68f157f8fd027ee4c32c4b427f4eed274749bfb745427e2d954fa89d95ad3
F src/vdbe.c 2f5cdcd66be9bc1d1c6ca23b4a4ae003a5a36cf9830d9fa160efce66d9161c9d F src/trigger.c 6b1472e6b5bbca71e13f95c61ebcd0b255450352de8254a42c40222020b7ac43
F src/vacuum.c b196258ea36cfed5f455f18519345613bab04daf0e038a63ee715407c5a7ae9e
F src/vdbe.c 985f92b5131d62654c3c26062a2e55b1c8f71c2e10497e23021c6650d5c392b3
F src/vtab.c 33ecf1d8b0fd1508fe23be9da40e48909c86a13db2725e273177eb47db2fc265
F src/window.c 88a63e6948ea924b3cf9ad8aff5ea1fa53bebdb2f13340867205fda16ed0f19c F src/window.c 88a63e6948ea924b3cf9ad8aff5ea1fa53bebdb2f13340867205fda16ed0f19c
F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0 F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0
F test/fts3corrupt4.test e77b06926348eb45b71569f9dc45e5b19c984ca1b1ef6671367f4ca9d6eaa973 F test/fts3corrupt4.test e77b06926348eb45b71569f9dc45e5b19c984ca1b1ef6671367f4ca9d6eaa973
@ -19,9 +24,11 @@ F test/fuzzdata8.db b87ae726c84c3f80d457642d7650724a76eb3d7b76258959d712cc4d926d
F test/istrue.test 06f92ea38750fa74df7dbbe6920205251c2310861fbbe23a3adfa918a2e2ba74 F test/istrue.test 06f92ea38750fa74df7dbbe6920205251c2310861fbbe23a3adfa918a2e2ba74
F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c
F test/selectA.test 68de52409e45a3313d00b8461b48bef4fb729faf36ade9067a994eae55cc86f4 F test/selectA.test 68de52409e45a3313d00b8461b48bef4fb729faf36ade9067a994eae55cc86f4
F test/where.test f5e62453537e5b335b69f3b09f8a02ce3328289fad5d866e25371284b837d78d
F test/whereG.test 9363b2a97d914cb1b81aff5069ef0cf2a071a67e2b604eac6fe9c0114017d9aa F test/whereG.test 9363b2a97d914cb1b81aff5069ef0cf2a071a67e2b604eac6fe9c0114017d9aa
F test/window1.test 9d7f4990e5b36d95af93b189da4aa75216c6690ce95cced3c8b6d3234be51c2c F test/window1.test 9d7f4990e5b36d95af93b189da4aa75216c6690ce95cced3c8b6d3234be51c2c
P d31fd57ea538668238787fde10a6a57bbd8a428c73f2e54b2e95ee9a645bc75b F test/without_rowid3.test 96426a6c9a2a5cf62bbe55ea1ad038eaaf4bf743f40a1ad517233b8e5a3d4339
R 9bf0d64a5e369f6303626cfabb9127fe P 9472f1fe58222b738ad10fc93ceb365dc33b65c2bbca571f52bcd5bdb74b347e
R 02b044eedda1f74db4b37271f6bc932d
U drh U drh
Z b4b377f6d8e70e8e674e66c244cb5822 Z dcba90128c816b6defcdc3a0ba95ebaa

View File

@ -1 +1 @@
9472f1fe58222b738ad10fc93ceb365dc33b65c2bbca571f52bcd5bdb74b347e 61782a7ae3c25cf59d7a676cb295eb024d17c46e532ae78c6fe871a91d712fa9

View File

@ -52,22 +52,22 @@ static int isAlterableTable(Parse *pParse, Table *pTab){
static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"SELECT 1 " "SELECT 1 "
"FROM \"%w\".%s " "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
" AND sql NOT LIKE 'create virtual%%'" " AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ", " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
zDb, MASTER_NAME, zDb,
zDb, bTemp zDb, bTemp
); );
if( bTemp==0 ){ if( bTemp==0 ){
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"SELECT 1 " "SELECT 1 "
"FROM temp.%s " "FROM temp." DFLT_SCHEMA_TABLE " "
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
" AND sql NOT LIKE 'create virtual%%'" " AND sql NOT LIKE 'create virtual%%'"
" AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ", " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ",
MASTER_NAME, zDb zDb
); );
} }
} }
@ -185,17 +185,17 @@ void sqlite3AlterRenameTable(
/* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
** the schema to use the new table name. */ ** the schema to use the new table name. */
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET " "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
"AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
, zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName , zDb, zDb, zTabName, zName, (iDb==1), zTabName
); );
/* Update the tbl_name and name columns of the sqlite_master table /* Update the tbl_name and name columns of the sqlite_master table
** as required. */ ** as required. */
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET " "UPDATE %Q." DFLT_SCHEMA_TABLE " SET "
"tbl_name = %Q, " "tbl_name = %Q, "
"name = CASE " "name = CASE "
"WHEN type='table' THEN %Q " "WHEN type='table' THEN %Q "
@ -205,7 +205,7 @@ void sqlite3AlterRenameTable(
"ELSE name END " "ELSE name END "
"WHERE tbl_name=%Q COLLATE nocase AND " "WHERE tbl_name=%Q COLLATE nocase AND "
"(type='table' OR type='index' OR type='trigger');", "(type='table' OR type='index' OR type='trigger');",
zDb, MASTER_NAME, zDb,
zName, zName, zName, zName, zName, zName,
nTabName, zTabName nTabName, zTabName
); );
@ -382,10 +382,10 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
} }
db->mDbFlags |= DBFLAG_PreferBuiltin; db->mDbFlags |= DBFLAG_PreferBuiltin;
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET " "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
"sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
"WHERE type = 'table' AND name = %Q", "WHERE type = 'table' AND name = %Q",
zDb, MASTER_NAME, pNew->addColOffset, zCol, pNew->addColOffset+1, zDb, pNew->addColOffset, zCol, pNew->addColOffset+1,
zTab zTab
); );
sqlite3DbFree(db, zCol); sqlite3DbFree(db, zCol);
@ -595,21 +595,20 @@ void sqlite3AlterRenameColumn(
assert( pNew->n>0 ); assert( pNew->n>0 );
bQuote = sqlite3Isquote(pNew->z[0]); bQuote = sqlite3Isquote(pNew->z[0]);
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"UPDATE \"%w\".%s SET " "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
" AND (type != 'index' OR tbl_name = %Q)" " AND (type != 'index' OR tbl_name = %Q)"
" AND sql NOT LIKE 'create virtual%%'", " AND sql NOT LIKE 'create virtual%%'",
zDb, MASTER_NAME, zDb,
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
pTab->zName pTab->zName
); );
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"UPDATE temp.%s SET " "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
"WHERE type IN ('trigger', 'view')", "WHERE type IN ('trigger', 'view')",
MASTER_NAME,
zDb, pTab->zName, iCol, zNew, bQuote zDb, pTab->zName, iCol, zNew, bQuote
); );

View File

@ -3429,7 +3429,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
/* Any read-only or read-write transaction implies a read-lock on /* Any read-only or read-write transaction implies a read-lock on
** page 1. So if some other shared-cache client already has a write-lock ** page 1. So if some other shared-cache client already has a write-lock
** on page 1, the transaction cannot be opened. */ ** on page 1, the transaction cannot be opened. */
rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK);
if( SQLITE_OK!=rc ) goto trans_begun; if( SQLITE_OK!=rc ) goto trans_begun;
pBt->btsFlags &= ~BTS_INITIALLY_EMPTY; pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
@ -9477,7 +9477,7 @@ void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
sqlite3BtreeEnter(p); sqlite3BtreeEnter(p);
assert( p->inTrans>TRANS_NONE ); assert( p->inTrans>TRANS_NONE );
assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) ); assert( SQLITE_OK==querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK) );
assert( pBt->pPage1 ); assert( pBt->pPage1 );
assert( idx>=0 && idx<=15 ); assert( idx>=0 && idx<=15 );
@ -10360,7 +10360,7 @@ int sqlite3BtreeSchemaLocked(Btree *p){
int rc; int rc;
assert( sqlite3_mutex_held(p->db->mutex) ); assert( sqlite3_mutex_held(p->db->mutex) );
sqlite3BtreeEnter(p); sqlite3BtreeEnter(p);
rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK);
assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE );
sqlite3BtreeLeave(p); sqlite3BtreeLeave(p);
return rc; return rc;

View File

@ -253,7 +253,7 @@ void sqlite3FinishCoding(Parse *pParse){
** outermost parser. ** outermost parser.
** **
** Not everything is nestable. This facility is designed to permit ** Not everything is nestable. This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use ** INSERT, UPDATE, and DELETE operations against the schema table. Use
** care if you decide to try to use this routine for some other purposes. ** care if you decide to try to use this routine for some other purposes.
*/ */
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
@ -335,9 +335,21 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
} }
} }
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName); p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
if( p==0 && i==1 && sqlite3StrICmp(zName, MASTER_NAME)==0 ){ if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
/* All temp.sqlite_master to be an alias for sqlite_temp_master */ if( i==1 ){
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, TEMP_MASTER_NAME); if( sqlite3StrICmp(zName+7, ALT_TEMP_SCHEMA_TABLE+7)==0
|| sqlite3StrICmp(zName+7, ALT_SCHEMA_TABLE+7)==0
|| sqlite3StrICmp(zName+7, DFLT_SCHEMA_TABLE+7)==0
){
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
DFLT_TEMP_SCHEMA_TABLE);
}
}else{
if( sqlite3StrICmp(zName+7, ALT_SCHEMA_TABLE+7)==0 ){
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
DFLT_SCHEMA_TABLE);
}
}
} }
}else{ }else{
/* Match against TEMP first */ /* Match against TEMP first */
@ -352,6 +364,14 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName); p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
if( p ) break; if( p ) break;
} }
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
if( sqlite3StrICmp(zName+7, ALT_SCHEMA_TABLE+7)==0 ){
p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, DFLT_SCHEMA_TABLE);
}else if( sqlite3StrICmp(zName+7, ALT_TEMP_SCHEMA_TABLE+7)==0 ){
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
DFLT_TEMP_SCHEMA_TABLE);
}
}
} }
return p; return p;
} }
@ -746,10 +766,10 @@ char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
** Open the sqlite_master table stored in database number iDb for ** Open the sqlite_master table stored in database number iDb for
** writing. The table is opened using cursor 0. ** writing. The table is opened using cursor 0.
*/ */
void sqlite3OpenMasterTable(Parse *p, int iDb){ void sqlite3OpenSchemaTable(Parse *p, int iDb){
Vdbe *v = sqlite3GetVdbe(p); Vdbe *v = sqlite3GetVdbe(p);
sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME); sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, DFLT_SCHEMA_TABLE);
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5); sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
if( p->nTab==0 ){ if( p->nTab==0 ){
p->nTab = 1; p->nTab = 1;
} }
@ -1135,7 +1155,7 @@ void sqlite3StartTable(
#endif #endif
/* Begin generating the code that will insert the table record into /* Begin generating the code that will insert the table record into
** the SQLITE_MASTER table. Note in particular that we must go ahead ** the schema table. Note in particular that we must go ahead
** and allocate the record number for the table entry now. Before any ** and allocate the record number for the table entry now. Before any
** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause
** indices to be created and the table record must come before the ** indices to be created and the table record must come before the
@ -1189,7 +1209,7 @@ void sqlite3StartTable(
pParse->addrCrTab = pParse->addrCrTab =
sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
} }
sqlite3OpenMasterTable(pParse, iDb); sqlite3OpenSchemaTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC); sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
@ -2364,7 +2384,7 @@ void sqlite3EndTable(
} }
/* If not initializing, then create a record for the new table /* If not initializing, then create a record for the new table
** in the SQLITE_MASTER table of the database. ** in the schema table of the database.
** **
** If this is a TEMPORARY table, write the entry into the auxiliary ** If this is a TEMPORARY table, write the entry into the auxiliary
** file instead of into the main database file. ** file instead of into the main database file.
@ -2466,14 +2486,14 @@ void sqlite3EndTable(
} }
/* A slot for the record has already been allocated in the /* A slot for the record has already been allocated in the
** SQLITE_MASTER table. We just need to update that slot with all ** schema table. We just need to update that slot with all
** the information we've collected. ** the information we've collected.
*/ */
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"UPDATE %Q.%s " "UPDATE %Q." DFLT_SCHEMA_TABLE
"SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
"WHERE rowid=#%d", " WHERE rowid=#%d",
db->aDb[iDb].zDbSName, MASTER_NAME, db->aDb[iDb].zDbSName,
zType, zType,
p->zName, p->zName,
p->zName, p->zName,
@ -2601,7 +2621,7 @@ void sqlite3CreateView(
sEnd.z = &z[n-1]; sEnd.z = &z[n-1];
sEnd.n = 1; sEnd.n = 1;
/* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */ /* Use sqlite3EndTable() to add the view to the schema table */
sqlite3EndTable(pParse, 0, &sEnd, 0, 0); sqlite3EndTable(pParse, 0, &sEnd, 0, 0);
create_view_fail: create_view_fail:
@ -2837,8 +2857,9 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
** token for additional information. ** token for additional information.
*/ */
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", "UPDATE %Q." DFLT_SCHEMA_TABLE
pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1); " SET rootpage=%d WHERE #%d AND rootpage=#%d",
pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
#endif #endif
sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r1);
} }
@ -2963,7 +2984,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
} }
#endif #endif
/* Drop all SQLITE_MASTER table and index entries that refer to the /* Drop all entries in the schema table that refer to the
** table. The program name loops through the master table and deletes ** 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 ** 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 ** dropped. Triggers are handled separately because a trigger can be
@ -2971,8 +2992,9 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
** database. ** database.
*/ */
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", "DELETE FROM %Q." DFLT_SCHEMA_TABLE
pDb->zDbSName, MASTER_NAME, pTab->zName); " WHERE tbl_name=%Q and type!='trigger'",
pDb->zDbSName, pTab->zName);
if( !isView && !IsVirtual(pTab) ){ if( !isView && !IsVirtual(pTab) ){
destroyTable(pParse, pTab); destroyTable(pParse, pTab);
} }
@ -3979,8 +4001,8 @@ void sqlite3CreateIndex(
/* Add an entry in sqlite_master for this index /* Add an entry in sqlite_master for this index
*/ */
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", "INSERT INTO %Q." DFLT_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
db->aDb[iDb].zDbSName, MASTER_NAME, db->aDb[iDb].zDbSName,
pIndex->zName, pIndex->zName,
pTab->zName, pTab->zName,
iMem, iMem,
@ -4150,8 +4172,8 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
if( v ){ if( v ){
sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3BeginWriteOperation(pParse, 1, iDb);
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='index'", "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName db->aDb[iDb].zDbSName, pIndex->zName
); );
sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
sqlite3ChangeCookie(pParse, iDb); sqlite3ChangeCookie(pParse, iDb);

View File

@ -9030,8 +9030,11 @@ static int do_meta_command(char *zLine, ShellState *p){
} }
} }
if( zName!=0 ){ if( zName!=0 ){
int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0; int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0
if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 ){ || sqlite3_strlike(zName, "sqlite_schema", '\\')==0
|| sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
|| sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
if( isMaster ){
char *new_argv[2], *new_colv[2]; char *new_argv[2], *new_colv[2];
new_argv[0] = sqlite3_mprintf( new_argv[0] = sqlite3_mprintf(
"CREATE TABLE %s (\n" "CREATE TABLE %s (\n"
@ -9040,7 +9043,7 @@ static int do_meta_command(char *zLine, ShellState *p){
" tbl_name text,\n" " tbl_name text,\n"
" rootpage integer,\n" " rootpage integer,\n"
" sql text\n" " sql text\n"
")", isMaster ? "sqlite_master" : "sqlite_temp_master"); ")", zName);
new_argv[1] = 0; new_argv[1] = 0;
new_colv[0] = "sql"; new_colv[0] = "sql";
new_colv[1] = 0; new_colv[1] = 0;

View File

@ -1011,18 +1011,24 @@ struct BusyHandler {
** is a special table that holds the names and attributes of all ** is a special table that holds the names and attributes of all
** user tables and indices. ** user tables and indices.
*/ */
#define MASTER_NAME "sqlite_master" //#define MASTER_NAME "sqlite_master"
#define TEMP_MASTER_NAME "sqlite_temp_master" //#define TEMP_MASTER_NAME "sqlite_temp_master"
#define DFLT_SCHEMA_TABLE "sqlite_master"
#define DFLT_TEMP_SCHEMA_TABLE "sqlite_temp_master"
#define ALT_SCHEMA_TABLE "sqlite_schema"
#define ALT_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
/* /*
** The root-page of the master database table. ** The root-page of the schema table.
*/ */
#define MASTER_ROOT 1 #define SCHEMA_ROOT 1
/* /*
** The name of the schema table. ** The name of the schema table. The name is different for TEMP.
*/ */
#define SCHEMA_TABLE(x) ((!OMIT_TEMPDB)&&(x==1)?TEMP_MASTER_NAME:MASTER_NAME) #define SCHEMA_TABLE(x) \
((!OMIT_TEMPDB)&&(x==1)?DFLT_TEMP_SCHEMA_TABLE:DFLT_SCHEMA_TABLE)
/* /*
** A convenience macro that returns the number of elements in ** A convenience macro that returns the number of elements in
@ -4144,7 +4150,7 @@ void sqlite3DeleteColumnNames(sqlite3*,Table*);
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
void sqlite3OpenMasterTable(Parse *, int); void sqlite3OpenSchemaTable(Parse *, int);
Index *sqlite3PrimaryKeyIndex(Table*); Index *sqlite3PrimaryKeyIndex(Table*);
i16 sqlite3TableColumnToIndex(Index*, i16); i16 sqlite3TableColumnToIndex(Index*, i16);
#ifdef SQLITE_OMIT_GENERATED_COLUMNS #ifdef SQLITE_OMIT_GENERATED_COLUMNS

View File

@ -128,7 +128,7 @@ void sqlite3BeginTrigger(
** ^^^^^^^^ ** ^^^^^^^^
** **
** To maintain backwards compatibility, ignore the database ** To maintain backwards compatibility, ignore the database
** name on pTableName if we are reparsing out of SQLITE_MASTER. ** name on pTableName if we are reparsing out of the schema table
*/ */
if( db->init.busy && iDb!=1 ){ if( db->init.busy && iDb!=1 ){
sqlite3DbFree(db, pTableName->a[0].zDatabase); sqlite3DbFree(db, pTableName->a[0].zDatabase);
@ -331,8 +331,9 @@ void sqlite3FinishTrigger(
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
testcase( z==0 ); testcase( z==0 );
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", "INSERT INTO %Q." DFLT_SCHEMA_TABLE
db->aDb[iDb].zDbSName, MASTER_NAME, zName, " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
db->aDb[iDb].zDbSName, zName,
pTrig->table, z); pTrig->table, z);
sqlite3DbFree(db, z); sqlite3DbFree(db, z);
sqlite3ChangeCookie(pParse, iDb); sqlite3ChangeCookie(pParse, iDb);
@ -639,8 +640,8 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
*/ */
if( (v = sqlite3GetVdbe(pParse))!=0 ){ if( (v = sqlite3GetVdbe(pParse))!=0 ){
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName db->aDb[iDb].zDbSName, pTrigger->zName
); );
sqlite3ChangeCookie(pParse, iDb); sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);

View File

@ -304,7 +304,7 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
/* Copy the triggers, views, and virtual tables from the main database /* Copy the triggers, views, and virtual tables from the main database
** over to the temporary database. None of these objects has any ** over to the temporary database. None of these objects has any
** associated storage, so all we have to do is copy their entries ** associated storage, so all we have to do is copy their entries
** from the SQLITE_MASTER table. ** from the schema table.
*/ */
rc = execSqlF(db, pzErrMsg, rc = execSqlF(db, pzErrMsg,
"INSERT INTO vacuum_db.sqlite_master" "INSERT INTO vacuum_db.sqlite_master"

View File

@ -3950,7 +3950,7 @@ case OP_OpenEphemeral: {
rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot, rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
BTREE_BLOBKEY | pOp->p5); BTREE_BLOBKEY | pOp->p5);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
assert( pCx->pgnoRoot==MASTER_ROOT+1 ); assert( pCx->pgnoRoot==SCHEMA_ROOT+1 );
assert( pKeyInfo->db==db ); assert( pKeyInfo->db==db );
assert( pKeyInfo->enc==ENC(db) ); assert( pKeyInfo->enc==ENC(db) );
rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
@ -3958,8 +3958,8 @@ case OP_OpenEphemeral: {
} }
pCx->isTable = 0; pCx->isTable = 0;
}else{ }else{
pCx->pgnoRoot = MASTER_ROOT; pCx->pgnoRoot = SCHEMA_ROOT;
rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR, rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR,
0, pCx->uc.pCursor); 0, pCx->uc.pCursor);
pCx->isTable = 1; pCx->isTable = 1;
} }
@ -6066,7 +6066,7 @@ case OP_SqlExec: {
/* Opcode: ParseSchema P1 * * P4 * /* Opcode: ParseSchema P1 * * P4 *
** **
** Read and parse all entries from the SQLITE_MASTER table of database P1 ** Read and parse all entries from the schema table of database P1
** that match the WHERE clause P4. If P4 is a NULL pointer, then the ** that match the WHERE clause P4. If P4 is a NULL pointer, then the
** entire schema for P1 is reparsed. ** entire schema for P1 is reparsed.
** **
@ -6103,7 +6103,7 @@ case OP_ParseSchema: {
}else }else
#endif #endif
{ {
zMaster = MASTER_NAME; zMaster = DFLT_SCHEMA_TABLE;
initData.db = db; initData.db = db;
initData.iDb = iDb; initData.iDb = iDb;
initData.pzErrMsg = &p->zErrMsg; initData.pzErrMsg = &p->zErrMsg;

View File

@ -466,7 +466,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
/* A slot for the record has already been allocated in the /* A slot for the record has already been allocated in the
** SQLITE_MASTER table. We just need to update that slot with all ** schema table. We just need to update that slot with all
** the information we've collected. ** the information we've collected.
** **
** The VM register number pParse->regRowid holds the rowid of an ** The VM register number pParse->regRowid holds the rowid of an
@ -475,10 +475,10 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
*/ */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema); iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3NestedParse(pParse, sqlite3NestedParse(pParse,
"UPDATE %Q.%s " "UPDATE %Q." DFLT_SCHEMA_TABLE " "
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
"WHERE rowid=#%d", "WHERE rowid=#%d",
db->aDb[iDb].zDbSName, MASTER_NAME, db->aDb[iDb].zDbSName,
pTab->zName, pTab->zName,
pTab->zName, pTab->zName,
zStmt, zStmt,

View File

@ -1496,8 +1496,8 @@ do_execsql_test where-25.0 {
INSERT INTO t2 VALUES(3, 'three', 'iii'); INSERT INTO t2 VALUES(3, 'three', 'iii');
PRAGMA writable_schema = 1; PRAGMA writable_schema = 1;
UPDATE sqlite_master SET rootpage = ( UPDATE sqlite_schema SET rootpage = (
SELECT rootpage FROM sqlite_master WHERE name = 'i2' SELECT rootpage FROM sqlite_schema WHERE name = 'i2'
) WHERE name = 'i1'; ) WHERE name = 'i1';
} }
db close db close
@ -1524,8 +1524,8 @@ do_execsql_test where-25.3 {
INSERT INTO t2 VALUES(3, 'three', 'iii'); INSERT INTO t2 VALUES(3, 'three', 'iii');
PRAGMA writable_schema = 1; PRAGMA writable_schema = 1;
UPDATE sqlite_master SET rootpage = ( UPDATE sqlite_schema SET rootpage = (
SELECT rootpage FROM sqlite_master WHERE name = 'i2' SELECT rootpage FROM sqlite_schema WHERE name = 'i2'
) WHERE name = 'i1'; ) WHERE name = 'i1';
} }
db close db close

View File

@ -942,7 +942,7 @@ ifcapable altertable {
PRAGMA foreign_keys = off; PRAGMA foreign_keys = off;
ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
PRAGMA foreign_keys = on; PRAGMA foreign_keys = on;
SELECT sql FROM sqlite_master WHERE name='t2'; SELECT sql FROM sqlite_schema WHERE name='t2';
} }
} {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
@ -976,7 +976,7 @@ ifcapable altertable {
WITHOUT rowid; WITHOUT rowid;
CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1); CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
} }
execsql { SELECT sql FROM sqlite_master WHERE type = 'table'} execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
} [list \ } [list \
{CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \ {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
@ -985,7 +985,7 @@ ifcapable altertable {
] ]
do_test without_rowid3-14.2.2.2 { do_test without_rowid3-14.2.2.2 {
execsql { ALTER TABLE t1 RENAME TO t4 } execsql { ALTER TABLE t1 RENAME TO t4 }
execsql { SELECT sql FROM sqlite_master WHERE type = 'table'} execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
} [list \ } [list \
{CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \ {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2) {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
@ -1037,7 +1037,7 @@ ifcapable altertable {
PRAGMA foreign_keys = off; PRAGMA foreign_keys = off;
ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
PRAGMA foreign_keys = on; PRAGMA foreign_keys = on;
SELECT sql FROM temp.sqlite_master WHERE name='t2'; SELECT sql FROM temp.sqlite_schema WHERE name='t2';
} }
} {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
@ -1063,7 +1063,7 @@ ifcapable altertable {
WITHOUT rowid; WITHOUT rowid;
CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1); CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
} }
execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'} execsql { SELECT sql FROM sqlite_temp_schema WHERE type = 'table'}
} [list \ } [list \
{CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \ {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
@ -1072,7 +1072,7 @@ ifcapable altertable {
] ]
do_test without_rowid3-14.2tmp.2.2 { do_test without_rowid3-14.2tmp.2.2 {
execsql { ALTER TABLE t1 RENAME TO t4 } execsql { ALTER TABLE t1 RENAME TO t4 }
execsql { SELECT sql FROM temp.sqlite_master WHERE type = 'table'} execsql { SELECT sql FROM temp.sqlite_schema WHERE type = 'table'}
} [list \ } [list \
{CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \ {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2) {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
@ -1125,7 +1125,7 @@ ifcapable altertable {
PRAGMA foreign_keys = off; PRAGMA foreign_keys = off;
ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
PRAGMA foreign_keys = on; PRAGMA foreign_keys = on;
SELECT sql FROM aux.sqlite_master WHERE name='t2'; SELECT sql FROM aux.sqlite_schema WHERE name='t2';
} }
} {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
@ -1151,7 +1151,7 @@ ifcapable altertable {
WITHOUT rowid; WITHOUT rowid;
CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1); CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
} }
execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'} execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
} [list \ } [list \
{CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \ {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
@ -1160,7 +1160,7 @@ ifcapable altertable {
] ]
do_test without_rowid3-14.2aux.2.2 { do_test without_rowid3-14.2aux.2.2 {
execsql { ALTER TABLE t1 RENAME TO t4 } execsql { ALTER TABLE t1 RENAME TO t4 }
execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'} execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
} [list \ } [list \
{CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \ {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2) {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)