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

Referenced objects in check constraints could be dropped, which resulted in a…

Referenced objects in check constraints could be dropped, which resulted in a database that can't be opened normally.
上级 42edd760
......@@ -9,6 +9,7 @@ package org.h2.constraint;
import java.util.HashSet;
import org.h2.engine.DbObject;
import org.h2.engine.Session;
import org.h2.expression.ExpressionVisitor;
import org.h2.index.Index;
import org.h2.message.DbException;
import org.h2.message.Trace;
......@@ -179,4 +180,15 @@ public abstract class Constraint extends SchemaObjectBase implements Comparable<
return table.isHidden();
}
/**
* Visit all elements in the constraint.
*
* @param visitor the visitor
* @return true if every visited expression returned true, or if there are
* no expressions
*/
public boolean isEverything(ExpressionVisitor visitor) {
return true;
}
}
......@@ -140,4 +140,8 @@ public class ConstraintCheck extends Constraint {
// nothing to do
}
public boolean isEverything(ExpressionVisitor visitor) {
return expr.isEverything(visitor);
}
}
......@@ -311,6 +311,10 @@ public abstract class Table extends SchemaObjectBase {
* @param dependencies the current set of dependencies
*/
public void addDependencies(HashSet<DbObject> dependencies) {
if (dependencies.contains(this)) {
// avoid endless recursion
return;
}
if (sequences != null) {
for (Sequence s : sequences) {
dependencies.add(s);
......@@ -320,6 +324,12 @@ public abstract class Table extends SchemaObjectBase {
for (Column col : columns) {
col.isEverything(visitor);
}
if (constraints != null) {
for (Constraint c : constraints) {
c.isEverything(visitor);
}
}
dependencies.add(this);
}
public ArrayList<DbObject> getChildren() {
......
......@@ -37,6 +37,7 @@ public class TestCases extends TestBase {
}
public void test() throws Exception {
testDependencies();
testConvertType();
testSortedSelect();
testMaxMemoryRowsDistinct();
......@@ -92,6 +93,43 @@ public class TestCases extends TestBase {
deleteDb("cases");
}
private void testDependencies() throws SQLException {
deleteDb("cases");
Connection conn = getConnection("cases");
Statement stat = conn.createStatement();
// avoid endless recursion when adding dependencies
stat.execute("create table test(id int primary key, parent int)");
stat.execute("alter table test add constraint test check (select count(*) from test) < 10");
stat.execute("create table b()");
stat.execute("drop table b");
stat.execute("drop table test");
// ensure the dependency is detected
stat.execute("create alias is_positive as 'boolean isPositive(int x) { return x > 0; }'");
stat.execute("create table a(a integer, constraint test check is_positive(a))");
try {
stat.execute("drop alias is_positive");
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.CANNOT_DROP_2, e.getErrorCode());
}
stat.execute("drop table a");
stat.execute("drop alias is_positive");
// ensure trying to reference the table fails
// (otherwise re-opening the database is not possible)
stat.execute("create table test(id int primary key)");
try {
stat.execute("alter table test alter column id set default ifnull((select max(id) from test for update)+1, 0)");
fail();
} catch (SQLException e) {
assertEquals(ErrorCode.COLUMN_IS_REFERENCED_1, e.getErrorCode());
}
stat.execute("drop table test");
conn.close();
}
private void testConvertType() throws SQLException {
deleteDb("cases");
Connection conn = getConnection("cases");
......@@ -101,6 +139,7 @@ public class TestCases extends TestBase {
assertEquals(2, meta.getPrecision(1));
assertEquals(2, meta.getScale(1));
stat.execute("alter table test add column y int");
stat.execute("drop table test");
conn.close();
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论