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

Referential integrity: when adding a referential integrity constraint failed,…

Referential integrity: when adding a referential integrity constraint failed, and if creating the constraint automatically created an index, this index was not removed.
上级 da1e29c7
...@@ -18,7 +18,9 @@ Change Log ...@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>The auto-analyze feature now only reads 1000 rows per table instead of 10000. <ul><li>Referential integrity: when adding a referential integrity constraint failed,
and if creating the constraint automatically created an index, this index was not removed.
</li><li>The auto-analyze feature now only reads 1000 rows per table instead of 10000.
</li><li>The optimization for IN(...) queries combined with OR could result </li><li>The optimization for IN(...) queries combined with OR could result
in a strange exception of the type "column x must be included in the group by list". in a strange exception of the type "column x must be included in the group by list".
</li><li>Issue 454: Use Charset for type-safety. </li><li>Issue 454: Use Charset for type-safety.
......
...@@ -50,6 +50,7 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -50,6 +50,7 @@ public class AlterTableAddConstraint extends SchemaCommand {
private boolean checkExisting; private boolean checkExisting;
private boolean primaryKeyHash; private boolean primaryKeyHash;
private final boolean ifNotExists; private final boolean ifNotExists;
private ArrayList<Index> createdIndexes = New.arrayList();
public AlterTableAddConstraint(Session session, Schema schema, boolean ifNotExists) { public AlterTableAddConstraint(Session session, Schema schema, boolean ifNotExists) {
super(session, schema); super(session, schema);
...@@ -67,6 +68,11 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -67,6 +68,11 @@ public class AlterTableAddConstraint extends SchemaCommand {
public int update() { public int update() {
try { try {
return tryUpdate(); return tryUpdate();
} catch (DbException e) {
for (Index index : createdIndexes) {
session.getDatabase().removeSchemaObject(session, index);
}
throw e;
} finally { } finally {
getSchema().freeUniqueName(constraintName); getSchema().freeUniqueName(constraintName);
} }
...@@ -259,7 +265,9 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -259,7 +265,9 @@ public class AlterTableAddConstraint extends SchemaCommand {
String prefix = constraintName == null ? "CONSTRAINT" : constraintName; String prefix = constraintName == null ? "CONSTRAINT" : constraintName;
String indexName = t.getSchema().getUniqueIndexName(session, t, prefix + "_INDEX_"); String indexName = t.getSchema().getUniqueIndexName(session, t, prefix + "_INDEX_");
try { try {
return t.addIndex(session, indexName, indexId, cols, indexType, true, null); Index index = t.addIndex(session, indexName, indexId, cols, indexType, true, null);
createdIndexes.add(index);
return index;
} finally { } finally {
getSchema().freeUniqueName(indexName); getSchema().freeUniqueName(indexName);
} }
......
...@@ -493,7 +493,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -493,7 +493,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
private void runTests() throws SQLException { private void runTests() throws SQLException {
int test; int test;
mvStore = true; mvStore = false;
smallLog = big = networked = memory = ssl = false; smallLog = big = networked = memory = ssl = false;
diskResult = traceSystemOut = diskUndo = false; diskResult = traceSystemOut = diskUndo = false;
...@@ -565,123 +565,111 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1` ...@@ -565,123 +565,111 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
beforeTest(); beforeTest();
// db // db
//// new TestScriptSimple().runTest(this); new TestScriptSimple().runTest(this);
new TestScript().runTest(this); new TestScript().runTest(this);
if(true)System.exit(0); new TestAlter().runTest(this);
new TestAlterSchemaRename().runTest(this);
// new TestAlter().runTest(this); new TestAutoRecompile().runTest(this);
// new TestAlterSchemaRename().runTest(this); new TestBitField().runTest(this);
// new TestAutoRecompile().runTest(this); new TestBackup().runTest(this);
// new TestBitField().runTest(this); new TestBigDb().runTest(this);
//// new TestBackup().runTest(this); new TestBigResult().runTest(this);
// new TestBigDb().runTest(this); new TestCases().runTest(this);
// new TestBigResult().runTest(this); new TestCheckpoint().runTest(this);
// new TestCases().runTest(this); new TestCluster().runTest(this);
// new TestCheckpoint().runTest(this); new TestCompatibility().runTest(this);
//// new TestCluster().runTest(this); new TestCsv().runTest(this);
// new TestCompatibility().runTest(this); new TestDateStorage().runTest(this);
// new TestCsv().runTest(this); new TestDeadlock().runTest(this);
// new TestDateStorage().runTest(this); new TestEncryptedDb().runTest(this);
// new TestDeadlock().runTest(this); new TestExclusive().runTest(this);
// new TestEncryptedDb().runTest(this); new TestFullText().runTest(this);
// new TestExclusive().runTest(this); new TestFunctionOverload().runTest(this);
new TestFunctions().runTest(this);
// unique index on update? new TestInit().runTest(this);
//// new TestFullText().runTest(this); new TestIndex().runTest(this);
new TestLargeBlob().runTest(this);
// new TestFunctionOverload().runTest(this); new TestLinkedTable().runTest(this);
// new TestFunctions().runTest(this); new TestListener().runTest(this);
// new TestInit().runTest(this); new TestLob().runTest(this);
new TestMemoryUsage().runTest(this);
// unique index on update? new TestMultiConn().runTest(this);
//// new TestIndex().runTest(this); new TestMultiDimension().runTest(this);
// new TestLargeBlob().runTest(this); new TestMultiThread().runTest(this);
// new TestLinkedTable().runTest(this); new TestMultiThreadedKernel().runTest(this);
// new TestListener().runTest(this); new TestOpenClose().runTest(this);
new TestOptimizations().runTest(this);
// index on lob for in-memory indexes? new TestOutOfMemory().runTest(this);
//// new TestLob().runTest(this); new TestPowerOff().runTest(this);
// new TestMemoryUsage().runTest(this); new TestQueryCache().runTest(this);
// new TestMultiConn().runTest(this); new TestReadOnly().runTest(this);
// new TestMultiDimension().runTest(this); new TestRecursiveQueries().runTest(this);
// new TestMultiThread().runTest(this); new TestRights().runTest(this);
//// new TestMultiThreadedKernel().runTest(this); new TestRunscript().runTest(this);
// new TestOpenClose().runTest(this); new TestSQLInjection().runTest(this);
// new TestOptimizations().runTest(this); new TestSessionsLocks().runTest(this);
//// new TestOutOfMemory().runTest(this); new TestSelectCountNonNullColumn().runTest(this);
//// new TestPowerOff().runTest(this); new TestSequence().runTest(this);
// new TestQueryCache().runTest(this); new TestSpaceReuse().runTest(this);
//// new TestReadOnly().runTest(this); new TestSpeed().runTest(this);
// new TestRecursiveQueries().runTest(this); new TestTableEngines().runTest(this);
// new TestRights().runTest(this); new TestTempTables().runTest(this);
new TestTransaction().runTest(this);
// wrong script? new TestTriggersConstraints().runTest(this);
//// new TestRunscript().runTest(this); new TestTwoPhaseCommit().runTest(this);
new TestView().runTest(this);
// new TestSQLInjection().runTest(this); new TestViewAlterTable().runTest(this);
// new TestSessionsLocks().runTest(this); new TestViewDropView().runTest(this);
// new TestSelectCountNonNullColumn().runTest(this);
// new TestSequence().runTest(this); // jaqu
// new TestSpaceReuse().runTest(this); new AliasMapTest().runTest(this);
// new TestSpeed().runTest(this); new AnnotationsTest().runTest(this);
// new TestTableEngines().runTest(this); new ClobTest().runTest(this);
// new TestTempTables().runTest(this); new ModelsTest().runTest(this);
//// new TestTransaction().runTest(this); new SamplesTest().runTest(this);
//// new TestTriggersConstraints().runTest(this); new UpdateTest().runTest(this);
//// new TestTwoPhaseCommit().runTest(this);
// new TestView().runTest(this); // jdbc
// new TestViewAlterTable().runTest(this); new TestBatchUpdates().runTest(this);
// new TestViewDropView().runTest(this); new TestCallableStatement().runTest(this);
// new TestCancel().runTest(this);
// // jaqu new TestDatabaseEventListener().runTest(this);
// new AliasMapTest().runTest(this); new TestDriver().runTest(this);
// new AnnotationsTest().runTest(this); new TestJavaObject().runTest(this);
// new ClobTest().runTest(this); new TestLimitUpdates().runTest(this);
// new ModelsTest().runTest(this); new TestLobApi().runTest(this);
// new SamplesTest().runTest(this); new TestManyJdbcObjects().runTest(this);
// new UpdateTest().runTest(this); new TestMetaData().runTest(this);
// new TestNativeSQL().runTest(this);
// // jdbc new TestPreparedStatement().runTest(this);
// new TestBatchUpdates().runTest(this); new TestResultSet().runTest(this);
// new TestCallableStatement().runTest(this); new TestStatement().runTest(this);
// new TestCancel().runTest(this); new TestTransactionIsolation().runTest(this);
// new TestDatabaseEventListener().runTest(this); new TestUpdatableResultSet().runTest(this);
// new TestDriver().runTest(this); new TestZloty().runTest(this);
// new TestJavaObject().runTest(this);
// new TestLimitUpdates().runTest(this); // jdbcx
// new TestLobApi().runTest(this); new TestConnectionPool().runTest(this);
// new TestManyJdbcObjects().runTest(this); new TestDataSource().runTest(this);
// new TestMetaData().runTest(this); new TestXA().runTest(this);
// new TestNativeSQL().runTest(this); new TestXASimple().runTest(this);
// new TestPreparedStatement().runTest(this);
// new TestResultSet().runTest(this); // server
// new TestStatement().runTest(this); new TestAutoServer().runTest(this);
// new TestTransactionIsolation().runTest(this); new TestNestedLoop().runTest(this);
// new TestUpdatableResultSet().runTest(this); new TestWeb().runTest(this);
// new TestZloty().runTest(this);
// // mvcc & row level locking
// // jdbcx new TestMvcc1().runTest(this);
// new TestConnectionPool().runTest(this); new TestMvcc2().runTest(this);
// new TestDataSource().runTest(this); new TestMvcc3().runTest(this);
// new TestXA().runTest(this); new TestMvccMultiThreaded().runTest(this);
//// new TestXASimple().runTest(this); new TestRowLocks().runTest(this);
//
// // server // synth
// new TestAutoServer().runTest(this); new TestBtreeIndex().runTest(this);
// new TestNestedLoop().runTest(this); new TestDiskFull().runTest(this);
// new TestWeb().runTest(this); new TestCrashAPI().runTest(this);
//
// // mvcc & row level locking
// new TestMvcc1().runTest(this);
// new TestMvcc2().runTest(this);
// new TestMvcc3().runTest(this);
//// new TestMvccMultiThreaded().runTest(this);
//// new TestRowLocks().runTest(this);
//
// // synth
// new TestBtreeIndex().runTest(this);
// new TestDiskFull().runTest(this);
//// new TestCrashAPI().runTest(this);
new TestFuzzOptimizations().runTest(this); new TestFuzzOptimizations().runTest(this);
new TestLimit().runTest(this); new TestLimit().runTest(this);
new TestRandomSQL().runTest(this); new TestRandomSQL().runTest(this);
......
...@@ -36,6 +36,7 @@ public class TestTransaction extends TestBase { ...@@ -36,6 +36,7 @@ public class TestTransaction extends TestBase {
@Override @Override
public void test() throws SQLException { public void test() throws SQLException {
testContraintCreationRollback();
testCommitOnAutoCommitChange(); testCommitOnAutoCommitChange();
testConcurrentSelectForUpdate(); testConcurrentSelectForUpdate();
testLogMode(); testLogMode();
...@@ -49,6 +50,24 @@ public class TestTransaction extends TestBase { ...@@ -49,6 +50,24 @@ public class TestTransaction extends TestBase {
deleteDb("transaction"); deleteDb("transaction");
} }
private void testContraintCreationRollback() throws SQLException {
deleteDb("transaction");
Connection conn = getConnection("transaction");
Statement stat = conn.createStatement();
stat.execute("create table test(id int, p int)");
stat.execute("insert into test values(1, 2)");
try {
stat.execute("alter table test add constraint fail " +
"foreign key(p) references test(id)");
fail();
} catch (SQLException e) {
// expected
}
stat.execute("insert into test values(1, 2)");
stat.execute("drop table test");
conn.close();
}
private void testCommitOnAutoCommitChange() throws SQLException { private void testCommitOnAutoCommitChange() throws SQLException {
deleteDb("transaction"); deleteDb("transaction");
Connection conn = getConnection("transaction"); Connection conn = getConnection("transaction");
......
...@@ -128,8 +128,7 @@ int test; ...@@ -128,8 +128,7 @@ int test;
} catch (SQLException e) { } catch (SQLException e) {
// expected // expected
} }
int todo; stat.execute("update child set pid=1");
// stat.execute("update child set pid=1");
stat.execute("drop table child, parent"); stat.execute("drop table child, parent");
stat.execute("create table parent(id int)"); stat.execute("create table parent(id int)");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论