Skip to content

Commit

Permalink
refactor: make PSQLState enum consts for integrity constraint violati…
Browse files Browse the repository at this point in the history
…ons (#1699)

* refactor: make PSQLState enum consts for integrity constraint violations

Previously the PSQLState enum did not include values for any of the
integrity constraint violation error codes mentioned in the PostgreSQL
docs (as seen under Class 25 here:
https://www.postgresql.org/docs/current/errcodes-appendix.html); this
required hardcoding or the creation of consts wherever they were needed
(as seen in LogServerMessagePropertyTest.java). This commit adds all of
them (except restrict_violation which doesn't seem to appear in the
wild) and creates a test checking for each of them.
  • Loading branch information
MSGoodman committed Feb 7, 2020
1 parent a95b3e5 commit cc31c13
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
6 changes: 6 additions & 0 deletions pgjdbc/src/main/java/org/postgresql/util/PSQLState.java
Expand Up @@ -58,6 +58,12 @@ public enum PSQLState {
MOST_SPECIFIC_TYPE_DOES_NOT_MATCH("2200G"),
INVALID_PARAMETER_VALUE("22023"),

NOT_NULL_VIOLATION("23502"),
FOREIGN_KEY_VIOLATION("23503"),
UNIQUE_VIOLATION("23505"),
CHECK_VIOLATION("23514"),
EXCLUSION_VIOLATION("23P01"),

INVALID_CURSOR_STATE("24000"),

TRANSACTION_STATE_INVALID("25000"),
Expand Down
Expand Up @@ -8,6 +8,7 @@
import org.postgresql.PGProperty;
import org.postgresql.core.ServerVersion;
import org.postgresql.test.TestUtil;
import org.postgresql.util.PSQLState;

import org.junit.Assert;
import org.junit.Assume;
Expand All @@ -27,7 +28,6 @@ public class LogServerMessagePropertyTest {
private static final String SECRET_VALUE = "some_secret_value";
private static final String INSERT_SQL =
"INSERT INTO pg_temp.lms_test (id) VALUES ('" + SECRET_VALUE + "')";
private static final String UNIQUE_VIOLATION_SQL_STATE = "23505";

/**
* Creates a connection with the additional properties, use it to
Expand All @@ -44,7 +44,7 @@ private static String testViolatePrimaryKey(Properties props) throws SQLExceptio
// Second insert should throw a duplicate key error
TestUtil.execute(INSERT_SQL, conn);
} catch (SQLException e) {
Assert.assertEquals("SQL state must be for a unique violation", UNIQUE_VIOLATION_SQL_STATE, e.getSQLState());
Assert.assertEquals("SQL state must be for a unique violation", PSQLState.UNIQUE_VIOLATION.getState(), e.getSQLState());
return e.getMessage();
} finally {
conn.close();
Expand Down
Expand Up @@ -12,6 +12,7 @@
import org.postgresql.core.ServerVersion;
import org.postgresql.test.TestUtil;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
import org.postgresql.util.ServerErrorMessage;

import org.junit.Test;
Expand Down Expand Up @@ -57,6 +58,7 @@ public void testPrimaryKey() throws Exception {
assertEquals("public", err.getSchema());
assertEquals("testerr", err.getTable());
assertEquals("testerr_pk", err.getConstraint());
assertEquals(PSQLState.UNIQUE_VIOLATION.getState(), err.getSQLState());
assertNull(err.getDatatype());
assertNull(err.getColumn());
}
Expand Down Expand Up @@ -95,4 +97,82 @@ public void testDatatype() throws Exception {
stmt.close();
}

@Test
public void testNotNullConstraint() throws Exception {
Statement stmt = con.createStatement();
try {
stmt.executeUpdate("INSERT INTO testerr (val) VALUES (1)");
fail("Should have thrown a not-null exception.");
} catch (SQLException sqle) {
ServerErrorMessage err = ((PSQLException) sqle).getServerErrorMessage();
assertEquals("public", err.getSchema());
assertEquals("testerr", err.getTable());
assertEquals("id", err.getColumn());
assertEquals(PSQLState.NOT_NULL_VIOLATION.getState(), err.getSQLState());
assertNull(err.getDatatype());
}
stmt.close();
}

@Test
public void testForeignKeyConstraint() throws Exception {
TestUtil.createTable(con, "testerr_foreign", "id int not null, testerr_id int,"
+ "CONSTRAINT testerr FOREIGN KEY (testerr_id) references testerr(id)");
Statement stmt = con.createStatement();
stmt.executeUpdate("INSERT INTO testerr (id, val) VALUES (1, 1)");
try {
stmt.executeUpdate("INSERT INTO testerr_foreign (id, testerr_id) VALUES (1, 2)");
fail("Should have thrown a foreign key exception.");
} catch (SQLException sqle) {
ServerErrorMessage err = ((PSQLException) sqle).getServerErrorMessage();
assertEquals("public", err.getSchema());
assertEquals("testerr_foreign", err.getTable());
assertEquals(PSQLState.FOREIGN_KEY_VIOLATION.getState(), err.getSQLState());
assertNull(err.getDatatype());
assertNull(err.getColumn());
}
TestUtil.dropTable(con, "testerr_foreign");
stmt.close();
}

@Test
public void testCheckConstraint() throws Exception {
TestUtil.createTable(con, "testerr_check", "id int not null, max10 int CHECK (max10 < 11)");
Statement stmt = con.createStatement();
stmt.executeUpdate("INSERT INTO testerr_check (id, max10) VALUES (1, 5)");
try {
stmt.executeUpdate("INSERT INTO testerr_check (id, max10) VALUES (2, 11)");
fail("Should have thrown a check exception.");
} catch (SQLException sqle) {
ServerErrorMessage err = ((PSQLException) sqle).getServerErrorMessage();
assertEquals("public", err.getSchema());
assertEquals("testerr_check", err.getTable());
assertEquals(PSQLState.CHECK_VIOLATION.getState(), err.getSQLState());
assertNull(err.getDatatype());
assertNull(err.getColumn());
}
TestUtil.dropTable(con, "testerr_check");
stmt.close();
}

@Test
public void testExclusionConstraint() throws Exception {
TestUtil.createTable(con, "testerr_exclude", "id int, EXCLUDE (id WITH =)");
Statement stmt = con.createStatement();
stmt.executeUpdate("INSERT INTO testerr_exclude (id) VALUES (1108)");
try {
stmt.executeUpdate("INSERT INTO testerr_exclude (id) VALUES (1108)");
fail("Should have thrown an exclusion exception.");
} catch (SQLException sqle) {
ServerErrorMessage err = ((PSQLException) sqle).getServerErrorMessage();
assertEquals("public", err.getSchema());
assertEquals("testerr_exclude", err.getTable());
assertEquals(PSQLState.EXCLUSION_VIOLATION.getState(), err.getSQLState());
assertNull(err.getDatatype());
assertNull(err.getColumn());
}
TestUtil.dropTable(con, "testerr_exclude");
stmt.close();
}

}

0 comments on commit cc31c13

Please sign in to comment.