Skip to content

Commit

Permalink
Remove relevant elements from the sqlite_stat2 table when doing a DROP
Browse files Browse the repository at this point in the history
INDEX or DROP TABLE.
  • Loading branch information
D. Richard Hipp committed Aug 7, 2011
1 parent 493a3dd commit 7356012
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 16 deletions.
42 changes: 26 additions & 16 deletions src/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -1980,6 +1980,29 @@ static void destroyTable(Parse *pParse, Table *pTab){
#endif
}

/*
** Remove entries from the sqlite_stat1 and sqlite_stat2 tables
** after a DROP INDEX or DROP TABLE command.
*/
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 */
){
static const char *azStatTab[] = { "sqlite_stat1", "sqlite_stat2" };
int i;
const char *zDbName = pParse->db->aDb[iDb].zName;
for(i=0; i<ArraySize(azStatTab); i++){
if( sqlite3FindTable(pParse->db, azStatTab[i], zDbName) ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE %s=%Q",
zDbName, azStatTab[i], zType, zName
);
}
}
}

/*
** This routine is called to do the work of a DROP TABLE statement.
** pName is the name of the table to be dropped.
Expand Down Expand Up @@ -2119,14 +2142,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);

/* Drop any statistics from the sqlite_stat1 table, if it exists */
if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q", pDb->zName, pTab->zName
);
}

sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
if( !isView && !IsVirtual(pTab) ){
destroyTable(pParse, pTab);
}
Expand Down Expand Up @@ -2949,15 +2965,9 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
sqlite3BeginWriteOperation(pParse, 1, iDb);
sqlite3NestedParse(pParse,
"DELETE FROM %Q.%s WHERE name=%Q AND type='index'",
db->aDb[iDb].zName, SCHEMA_TABLE(iDb),
pIndex->zName
db->aDb[iDb].zName, SCHEMA_TABLE(iDb), pIndex->zName
);
if( sqlite3FindTable(db, "sqlite_stat1", db->aDb[iDb].zName) ){
sqlite3NestedParse(pParse,
"DELETE FROM %Q.sqlite_stat1 WHERE idx=%Q",
db->aDb[iDb].zName, 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);
Expand Down
58 changes: 58 additions & 0 deletions test/analyze.test
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,64 @@ do_test analyze-4.3 {
}
} {}

# Verify that DROP TABLE and DROP INDEX remove entries from the
# sqlite_stat1 and sqlite_stat2 tables.
#
do_test analyze-5.0 {
execsql {
DELETE FROM t3;
DELETE FROM t4;
INSERT INTO t3 VALUES(1,2,3,4);
INSERT INTO t3 VALUES(5,6,7,8);
INSERT INTO t3 SELECT a+8, b+8, c+8, d+8 FROM t3;
INSERT INTO t3 SELECT a+16, b+16, c+16, d+16 FROM t3;
INSERT INTO t3 SELECT a+32, b+32, c+32, d+32 FROM t3;
INSERT INTO t3 SELECT a+64, b+64, c+64, d+64 FROM t3;
INSERT INTO t4 SELECT a, b, c FROM t3;
ANALYZE;
SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
}
} {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
ifcapable stat2 {
do_test analyze-5.1 {
execsql {
SELECT DISTINCT idx FROM sqlite_stat2 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat2 ORDER BY 1;
}
} {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
}
do_test analyze-5.2 {
execsql {
DROP INDEX t3i2;
SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
}
} {t3i1 t3i3 t4i1 t4i2 t3 t4}
ifcapable stat2 {
do_test analyze-5.3 {
execsql {
SELECT DISTINCT idx FROM sqlite_stat2 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat2 ORDER BY 1;
}
} {t3i1 t3i3 t4i1 t4i2 t3 t4}
}
do_test analyze-5.4 {
execsql {
DROP TABLE t3;
SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
}
} {t4i1 t4i2 t4}
ifcapable stat2 {
do_test analyze-5.5 {
execsql {
SELECT DISTINCT idx FROM sqlite_stat2 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat2 ORDER BY 1;
}
} {t4i1 t4i2 t4}
}

# This test corrupts the database file so it must be the last test
# in the series.
#
Expand Down

0 comments on commit 7356012

Please sign in to comment.