提交 b19ef746 authored 作者: Thomas Mueller's avatar Thomas Mueller

The statement "drop all objects" did not work if a table depends on a view via a constraint.

上级 f120ff74
...@@ -18,7 +18,8 @@ Change Log ...@@ -18,7 +18,8 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Subqueries or views with "order by" an alias expression could not be executed <ul><li>The statement "drop all objects" did not work if a table depends on a view via a constraint.
</li><li>Subqueries or views with "order by" an alias expression could not be executed
due to a regression introduced in version 1.3.174. due to a regression introduced in version 1.3.174.
</li><li>Issue 73: MySQL compatibility: support REPLACE, patch by Cemo Koc. </li><li>Issue 73: MySQL compatibility: support REPLACE, patch by Cemo Koc.
</li><li>The spatial index now works in MVCC mode when using the MVStore storage. </li><li>The spatial index now works in MVCC mode when using the MVStore storage.
......
...@@ -53,39 +53,45 @@ public class DropDatabase extends DefineCommand { ...@@ -53,39 +53,45 @@ public class DropDatabase extends DefineCommand {
db.removeDatabaseObject(session, schema); db.removeDatabaseObject(session, schema);
} }
} }
ArrayList<Table> tables = db.getAllTablesAndViews(false);
for (Table t : tables) {
if (t.getName() != null && Table.VIEW.equals(t.getTableType())) {
db.removeSchemaObject(session, t);
}
}
for (Table t : tables) {
if (t.getName() != null && Table.TABLE_LINK.equals(t.getTableType())) {
db.removeSchemaObject(session, t);
}
}
// There can be dependencies between tables e.g. using computed columns, // There can be dependencies between tables e.g. using computed columns,
// so we might need to loop over them multiple times. // so we might need to loop over them multiple times.
boolean runLoopAgain = false; boolean runLoopAgain;
do { do {
runLoopAgain = false; ArrayList<Table> tables = db.getAllTablesAndViews(false);
ArrayList<Table> toRemove = New.arrayList();
for (Table t : tables) {
if (t.getName() != null && Table.VIEW.equals(t.getTableType())) {
toRemove.add(t);
}
}
for (Table t : tables) {
if (t.getName() != null && Table.TABLE_LINK.equals(t.getTableType())) {
toRemove.add(t);
}
}
for (Table t : tables) { for (Table t : tables) {
if (t.getName() != null && Table.TABLE.equals(t.getTableType()) && !t.isHidden()) { if (t.getName() != null && Table.TABLE.equals(t.getTableType()) && !t.isHidden()) {
if (db.getDependentTable(t, t) == null) { toRemove.add(t);
db.removeSchemaObject(session, t); }
} else { }
runLoopAgain = true; for (Table t : tables) {
} if (t.getName() != null && Table.EXTERNAL_TABLE_ENGINE.equals(t.getTableType()) && !t.isHidden()) {
toRemove.add(t);
}
}
runLoopAgain = false;
for (Table t : toRemove) {
if (t.getName() == null) {
// ignore
} else if (db.getDependentTable(t, t) == null) {
db.removeSchemaObject(session, t);
} else {
runLoopAgain = true;
} }
} }
} while (runLoopAgain); } while (runLoopAgain);
for (Table t : tables) {
if (t.getName() != null && Table.EXTERNAL_TABLE_ENGINE.equals(t.getTableType()) && !t.isHidden()) {
db.removeSchemaObject(session, t);
}
}
session.findLocalTempTable(null); session.findLocalTempTable(null);
ArrayList<SchemaObject> list = New.arrayList(); ArrayList<SchemaObject> list = New.arrayList();
list.addAll(db.getAllSchemaObjects(DbObject.SEQUENCE)); list.addAll(db.getAllSchemaObjects(DbObject.SEQUENCE));
......
...@@ -1643,6 +1643,8 @@ public class Database implements DataHandler { ...@@ -1643,6 +1643,8 @@ public class Database implements DataHandler {
for (Table t : getAllTablesAndViews(false)) { for (Table t : getAllTablesAndViews(false)) {
if (except == t) { if (except == t) {
continue; continue;
} else if (Table.VIEW.equals(t.getTableType())) {
continue;
} }
set.clear(); set.clear();
t.addDependencies(set); t.addDependencies(set);
......
...@@ -7,10 +7,13 @@ ...@@ -7,10 +7,13 @@
package org.h2.table; package org.h2.table;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.command.dml.Query; import org.h2.command.dml.Query;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.engine.DbObject;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.engine.User; import org.h2.engine.User;
import org.h2.expression.Expression; import org.h2.expression.Expression;
...@@ -503,5 +506,17 @@ public class TableView extends Table { ...@@ -503,5 +506,17 @@ public class TableView extends Table {
public boolean isTableExpression() { public boolean isTableExpression() {
return tableExpression; return tableExpression;
} }
@Override
public void addDependencies(HashSet<DbObject> dependencies) {
super.addDependencies(dependencies);
if (tables != null) {
for (Table t : tables) {
if (!Table.VIEW.equals(t.getTableType())) {
t.addDependencies(dependencies);
}
}
}
}
} }
...@@ -34,11 +34,20 @@ public class TestDrop extends TestBase { ...@@ -34,11 +34,20 @@ public class TestDrop extends TestBase {
conn = getConnection("drop"); conn = getConnection("drop");
stat = conn.createStatement(); stat = conn.createStatement();
testTableDependsOnView();
testComputedColumnDependency(); testComputedColumnDependency();
conn.close(); conn.close();
deleteDb("drop"); deleteDb("drop");
} }
private void testTableDependsOnView() throws SQLException {
stat.execute("drop all objects");
stat.execute("create table a(x int)");
stat.execute("create view b as select * from a");
stat.execute("create table c(y int check (select count(*) from b) = 0)");
stat.execute("drop all objects");
}
private void testComputedColumnDependency() throws SQLException { private void testComputedColumnDependency() throws SQLException {
stat.execute("DROP ALL OBJECTS"); stat.execute("DROP ALL OBJECTS");
...@@ -50,4 +59,5 @@ public class TestDrop extends TestBase { ...@@ -50,4 +59,5 @@ public class TestDrop extends TestBase {
stat.execute("CREATE TABLE TEST_SCHEMA.B (B INT AS SELECT A FROM TEST_SCHEMA.A);"); stat.execute("CREATE TABLE TEST_SCHEMA.B (B INT AS SELECT A FROM TEST_SCHEMA.A);");
stat.execute("DROP SCHEMA TEST_SCHEMA"); stat.execute("DROP SCHEMA TEST_SCHEMA");
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论