提交 c84e4da0 authored 作者: noelgrandin's avatar noelgrandin

Improve error message when we have a unique constraint violation, displays the…

Improve error message when we have a unique constraint violation, displays the offending key in the error message
上级 110e1596
...@@ -33,6 +33,7 @@ Change Log ...@@ -33,6 +33,7 @@ Change Log
</li><li>Issue 476: Broken link in jaqu.html </li><li>Issue 476: Broken link in jaqu.html
</li><li>Fix potential UTF8 encoding issue in org.h2.store.FileStore, reported by Juerg Spiess </li><li>Fix potential UTF8 encoding issue in org.h2.store.FileStore, reported by Juerg Spiess
</li><li>Improve error message when check constraint is broken, test case from Gili (cowwoc) </li><li>Improve error message when check constraint is broken, test case from Gili (cowwoc)
</li><li>Improve error message when we have a unique constraint violation, displays the offending key in the error message
</li></ul> </li></ul>
<h2>Version 1.3.172 (2013-05-25)</h2> <h2>Version 1.3.172 (2013-05-25)</h2>
......
...@@ -92,8 +92,11 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index { ...@@ -92,8 +92,11 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
* *
* @return the exception * @return the exception
*/ */
protected DbException getDuplicateKeyException() { protected DbException getDuplicateKeyException(String key) {
String sql = getName() + " ON " + table.getSQL() + "(" + getColumnListSQL() + ")"; String sql = getName() + " ON " + table.getSQL() + "(" + getColumnListSQL() + ")";
if (key != null) {
sql += " VALUES " + key;
}
DbException e = DbException.get(ErrorCode.DUPLICATE_KEY_1, sql); DbException e = DbException.get(ErrorCode.DUPLICATE_KEY_1, sql);
e.setSource(this); e.setSource(this);
return e; return e;
......
...@@ -52,7 +52,7 @@ public class HashIndex extends BaseIndex { ...@@ -52,7 +52,7 @@ public class HashIndex extends BaseIndex {
Object old = rows.get(key); Object old = rows.get(key);
if (old != null) { if (old != null) {
// TODO index duplicate key for hash indexes: is this allowed? // TODO index duplicate key for hash indexes: is this allowed?
throw getDuplicateKeyException(); throw getDuplicateKeyException(key.toString());
} }
rows.put(key, row.getKey()); rows.put(key, row.getKey());
} }
......
...@@ -118,7 +118,7 @@ public abstract class PageBtree extends Page { ...@@ -118,7 +118,7 @@ public abstract class PageBtree extends Page {
if (comp == 0) { if (comp == 0) {
if (add && index.indexType.isUnique()) { if (add && index.indexType.isUnique()) {
if (!index.containsNullAndAllowMultipleNull(compare)) { if (!index.containsNullAndAllowMultipleNull(compare)) {
throw index.getDuplicateKeyException(); throw index.getDuplicateKeyException(compare.toString());
} }
} }
if (compareKeys) { if (compareKeys) {
......
...@@ -94,9 +94,9 @@ public class PageDataIndex extends PageIndex { ...@@ -94,9 +94,9 @@ public class PageDataIndex extends PageIndex {
} }
@Override @Override
public DbException getDuplicateKeyException() { public DbException getDuplicateKeyException(String key) {
if (fastDuplicateKeyException == null) { if (fastDuplicateKeyException == null) {
fastDuplicateKeyException = super.getDuplicateKeyException(); fastDuplicateKeyException = super.getDuplicateKeyException(null);
} }
return fastDuplicateKeyException; return fastDuplicateKeyException;
} }
......
...@@ -154,7 +154,7 @@ public class PageDataLeaf extends PageData { ...@@ -154,7 +154,7 @@ public class PageDataLeaf extends PageData {
private int findInsertionPoint(long key) { private int findInsertionPoint(long key) {
int x = find(key); int x = find(key);
if (x < entryCount && keys[x] == key) { if (x < entryCount && keys[x] == key) {
throw index.getDuplicateKeyException(); throw index.getDuplicateKeyException(""+key);
} }
return x; return x;
} }
......
...@@ -65,7 +65,7 @@ public class TreeIndex extends BaseIndex { ...@@ -65,7 +65,7 @@ public class TreeIndex extends BaseIndex {
if (compare == 0) { if (compare == 0) {
if (indexType.isUnique()) { if (indexType.isUnique()) {
if (!containsNullAndAllowMultipleNull(row)) { if (!containsNullAndAllowMultipleNull(row)) {
throw getDuplicateKeyException(); throw getDuplicateKeyException(row.toString());
} }
} }
compare = compareKeys(row, r); compare = compareKeys(row, r);
......
...@@ -94,7 +94,7 @@ public class MVSecondaryIndex extends BaseIndex { ...@@ -94,7 +94,7 @@ public class MVSecondaryIndex extends BaseIndex {
SearchRow r2 = getRow(key.getList()); SearchRow r2 = getRow(key.getList());
if (compareRows(row, r2) == 0) { if (compareRows(row, r2) == 0) {
if (!containsNullAndAllowMultipleNull(r2)) { if (!containsNullAndAllowMultipleNull(r2)) {
throw getDuplicateKeyException(); throw getDuplicateKeyException(key.toString());
} }
} }
} }
......
...@@ -13,7 +13,7 @@ import java.sql.SQLException; ...@@ -13,7 +13,7 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.HashMap; import java.util.HashMap;
import java.util.Random; import java.util.Random;
import org.h2.constant.ErrorCode;
import org.h2.result.SortOrder; import org.h2.result.SortOrder;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.New; import org.h2.util.New;
...@@ -40,6 +40,7 @@ public class TestIndex extends TestBase { ...@@ -40,6 +40,7 @@ public class TestIndex extends TestBase {
public void test() throws SQLException { public void test() throws SQLException {
deleteDb("index"); deleteDb("index");
testErrorMessage(); testErrorMessage();
testDuplicateKeyException();
testNonUniqueHashIndex(); testNonUniqueHashIndex();
testRenamePrimaryKey(); testRenamePrimaryKey();
testRandomized(); testRandomized();
...@@ -125,6 +126,24 @@ public class TestIndex extends TestBase { ...@@ -125,6 +126,24 @@ public class TestIndex extends TestBase {
stat.execute("drop table test"); stat.execute("drop table test");
} }
private void testDuplicateKeyException() throws SQLException {
reconnect();
stat.execute("create table test(id int primary key, name varchar(255))");
stat.execute("create unique index idx_test_name on test(name)");
stat.execute("insert into TEST values(1, 'Hello')");
try {
stat.execute("insert into TEST values(2, 'Hello')");
fail();
} catch (SQLException ex) {
assertEquals(ErrorCode.DUPLICATE_KEY_1, ex.getErrorCode());
String m = ex.getMessage();
int start = m.indexOf('\"'), end = m.indexOf('\"', start + 1);
String s = m.substring(start + 1, end);
assertEquals("IDX_TEST_NAME ON PUBLIC.TEST(NAME) VALUES ( /* 2 */ 'Hello' )", s);
}
stat.execute("drop table test");
}
private void testNonUniqueHashIndex() throws SQLException { private void testNonUniqueHashIndex() throws SQLException {
reconnect(); reconnect();
stat.execute("create memory table test(id bigint, data bigint)"); stat.execute("create memory table test(id bigint, data bigint)");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论