提交 efe8c198 authored 作者: sylvain-ilm's avatar sylvain-ilm

added STANDARD_DROP_TABLE_RESTRICT setting

上级 697a9691
...@@ -84,12 +84,15 @@ public class DropTable extends SchemaCommand { ...@@ -84,12 +84,15 @@ public class DropTable extends SchemaCommand {
buff.append(v.getName()); buff.append(v.getName());
} }
} }
final List<Constraint> constraints = table.getConstraints(); if (session.getDatabase()
if (constraints != null && constraints.size() > 0) { .getSettings().standardDropTableRestrict) {
for (Constraint c : constraints) { final List<Constraint> constraints = table.getConstraints();
if (c.getTable() != table) { if (constraints != null && constraints.size() > 0) {
buff.appendExceptFirst(", "); for (Constraint c : constraints) {
buff.append(c.getName()); if (c.getTable() != table) {
buff.appendExceptFirst(", ");
buff.append(c.getName());
}
} }
} }
} }
......
...@@ -350,6 +350,17 @@ public class DbSettings extends SettingsBase { ...@@ -350,6 +350,17 @@ public class DbSettings extends SettingsBase {
*/ */
public final boolean multiThreaded = get("MULTI_THREADED", false); public final boolean multiThreaded = get("MULTI_THREADED", false);
/**
* Database setting <code>STANDARD_DROP_TABLE_RESTRICT</code> (default:
* false).<br />
* <code>true</code> if DROP TABLE RESTRICT should fail if there's any
* foreign key referencing the table to be dropped. <code>false</code> if
* foreign keys referencing the table to be dropped should be silently
* dropped as well.
*/
public final boolean standardDropTableRestrict = get(
"STANDARD_DROP_TABLE_RESTRICT", false);
private DbSettings(HashMap<String, String> s) { private DbSettings(HashMap<String, String> s) {
super(s); super(s);
} }
......
...@@ -11,6 +11,7 @@ import java.util.ArrayList; ...@@ -11,6 +11,7 @@ import java.util.ArrayList;
import java.util.Properties; import java.util.Properties;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.Driver; import org.h2.Driver;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.store.fs.FilePathRec; import org.h2.store.fs.FilePathRec;
...@@ -431,6 +432,7 @@ java org.h2.test.TestAll timer ...@@ -431,6 +432,7 @@ java org.h2.test.TestAll timer
/** If not null the database should be opened with the collation parameter */ /** If not null the database should be opened with the collation parameter */
public String collation; public String collation;
public boolean stdDropTableRestrict;
/** /**
* The AB-BA locking detector. * The AB-BA locking detector.
...@@ -618,6 +620,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -618,6 +620,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
defrag = false; defrag = false;
traceLevelFile = throttle = 0; traceLevelFile = throttle = 0;
cipher = null; cipher = null;
stdDropTableRestrict = false;
// memory is a good match for multi-threaded, makes things happen // memory is a good match for multi-threaded, makes things happen
// faster, more chance of exposing race conditions // faster, more chance of exposing race conditions
...@@ -1127,6 +1130,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -1127,6 +1130,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
appendIf(buff, defrag, "defrag"); appendIf(buff, defrag, "defrag");
appendIf(buff, splitFileSystem, "split"); appendIf(buff, splitFileSystem, "split");
appendIf(buff, collation != null, collation); appendIf(buff, collation != null, collation);
appendIf(buff, stdDropTableRestrict, "stdDropTableRestrict");
return buff.toString(); return buff.toString();
} }
......
...@@ -34,6 +34,7 @@ import java.util.ArrayList; ...@@ -34,6 +34,7 @@ import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.SimpleTimeZone; import java.util.SimpleTimeZone;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.h2.jdbc.JdbcConnection; import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.store.fs.FilePath; import org.h2.store.fs.FilePath;
...@@ -333,6 +334,9 @@ public abstract class TestBase { ...@@ -333,6 +334,9 @@ public abstract class TestBase {
if (config.collation != null) { if (config.collation != null) {
url = addOption(url, "COLLATION", config.collation); url = addOption(url, "COLLATION", config.collation);
} }
if (config.stdDropTableRestrict) {
url = addOption(url, "STANDARD_DROP_TABLE_RESTRICT", "TRUE");
}
return "jdbc:h2:" + url; return "jdbc:h2:" + url;
} }
......
...@@ -279,11 +279,23 @@ public class TestCases extends TestBase { ...@@ -279,11 +279,23 @@ public class TestCases extends TestBase {
conn.close(); conn.close();
} }
private void testDropTable() throws SQLException {
final boolean prevVal = config.stdDropTableRestrict;
try {
for (final boolean newVal : new boolean[] { true, false }) {
config.stdDropTableRestrict = newVal;
_testDropTable();
}
} finally {
config.stdDropTableRestrict = prevVal;
}
}
private static enum DropDependent { private static enum DropDependent {
NONE, VIEW, FOREIGN_KEY; NONE, VIEW, FOREIGN_KEY;
} }
private void testDropTable() throws SQLException { private void _testDropTable() throws SQLException {
trace("testDrop"); trace("testDrop");
for (final boolean restrict : new boolean[] { true, false }) { for (final boolean restrict : new boolean[] { true, false }) {
...@@ -301,7 +313,10 @@ public class TestCases extends TestBase { ...@@ -301,7 +313,10 @@ public class TestCases extends TestBase {
} }
// drop allowed if no references or cascade // drop allowed if no references or cascade
final boolean expectedDropSuccess = dropDep == DropDependent.NONE || !restrict; final boolean expectedDropSuccess = dropDep == DropDependent.NONE
|| (!config.stdDropTableRestrict
&& dropDep == DropDependent.FOREIGN_KEY)
|| !restrict;
assertThrows(expectedDropSuccess ? 0 : ErrorCode.CANNOT_DROP_2, stat).execute("drop table test " + (restrict ? "restrict" : "cascade")); assertThrows(expectedDropSuccess ? 0 : ErrorCode.CANNOT_DROP_2, stat).execute("drop table test " + (restrict ? "restrict" : "cascade"));
assertThrows(expectedDropSuccess ? ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1 : 0, stat).execute("select * from test"); assertThrows(expectedDropSuccess ? ErrorCode.TABLE_OR_VIEW_NOT_FOUND_1 : 0, stat).execute("select * from test");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论