Provide "sqlite_schema" as an alternative name to the table that holds the
database schema. FossilOrigin-Name: 61782a7ae3c25cf59d7a676cb295eb024d17c46e532ae78c6fe871a91d712fa9
This commit is contained in:
parent
999429882e
commit
346a70ca1e
25
manifest
25
manifest
@ -1,17 +1,22 @@
|
||||
B fd5abb1a7b5a55127d5c0d5ff448020d8bccab44e4f5afe1eb88fc19578af735
|
||||
C Fix\sthe\sCLI\sso\sthat\sinterrupts\swork\sin\scolumnar\soutput\smode.
|
||||
D 2020-06-15T20:05:37.857
|
||||
C Provide\s"sqlite_schema"\sas\san\salternative\sname\sto\sthe\stable\sthat\sholds\sthe\ndatabase\sschema.
|
||||
D 2020-06-15T20:27:35.935
|
||||
F configure f594931bd7b23dad12db96b81e1dba43b41b30a4560d6eb008014e3d9f1617e8 x
|
||||
F configure.ac 13e4ecf89214c3aa0ba099a9e0178f13f03261ace627126737d8cee240ec5c1c
|
||||
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/global.c 0409ae635839e0bef26a69b68be64126ab6cba62ac19bd7694f1652e591c4c17
|
||||
F src/select.c 6ddd86a7272ff1f443bd9efcbb0f5ab590674d4c732e4cb8c3d5dd8e3a70cae6
|
||||
F src/shell.c.in 0e439519aae3c08cac2c0da84bc5899bbea4d5f273d3e970febb9bf7516d680b
|
||||
F src/sqliteInt.h abf448e9f839964086d5508ba795e948dbf36d773b6568cf4c830f6c7ad2110e
|
||||
F src/shell.c.in c27ee0cd27e17db69257597f927301532a9f019445e3526828c78d348b6f0786
|
||||
F src/sqliteInt.h 0a13c93b250270c5876da65c21963eaca60c5fc55271c313d5f6cf20547134af
|
||||
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 test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0
|
||||
F test/fts3corrupt4.test e77b06926348eb45b71569f9dc45e5b19c984ca1b1ef6671367f4ca9d6eaa973
|
||||
@ -19,9 +24,11 @@ F test/fuzzdata8.db b87ae726c84c3f80d457642d7650724a76eb3d7b76258959d712cc4d926d
|
||||
F test/istrue.test 06f92ea38750fa74df7dbbe6920205251c2310861fbbe23a3adfa918a2e2ba74
|
||||
F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c
|
||||
F test/selectA.test 68de52409e45a3313d00b8461b48bef4fb729faf36ade9067a994eae55cc86f4
|
||||
F test/where.test f5e62453537e5b335b69f3b09f8a02ce3328289fad5d866e25371284b837d78d
|
||||
F test/whereG.test 9363b2a97d914cb1b81aff5069ef0cf2a071a67e2b604eac6fe9c0114017d9aa
|
||||
F test/window1.test 9d7f4990e5b36d95af93b189da4aa75216c6690ce95cced3c8b6d3234be51c2c
|
||||
P d31fd57ea538668238787fde10a6a57bbd8a428c73f2e54b2e95ee9a645bc75b
|
||||
R 9bf0d64a5e369f6303626cfabb9127fe
|
||||
F test/without_rowid3.test 96426a6c9a2a5cf62bbe55ea1ad038eaaf4bf743f40a1ad517233b8e5a3d4339
|
||||
P 9472f1fe58222b738ad10fc93ceb365dc33b65c2bbca571f52bcd5bdb74b347e
|
||||
R 02b044eedda1f74db4b37271f6bc932d
|
||||
U drh
|
||||
Z b4b377f6d8e70e8e674e66c244cb5822
|
||||
Z dcba90128c816b6defcdc3a0ba95ebaa
|
||||
|
@ -1 +1 @@
|
||||
9472f1fe58222b738ad10fc93ceb365dc33b65c2bbca571f52bcd5bdb74b347e
|
||||
61782a7ae3c25cf59d7a676cb295eb024d17c46e532ae78c6fe871a91d712fa9
|
27
src/alter.c
27
src/alter.c
@ -52,22 +52,22 @@ static int isAlterableTable(Parse *pParse, Table *pTab){
|
||||
static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){
|
||||
sqlite3NestedParse(pParse,
|
||||
"SELECT 1 "
|
||||
"FROM \"%w\".%s "
|
||||
"FROM \"%w\"." DFLT_SCHEMA_TABLE " "
|
||||
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
|
||||
" AND sql NOT LIKE 'create virtual%%'"
|
||||
" AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ",
|
||||
zDb, MASTER_NAME,
|
||||
zDb,
|
||||
zDb, bTemp
|
||||
);
|
||||
|
||||
if( bTemp==0 ){
|
||||
sqlite3NestedParse(pParse,
|
||||
"SELECT 1 "
|
||||
"FROM temp.%s "
|
||||
"FROM temp." DFLT_SCHEMA_TABLE " "
|
||||
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
|
||||
" AND sql NOT LIKE 'create virtual%%'"
|
||||
" 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
|
||||
** the schema to use the new table name. */
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE \"%w\".%s SET "
|
||||
"UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
|
||||
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
|
||||
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
|
||||
"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
|
||||
** as required. */
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.%s SET "
|
||||
"UPDATE %Q." DFLT_SCHEMA_TABLE " SET "
|
||||
"tbl_name = %Q, "
|
||||
"name = CASE "
|
||||
"WHEN type='table' THEN %Q "
|
||||
@ -205,7 +205,7 @@ void sqlite3AlterRenameTable(
|
||||
"ELSE name END "
|
||||
"WHERE tbl_name=%Q COLLATE nocase AND "
|
||||
"(type='table' OR type='index' OR type='trigger');",
|
||||
zDb, MASTER_NAME,
|
||||
zDb,
|
||||
zName, zName, zName,
|
||||
nTabName, zTabName
|
||||
);
|
||||
@ -382,10 +382,10 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
|
||||
}
|
||||
db->mDbFlags |= DBFLAG_PreferBuiltin;
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE \"%w\".%s SET "
|
||||
"UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
|
||||
"sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
|
||||
"WHERE type = 'table' AND name = %Q",
|
||||
zDb, MASTER_NAME, pNew->addColOffset, zCol, pNew->addColOffset+1,
|
||||
zDb, pNew->addColOffset, zCol, pNew->addColOffset+1,
|
||||
zTab
|
||||
);
|
||||
sqlite3DbFree(db, zCol);
|
||||
@ -595,21 +595,20 @@ void sqlite3AlterRenameColumn(
|
||||
assert( pNew->n>0 );
|
||||
bQuote = sqlite3Isquote(pNew->z[0]);
|
||||
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) "
|
||||
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
|
||||
" AND (type != 'index' OR tbl_name = %Q)"
|
||||
" AND sql NOT LIKE 'create virtual%%'",
|
||||
zDb, MASTER_NAME,
|
||||
zDb,
|
||||
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
|
||||
pTab->zName
|
||||
);
|
||||
|
||||
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) "
|
||||
"WHERE type IN ('trigger', 'view')",
|
||||
MASTER_NAME,
|
||||
zDb, pTab->zName, iCol, zNew, bQuote
|
||||
);
|
||||
|
||||
|
@ -3429,7 +3429,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){
|
||||
/* 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
|
||||
** 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;
|
||||
|
||||
pBt->btsFlags &= ~BTS_INITIALLY_EMPTY;
|
||||
@ -9477,7 +9477,7 @@ void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
|
||||
|
||||
sqlite3BtreeEnter(p);
|
||||
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( idx>=0 && idx<=15 );
|
||||
|
||||
@ -10360,7 +10360,7 @@ int sqlite3BtreeSchemaLocked(Btree *p){
|
||||
int rc;
|
||||
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||
sqlite3BtreeEnter(p);
|
||||
rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
|
||||
rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK);
|
||||
assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE );
|
||||
sqlite3BtreeLeave(p);
|
||||
return rc;
|
||||
|
68
src/build.c
68
src/build.c
@ -253,7 +253,7 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
** outermost parser.
|
||||
**
|
||||
** 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.
|
||||
*/
|
||||
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);
|
||||
if( p==0 && i==1 && sqlite3StrICmp(zName, MASTER_NAME)==0 ){
|
||||
/* All temp.sqlite_master to be an alias for sqlite_temp_master */
|
||||
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, TEMP_MASTER_NAME);
|
||||
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
|
||||
if( i==1 ){
|
||||
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{
|
||||
/* 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);
|
||||
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;
|
||||
}
|
||||
@ -746,10 +766,10 @@ char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
|
||||
** Open the sqlite_master table stored in database number iDb for
|
||||
** writing. The table is opened using cursor 0.
|
||||
*/
|
||||
void sqlite3OpenMasterTable(Parse *p, int iDb){
|
||||
void sqlite3OpenSchemaTable(Parse *p, int iDb){
|
||||
Vdbe *v = sqlite3GetVdbe(p);
|
||||
sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME);
|
||||
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5);
|
||||
sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, DFLT_SCHEMA_TABLE);
|
||||
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
|
||||
if( p->nTab==0 ){
|
||||
p->nTab = 1;
|
||||
}
|
||||
@ -1135,7 +1155,7 @@ void sqlite3StartTable(
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause
|
||||
** indices to be created and the table record must come before the
|
||||
@ -1189,7 +1209,7 @@ void sqlite3StartTable(
|
||||
pParse->addrCrTab =
|
||||
sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
|
||||
}
|
||||
sqlite3OpenMasterTable(pParse, iDb);
|
||||
sqlite3OpenSchemaTable(pParse, iDb);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
|
||||
sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
|
||||
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
|
||||
@ -2364,7 +2384,7 @@ void sqlite3EndTable(
|
||||
}
|
||||
|
||||
/* 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
|
||||
** 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
|
||||
** 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.
|
||||
*/
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.%s "
|
||||
"UPDATE %Q." DFLT_SCHEMA_TABLE
|
||||
" SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
|
||||
" WHERE rowid=#%d",
|
||||
db->aDb[iDb].zDbSName, MASTER_NAME,
|
||||
db->aDb[iDb].zDbSName,
|
||||
zType,
|
||||
p->zName,
|
||||
p->zName,
|
||||
@ -2601,7 +2621,7 @@ void sqlite3CreateView(
|
||||
sEnd.z = &z[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);
|
||||
|
||||
create_view_fail:
|
||||
@ -2837,8 +2857,9 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){
|
||||
** token for additional information.
|
||||
*/
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d",
|
||||
pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1);
|
||||
"UPDATE %Q." DFLT_SCHEMA_TABLE
|
||||
" SET rootpage=%d WHERE #%d AND rootpage=#%d",
|
||||
pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
|
||||
#endif
|
||||
sqlite3ReleaseTempReg(pParse, r1);
|
||||
}
|
||||
@ -2963,7 +2984,7 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
|
||||
}
|
||||
#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
|
||||
** 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
|
||||
@ -2971,8 +2992,9 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
|
||||
** database.
|
||||
*/
|
||||
sqlite3NestedParse(pParse,
|
||||
"DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
|
||||
pDb->zDbSName, MASTER_NAME, pTab->zName);
|
||||
"DELETE FROM %Q." DFLT_SCHEMA_TABLE
|
||||
" WHERE tbl_name=%Q and type!='trigger'",
|
||||
pDb->zDbSName, pTab->zName);
|
||||
if( !isView && !IsVirtual(pTab) ){
|
||||
destroyTable(pParse, pTab);
|
||||
}
|
||||
@ -3979,8 +4001,8 @@ void sqlite3CreateIndex(
|
||||
/* 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, MASTER_NAME,
|
||||
"INSERT INTO %Q." DFLT_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
|
||||
db->aDb[iDb].zDbSName,
|
||||
pIndex->zName,
|
||||
pTab->zName,
|
||||
iMem,
|
||||
@ -4150,8 +4172,8 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
|
||||
if( v ){
|
||||
sqlite3BeginWriteOperation(pParse, 1, iDb);
|
||||
sqlite3NestedParse(pParse,
|
||||
"DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
|
||||
db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName
|
||||
"DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
|
||||
db->aDb[iDb].zDbSName, pIndex->zName
|
||||
);
|
||||
sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
|
||||
sqlite3ChangeCookie(pParse, iDb);
|
||||
|
@ -9030,8 +9030,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}
|
||||
if( zName!=0 ){
|
||||
int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0;
|
||||
if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 ){
|
||||
int isMaster = sqlite3_strlike(zName, "sqlite_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];
|
||||
new_argv[0] = sqlite3_mprintf(
|
||||
"CREATE TABLE %s (\n"
|
||||
@ -9040,7 +9043,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
" tbl_name text,\n"
|
||||
" rootpage integer,\n"
|
||||
" sql text\n"
|
||||
")", isMaster ? "sqlite_master" : "sqlite_temp_master");
|
||||
")", zName);
|
||||
new_argv[1] = 0;
|
||||
new_colv[0] = "sql";
|
||||
new_colv[1] = 0;
|
||||
|
@ -1011,18 +1011,24 @@ struct BusyHandler {
|
||||
** is a special table that holds the names and attributes of all
|
||||
** user tables and indices.
|
||||
*/
|
||||
#define MASTER_NAME "sqlite_master"
|
||||
#define TEMP_MASTER_NAME "sqlite_temp_master"
|
||||
//#define MASTER_NAME "sqlite_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
|
||||
@ -4144,7 +4150,7 @@ void sqlite3DeleteColumnNames(sqlite3*,Table*);
|
||||
int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
|
||||
void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
|
||||
Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
|
||||
void sqlite3OpenMasterTable(Parse *, int);
|
||||
void sqlite3OpenSchemaTable(Parse *, int);
|
||||
Index *sqlite3PrimaryKeyIndex(Table*);
|
||||
i16 sqlite3TableColumnToIndex(Index*, i16);
|
||||
#ifdef SQLITE_OMIT_GENERATED_COLUMNS
|
||||
|
@ -128,7 +128,7 @@ void sqlite3BeginTrigger(
|
||||
** ^^^^^^^^
|
||||
**
|
||||
** 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 ){
|
||||
sqlite3DbFree(db, pTableName->a[0].zDatabase);
|
||||
@ -331,8 +331,9 @@ void sqlite3FinishTrigger(
|
||||
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
|
||||
testcase( z==0 );
|
||||
sqlite3NestedParse(pParse,
|
||||
"INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
|
||||
db->aDb[iDb].zDbSName, MASTER_NAME, zName,
|
||||
"INSERT INTO %Q." DFLT_SCHEMA_TABLE
|
||||
" VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
|
||||
db->aDb[iDb].zDbSName, zName,
|
||||
pTrig->table, z);
|
||||
sqlite3DbFree(db, z);
|
||||
sqlite3ChangeCookie(pParse, iDb);
|
||||
@ -639,8 +640,8 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
|
||||
*/
|
||||
if( (v = sqlite3GetVdbe(pParse))!=0 ){
|
||||
sqlite3NestedParse(pParse,
|
||||
"DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'",
|
||||
db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName
|
||||
"DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
|
||||
db->aDb[iDb].zDbSName, pTrigger->zName
|
||||
);
|
||||
sqlite3ChangeCookie(pParse, iDb);
|
||||
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
|
||||
|
@ -304,7 +304,7 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
/* Copy the triggers, views, and virtual tables from the main database
|
||||
** over to the temporary database. None of these objects has any
|
||||
** associated storage, so all we have to do is copy their entries
|
||||
** from the SQLITE_MASTER table.
|
||||
** from the schema table.
|
||||
*/
|
||||
rc = execSqlF(db, pzErrMsg,
|
||||
"INSERT INTO vacuum_db.sqlite_master"
|
||||
|
10
src/vdbe.c
10
src/vdbe.c
@ -3950,7 +3950,7 @@ case OP_OpenEphemeral: {
|
||||
rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
|
||||
BTREE_BLOBKEY | pOp->p5);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( pCx->pgnoRoot==MASTER_ROOT+1 );
|
||||
assert( pCx->pgnoRoot==SCHEMA_ROOT+1 );
|
||||
assert( pKeyInfo->db==db );
|
||||
assert( pKeyInfo->enc==ENC(db) );
|
||||
rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
|
||||
@ -3958,8 +3958,8 @@ case OP_OpenEphemeral: {
|
||||
}
|
||||
pCx->isTable = 0;
|
||||
}else{
|
||||
pCx->pgnoRoot = MASTER_ROOT;
|
||||
rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
|
||||
pCx->pgnoRoot = SCHEMA_ROOT;
|
||||
rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR,
|
||||
0, pCx->uc.pCursor);
|
||||
pCx->isTable = 1;
|
||||
}
|
||||
@ -6066,7 +6066,7 @@ case OP_SqlExec: {
|
||||
|
||||
/* 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
|
||||
** entire schema for P1 is reparsed.
|
||||
**
|
||||
@ -6103,7 +6103,7 @@ case OP_ParseSchema: {
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
zMaster = MASTER_NAME;
|
||||
zMaster = DFLT_SCHEMA_TABLE;
|
||||
initData.db = db;
|
||||
initData.iDb = iDb;
|
||||
initData.pzErrMsg = &p->zErrMsg;
|
||||
|
@ -466,7 +466,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
|
||||
zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
|
||||
|
||||
/* 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 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);
|
||||
sqlite3NestedParse(pParse,
|
||||
"UPDATE %Q.%s "
|
||||
"UPDATE %Q." DFLT_SCHEMA_TABLE " "
|
||||
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
|
||||
"WHERE rowid=#%d",
|
||||
db->aDb[iDb].zDbSName, MASTER_NAME,
|
||||
db->aDb[iDb].zDbSName,
|
||||
pTab->zName,
|
||||
pTab->zName,
|
||||
zStmt,
|
||||
|
@ -1496,8 +1496,8 @@ do_execsql_test where-25.0 {
|
||||
INSERT INTO t2 VALUES(3, 'three', 'iii');
|
||||
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_master SET rootpage = (
|
||||
SELECT rootpage FROM sqlite_master WHERE name = 'i2'
|
||||
UPDATE sqlite_schema SET rootpage = (
|
||||
SELECT rootpage FROM sqlite_schema WHERE name = 'i2'
|
||||
) WHERE name = 'i1';
|
||||
}
|
||||
db close
|
||||
@ -1524,8 +1524,8 @@ do_execsql_test where-25.3 {
|
||||
INSERT INTO t2 VALUES(3, 'three', 'iii');
|
||||
|
||||
PRAGMA writable_schema = 1;
|
||||
UPDATE sqlite_master SET rootpage = (
|
||||
SELECT rootpage FROM sqlite_master WHERE name = 'i2'
|
||||
UPDATE sqlite_schema SET rootpage = (
|
||||
SELECT rootpage FROM sqlite_schema WHERE name = 'i2'
|
||||
) WHERE name = 'i1';
|
||||
}
|
||||
db close
|
||||
|
@ -942,7 +942,7 @@ ifcapable altertable {
|
||||
PRAGMA foreign_keys = off;
|
||||
ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
|
||||
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)}}
|
||||
|
||||
@ -976,7 +976,7 @@ ifcapable altertable {
|
||||
WITHOUT rowid;
|
||||
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 \
|
||||
{CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
|
||||
{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 {
|
||||
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 \
|
||||
{CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
|
||||
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
|
||||
@ -1037,7 +1037,7 @@ ifcapable altertable {
|
||||
PRAGMA foreign_keys = off;
|
||||
ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
|
||||
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)}}
|
||||
|
||||
@ -1063,7 +1063,7 @@ ifcapable altertable {
|
||||
WITHOUT rowid;
|
||||
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 \
|
||||
{CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
|
||||
{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 {
|
||||
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 \
|
||||
{CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
|
||||
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
|
||||
@ -1125,7 +1125,7 @@ ifcapable altertable {
|
||||
PRAGMA foreign_keys = off;
|
||||
ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
|
||||
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)}}
|
||||
|
||||
@ -1151,7 +1151,7 @@ ifcapable altertable {
|
||||
WITHOUT rowid;
|
||||
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 \
|
||||
{CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
|
||||
{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 {
|
||||
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 \
|
||||
{CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
|
||||
{CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
|
||||
|
Loading…
Reference in New Issue
Block a user