Skip to content

Commit

Permalink
fix: remove type name from cast exception of getBoolean and setObject (
Browse files Browse the repository at this point in the history
  • Loading branch information
jorsol authored and davecramer committed May 23, 2017
1 parent 9c3471f commit 394b3a2
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 36 deletions.
38 changes: 17 additions & 21 deletions pgjdbc/src/main/java/org/postgresql/jdbc/BooleanTypeUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,25 @@ private BooleanTypeUtil() {
* @throws PSQLException PSQLState.CANNOT_COERCE
*/
static boolean castToBoolean(final Object in) throws PSQLException {
LOGGER.log(Level.FINE, "Object to cast: {0}", in);
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Cast to boolean: \"{0}\"", String.valueOf(in));
}
if (in instanceof Boolean) {
return (Boolean) in;
}
if (in instanceof String) {
return from((String) in);
return fromString((String) in);
}
if (in instanceof Character) {
return from((Character) in);
return fromCharacter((Character) in);
}
if (in instanceof Number) {
return from((Number) in, in.getClass().getName());
return fromNumber((Number) in);
}
throw cannotCoerceException(in.getClass().getName());
throw new PSQLException("Cannot cast to boolean", PSQLState.CANNOT_COERCE);
}

private static boolean from(final String strval) throws PSQLException {
private static boolean fromString(final String strval) throws PSQLException {
// Leading or trailing whitespace is ignored, and case does not matter.
final String val = strval.trim();
if ("1".equals(val) || "true".equalsIgnoreCase(val)
Expand All @@ -62,10 +64,10 @@ private static boolean from(final String strval) throws PSQLException {
|| "n".equalsIgnoreCase(val) || "off".equalsIgnoreCase(val)) {
return false;
}
throw cannotCoerceException("String", val);
throw cannotCoerceException(strval);
}

private static boolean from(final Character charval) throws PSQLException {
private static boolean fromCharacter(final Character charval) throws PSQLException {
if ('1' == charval || 't' == charval || 'T' == charval
|| 'y' == charval || 'Y' == charval) {
return true;
Expand All @@ -74,33 +76,27 @@ private static boolean from(final Character charval) throws PSQLException {
|| 'n' == charval || 'N' == charval) {
return false;
}
throw cannotCoerceException("Character", charval.toString());
throw cannotCoerceException(charval);
}

private static boolean from(final Number numval, final String className) throws PSQLException {
private static boolean fromNumber(final Number numval) throws PSQLException {
// Handles BigDecimal, Byte, Short, Integer, Long Float, Double
// based on the widening primitive conversions.
double value = numval.doubleValue();
final double value = numval.doubleValue();
if (value == 1.0d) {
return true;
}
if (value == 0.0d) {
return false;
}
throw cannotCoerceException(className, String.valueOf(numval));
}

private static PSQLException cannotCoerceException(final String fromType) {
LOGGER.log(Level.FINE, "Cannot cast type {0} to boolean", fromType);
return new PSQLException(GT.tr("Cannot cast type {0} to boolean", fromType),
PSQLState.CANNOT_COERCE);
throw cannotCoerceException(numval);
}

private static PSQLException cannotCoerceException(final String fromType, final String value) {
private static PSQLException cannotCoerceException(final Object value) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.log(Level.FINE, "Cannot cast type {0} to boolean: \"{1}\"", new Object[]{fromType, value});
LOGGER.log(Level.FINE, "Cannot cast to boolean: \"{0}\"", String.valueOf(value));
}
return new PSQLException(GT.tr("Cannot cast type {0} to boolean: \"{1}\"", fromType, value),
return new PSQLException(GT.tr("Cannot cast to boolean: \"{0}\"", String.valueOf(value)),
PSQLState.CANNOT_COERCE);
}

Expand Down
4 changes: 2 additions & 2 deletions pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -1936,8 +1936,8 @@ public String getString(int columnIndex) throws SQLException {
* @param columnIndex the first column is 1, the second is 2, ...
* @return the column value; if the value is SQL <code>NULL</code>, the value returned is
* <code>false</code>
* @exception SQLException if the columnIndex is not valid; if a database access error occurs or
* this method is called on a closed result set
* @exception SQLException if the columnIndex is not valid; if a database access error occurs; if
* this method is called on a closed result set or is an invalid cast to boolean type.
* @see <a href="https://www.postgresql.org/docs/current/static/datatype-boolean.html">PostgreSQL
* Boolean Type</a>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -615,68 +615,79 @@ public void testBadBoolean() throws SQLException {
pstmt.setObject(1, "this is not boolean", Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"this is not boolean\"", e.getMessage());
}
try {
pstmt.setObject(1, 'X', Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"X\"", e.getMessage());
}
try {
java.io.File obj = new java.io.File("");
pstmt.setObject(1, obj, Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean", e.getMessage());
}
try {
pstmt.setObject(1, "1.0", Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"1.0\"", e.getMessage());
}
try {
pstmt.setObject(1, "-1", Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"-1\"", e.getMessage());
}
try {
pstmt.setObject(1, "ok", Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"ok\"", e.getMessage());
}
try {
pstmt.setObject(1, 0.99f, Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"0.99\"", e.getMessage());
}
try {
pstmt.setObject(1, -0.01d, Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"-0.01\"", e.getMessage());
}
try {
pstmt.setObject(1, new java.sql.Date(0), Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean", e.getMessage());
}
try {
pstmt.setObject(1, new java.math.BigInteger("1000"), Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"1000\"", e.getMessage());
}
try {
pstmt.setObject(1, Math.PI, Types.BOOLEAN);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"3.141592653589793\"", e.getMessage());
}
pstmt.close();
}
Expand Down
65 changes: 63 additions & 2 deletions pgjdbc/src/test/java/org/postgresql/test/jdbc2/ResultSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,76 @@ public void testBoolean(String table, int prepareThreshold) throws SQLException
rs.getBoolean(1);
fail();
} catch (SQLException e) {
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
}
}

}
rs.close();
pstmt.close();
}

@Test
public void testgetBooleanJDBCCompliance() throws SQLException {
// The JDBC specification in Table B-6 "Use of ResultSet getter Methods to Retrieve JDBC Data Types"
// the getBoolean have this Supported JDBC Type: TINYINT, SMALLINT, INTEGER, BIGINT, REAL, FLOAT,
// DOUBLE, DECIAML, NUMERIC, BIT, BOOLEAN, CHAR, VARCHAR, LONGVARCHAR

// There is no TINYINT in PostgreSQL
testgetBoolean("int2"); // SMALLINT
testgetBoolean("int4"); // INTEGER
testgetBoolean("int8"); // BIGINT
testgetBoolean("float4"); // REAL
testgetBoolean("float8"); // FLOAT, DOUBLE
testgetBoolean("numeric"); // DECIMAL, NUMERIC
testgetBoolean("bpchar"); // CHAR
testgetBoolean("varchar"); // VARCHAR
testgetBoolean("text"); // LONGVARCHAR?
}

public void testgetBoolean(String dataType) throws SQLException {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select 1::" + dataType + ", 0::" + dataType + ", 2::" + dataType);
assertTrue(rs.next());
assertEquals(true, rs.getBoolean(1));
assertEquals(false, rs.getBoolean(2));

try {
// The JDBC ResultSet JavaDoc states that only 1 and 0 are valid values, so 2 should return error.
rs.getBoolean(3);
fail();
} catch (SQLException e) {
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"2\"", e.getMessage());
}
rs.close();
stmt.close();
}

@Test
public void testgetBadBoolean() throws SQLException {
testBadBoolean("'2017-03-13 14:25:48.130861'::timestamp", "2017-03-13 14:25:48.130861");
testBadBoolean("'2017-03-13'::date", "2017-03-13");
testBadBoolean("'2017-03-13 14:25:48.130861'::time", "14:25:48.130861");
testBadBoolean("ARRAY[[1,0],[0,1]]", "{{1,0},{0,1}}");
testBadBoolean("'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11");
testBadBoolean("29::bit(4)", "1101");
}

public void testBadBoolean(String select, String value) throws SQLException {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select " + select);
assertTrue(rs.next());
try {
rs.getBoolean(1);
fail();
} catch (SQLException e) {
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
assertEquals("Cannot cast to boolean: \"" + value + "\"", e.getMessage());
}
rs.close();
stmt.close();
}

@Test
public void testgetByte() throws SQLException {
ResultSet rs = con.createStatement().executeQuery("select * from testnumeric");
Expand Down

0 comments on commit 394b3a2

Please sign in to comment.