postgresql-jdbc.git / summary / log / commit / refs
commit e9ac5f8d964202ab5d43e401d74dcd76cefd112e
Author: Kris Jurka <jurka@ejurka.com>
Date: Fri Feb 01 00:40:41 2013 +0000
Expose enhanced error message fields from constraint violations.
The server now provides the schema, table, column, datatype, and
constraint names for certain errors. So expose that to users so
they don't have to go rummaging through the error text trying
to find it.
The server doesn't always provide all the fields and doesn't cover
all the error messages, but it's a good start. In the future it
would be good to expose this information in a PGXXX class instead
of the supposedly private ServerErrorMessage.
org/postgresql/test/jdbc2/Jdbc2TestSuite.java | 3 +
org/postgresql/test/jdbc2/ServerErrorTest.java | 100 +++++++++++++++++++++++++
org/postgresql/util/ServerErrorMessage.java | 30 ++++++++
3 files changed, 133 insertions(+)
diff --git a/org/postgresql/test/jdbc2/Jdbc2TestSuite.java b/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
index 128009c6..d87591b0 100644
--- a/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
+++ b/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
@@ -94,6 +94,9 @@ public class Jdbc2TestSuite extends TestSuite
if (TestUtil.isProtocolVersion(conn, 3)) {
suite.addTestSuite(CopyTest.class);
}
+ if (TestUtil.haveMinimumServerVersion(conn, "9.3")) {
+ suite.addTestSuite(ServerErrorTest.class);
+ }
conn.close();
// That's all folks
diff --git a/org/postgresql/test/jdbc2/ServerErrorTest.java b/org/postgresql/test/jdbc2/ServerErrorTest.java
new file mode 100644
index 00000000..e2481302
--- /dev/null
+++ b/org/postgresql/test/jdbc2/ServerErrorTest.java
@@ -0,0 +1,100 @@
+/*-------------------------------------------------------------------------
+*
+* Copyright (c) 2013, PostgreSQL Global Development Group
+*
+*
+*-------------------------------------------------------------------------
+*/
+package org.postgresql.test.jdbc2;
+
+import org.postgresql.test.TestUtil;
+import org.postgresql.util.PSQLException;
+import org.postgresql.util.ServerErrorMessage;
+import junit.framework.TestCase;
+import java.sql.*;
+
+/*
+ * Test that enhanced error reports return the correct origin
+ * for constraint violation errors.
+ */
+public class ServerErrorTest extends TestCase
+{
+
+ private Connection con;
+
+ public ServerErrorTest(String name)
+ {
+ super(name);
+ }
+
+ protected void setUp() throws Exception
+ {
+ con = TestUtil.openDB();
+ Statement stmt = con.createStatement();
+
+ stmt.execute("CREATE DOMAIN testdom AS int4 CHECK (value < 10)");
+ TestUtil.createTable(con, "testerr", "id int not null, val testdom not null");
+ stmt.execute("ALTER TABLE testerr ADD CONSTRAINT testerr_pk PRIMARY KEY (id)");
+ stmt.close();
+ }
+
+ protected void tearDown() throws Exception
+ {
+ TestUtil.dropTable(con, "testerr");
+ Statement stmt = con.createStatement();
+ stmt.execute("DROP DOMAIN testdom");
+ stmt.close();
+ TestUtil.closeDB(con);
+ }
+
+ public void testPrimaryKey() throws Exception
+ {
+ Statement stmt = con.createStatement();
+ stmt.executeUpdate("INSERT INTO testerr (id, val) VALUES (1, 1)");
+ try {
+ stmt.executeUpdate("INSERT INTO testerr (id, val) VALUES (1, 1)");
+ fail("Should have thrown a duplicate key exception.");
+ } catch (SQLException sqle) {
+ ServerErrorMessage err = ((PSQLException)sqle).getServerErrorMessage();
+ assertEquals("public", err.getSchema());
+ assertEquals("testerr", err.getTable());
+ assertEquals("testerr_pk", err.getConstraint());
+ assertNull(err.getDatatype());
+ assertNull(err.getColumn());
+ }
+ stmt.close();
+ }
+
+ public void testColumn() throws Exception
+ {
+ Statement stmt = con.createStatement();
+ try {
+ stmt.executeUpdate("INSERT INTO testerr (id, val) VALUES (1, NULL)");
+ fail("Should have thrown a not null constraint violation.");
+ } catch (SQLException sqle) {
+ ServerErrorMessage err = ((PSQLException)sqle).getServerErrorMessage();
+ assertEquals("public", err.getSchema());
+ assertEquals("testerr", err.getTable());
+ assertEquals("val", err.getColumn());
+ assertNull(err.getDatatype());
+ assertNull(err.getConstraint());
+ }
+ stmt.close();
+ }
+
+ public void testDatatype() throws Exception
+ {
+ Statement stmt = con.createStatement();
+ try {
+ stmt.executeUpdate("INSERT INTO testerr (id, val) VALUES (1, 20)");
+ fail("Should have thrown a constraint violation.");
+ } catch (SQLException sqle) {
+ ServerErrorMessage err = ((PSQLException)sqle).getServerErrorMessage();
+ assertEquals("public", err.getSchema());
+ assertEquals("testdom", err.getDatatype());
+ assertEquals("testdom_check", err.getConstraint());
+ }
+ stmt.close();
+ }
+
+}
diff --git a/org/postgresql/util/ServerErrorMessage.java b/org/postgresql/util/ServerErrorMessage.java
index ded31270..d9ab98b1 100644
--- a/org/postgresql/util/ServerErrorMessage.java
+++ b/org/postgresql/util/ServerErrorMessage.java
@@ -26,6 +26,11 @@ public class ServerErrorMessage implements Serializable
private static final Character SQLSTATE = new Character('C');
private static final Character INTERNAL_POSITION = new Character('p');
private static final Character INTERNAL_QUERY = new Character('q');
+ private static final Character SCHEMA = new Character('s');
+ private static final Character TABLE = new Character('t');
+ private static final Character COLUMN = new Character('c');
+ private static final Character DATATYPE = new Character('d');
+ private static final Character CONSTRAINT = new Character('n');
private final Map m_mesgParts = new HashMap();
private final int verbosity;
@@ -91,6 +96,31 @@ public class ServerErrorMessage implements Serializable
return (String)m_mesgParts.get(WHERE);
}
+ public String getSchema()
+ {
+ return (String)m_mesgParts.get(SCHEMA);
+ }
+
+ public String getTable()
+ {
+ return (String)m_mesgParts.get(TABLE);
+ }
+
+ public String getColumn()
+ {
+ return (String)m_mesgParts.get(COLUMN);
+ }
+
+ public String getDatatype()
+ {
+ return (String)m_mesgParts.get(DATATYPE);
+ }
+
+ public String getConstraint()
+ {
+ return (String)m_mesgParts.get(CONSTRAINT);
+ }
+
public String getFile()
{
return (String)m_mesgParts.get(FILE);
[parent: 2bf33c277e0c]