Skip to content

Commit 394b3a2

Browse files
jorsoldavecramer
authored andcommitted
fix: remove type name from cast exception of getBoolean and setObject (pgjdbc#781)
1 parent 9c3471f commit 394b3a2

File tree

4 files changed

+104
-36
lines changed

4 files changed

+104
-36
lines changed

pgjdbc/src/main/java/org/postgresql/jdbc/BooleanTypeUtil.java

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,25 @@ private BooleanTypeUtil() {
3333
* @throws PSQLException PSQLState.CANNOT_COERCE
3434
*/
3535
static boolean castToBoolean(final Object in) throws PSQLException {
36-
LOGGER.log(Level.FINE, "Object to cast: {0}", in);
36+
if (LOGGER.isLoggable(Level.FINE)) {
37+
LOGGER.log(Level.FINE, "Cast to boolean: \"{0}\"", String.valueOf(in));
38+
}
3739
if (in instanceof Boolean) {
3840
return (Boolean) in;
3941
}
4042
if (in instanceof String) {
41-
return from((String) in);
43+
return fromString((String) in);
4244
}
4345
if (in instanceof Character) {
44-
return from((Character) in);
46+
return fromCharacter((Character) in);
4547
}
4648
if (in instanceof Number) {
47-
return from((Number) in, in.getClass().getName());
49+
return fromNumber((Number) in);
4850
}
49-
throw cannotCoerceException(in.getClass().getName());
51+
throw new PSQLException("Cannot cast to boolean", PSQLState.CANNOT_COERCE);
5052
}
5153

52-
private static boolean from(final String strval) throws PSQLException {
54+
private static boolean fromString(final String strval) throws PSQLException {
5355
// Leading or trailing whitespace is ignored, and case does not matter.
5456
final String val = strval.trim();
5557
if ("1".equals(val) || "true".equalsIgnoreCase(val)
@@ -62,10 +64,10 @@ private static boolean from(final String strval) throws PSQLException {
6264
|| "n".equalsIgnoreCase(val) || "off".equalsIgnoreCase(val)) {
6365
return false;
6466
}
65-
throw cannotCoerceException("String", val);
67+
throw cannotCoerceException(strval);
6668
}
6769

68-
private static boolean from(final Character charval) throws PSQLException {
70+
private static boolean fromCharacter(final Character charval) throws PSQLException {
6971
if ('1' == charval || 't' == charval || 'T' == charval
7072
|| 'y' == charval || 'Y' == charval) {
7173
return true;
@@ -74,33 +76,27 @@ private static boolean from(final Character charval) throws PSQLException {
7476
|| 'n' == charval || 'N' == charval) {
7577
return false;
7678
}
77-
throw cannotCoerceException("Character", charval.toString());
79+
throw cannotCoerceException(charval);
7880
}
7981

80-
private static boolean from(final Number numval, final String className) throws PSQLException {
82+
private static boolean fromNumber(final Number numval) throws PSQLException {
8183
// Handles BigDecimal, Byte, Short, Integer, Long Float, Double
8284
// based on the widening primitive conversions.
83-
double value = numval.doubleValue();
85+
final double value = numval.doubleValue();
8486
if (value == 1.0d) {
8587
return true;
8688
}
8789
if (value == 0.0d) {
8890
return false;
8991
}
90-
throw cannotCoerceException(className, String.valueOf(numval));
91-
}
92-
93-
private static PSQLException cannotCoerceException(final String fromType) {
94-
LOGGER.log(Level.FINE, "Cannot cast type {0} to boolean", fromType);
95-
return new PSQLException(GT.tr("Cannot cast type {0} to boolean", fromType),
96-
PSQLState.CANNOT_COERCE);
92+
throw cannotCoerceException(numval);
9793
}
9894

99-
private static PSQLException cannotCoerceException(final String fromType, final String value) {
95+
private static PSQLException cannotCoerceException(final Object value) {
10096
if (LOGGER.isLoggable(Level.FINE)) {
101-
LOGGER.log(Level.FINE, "Cannot cast type {0} to boolean: \"{1}\"", new Object[]{fromType, value});
97+
LOGGER.log(Level.FINE, "Cannot cast to boolean: \"{0}\"", String.valueOf(value));
10298
}
103-
return new PSQLException(GT.tr("Cannot cast type {0} to boolean: \"{1}\"", fromType, value),
99+
return new PSQLException(GT.tr("Cannot cast to boolean: \"{0}\"", String.valueOf(value)),
104100
PSQLState.CANNOT_COERCE);
105101
}
106102

pgjdbc/src/main/java/org/postgresql/jdbc/PgResultSet.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,8 +1936,8 @@ public String getString(int columnIndex) throws SQLException {
19361936
* @param columnIndex the first column is 1, the second is 2, ...
19371937
* @return the column value; if the value is SQL <code>NULL</code>, the value returned is
19381938
* <code>false</code>
1939-
* @exception SQLException if the columnIndex is not valid; if a database access error occurs or
1940-
* this method is called on a closed result set
1939+
* @exception SQLException if the columnIndex is not valid; if a database access error occurs; if
1940+
* this method is called on a closed result set or is an invalid cast to boolean type.
19411941
* @see <a href="https://www.postgresql.org/docs/current/static/datatype-boolean.html">PostgreSQL
19421942
* Boolean Type</a>
19431943
*/

pgjdbc/src/test/java/org/postgresql/test/jdbc2/PreparedStatementTest.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -615,68 +615,79 @@ public void testBadBoolean() throws SQLException {
615615
pstmt.setObject(1, "this is not boolean", Types.BOOLEAN);
616616
fail();
617617
} catch (SQLException e) {
618-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
618+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
619+
assertEquals("Cannot cast to boolean: \"this is not boolean\"", e.getMessage());
619620
}
620621
try {
621622
pstmt.setObject(1, 'X', Types.BOOLEAN);
622623
fail();
623624
} catch (SQLException e) {
624-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
625+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
626+
assertEquals("Cannot cast to boolean: \"X\"", e.getMessage());
625627
}
626628
try {
627629
java.io.File obj = new java.io.File("");
628630
pstmt.setObject(1, obj, Types.BOOLEAN);
629631
fail();
630632
} catch (SQLException e) {
631-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
633+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
634+
assertEquals("Cannot cast to boolean", e.getMessage());
632635
}
633636
try {
634637
pstmt.setObject(1, "1.0", Types.BOOLEAN);
635638
fail();
636639
} catch (SQLException e) {
637-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
640+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
641+
assertEquals("Cannot cast to boolean: \"1.0\"", e.getMessage());
638642
}
639643
try {
640644
pstmt.setObject(1, "-1", Types.BOOLEAN);
641645
fail();
642646
} catch (SQLException e) {
643-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
647+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
648+
assertEquals("Cannot cast to boolean: \"-1\"", e.getMessage());
644649
}
645650
try {
646651
pstmt.setObject(1, "ok", Types.BOOLEAN);
647652
fail();
648653
} catch (SQLException e) {
649-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
654+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
655+
assertEquals("Cannot cast to boolean: \"ok\"", e.getMessage());
650656
}
651657
try {
652658
pstmt.setObject(1, 0.99f, Types.BOOLEAN);
653659
fail();
654660
} catch (SQLException e) {
655-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
661+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
662+
assertEquals("Cannot cast to boolean: \"0.99\"", e.getMessage());
656663
}
657664
try {
658665
pstmt.setObject(1, -0.01d, Types.BOOLEAN);
659666
fail();
660667
} catch (SQLException e) {
661-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
668+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
669+
assertEquals("Cannot cast to boolean: \"-0.01\"", e.getMessage());
662670
}
663671
try {
664672
pstmt.setObject(1, new java.sql.Date(0), Types.BOOLEAN);
665673
fail();
666674
} catch (SQLException e) {
667-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
675+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
676+
assertEquals("Cannot cast to boolean", e.getMessage());
668677
}
669678
try {
670679
pstmt.setObject(1, new java.math.BigInteger("1000"), Types.BOOLEAN);
671680
fail();
672681
} catch (SQLException e) {
673-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
682+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
683+
assertEquals("Cannot cast to boolean: \"1000\"", e.getMessage());
674684
}
675685
try {
676686
pstmt.setObject(1, Math.PI, Types.BOOLEAN);
677687
fail();
678688
} catch (SQLException e) {
679-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
689+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
690+
assertEquals("Cannot cast to boolean: \"3.141592653589793\"", e.getMessage());
680691
}
681692
pstmt.close();
682693
}

pgjdbc/src/test/java/org/postgresql/test/jdbc2/ResultSetTest.java

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,76 @@ public void testBoolean(String table, int prepareThreshold) throws SQLException
252252
rs.getBoolean(1);
253253
fail();
254254
} catch (SQLException e) {
255-
assertEquals(e.getSQLState(), org.postgresql.util.PSQLState.CANNOT_COERCE.getState());
255+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
256256
}
257257
}
258-
259258
}
260259
rs.close();
261260
pstmt.close();
262261
}
263262

263+
@Test
264+
public void testgetBooleanJDBCCompliance() throws SQLException {
265+
// The JDBC specification in Table B-6 "Use of ResultSet getter Methods to Retrieve JDBC Data Types"
266+
// the getBoolean have this Supported JDBC Type: TINYINT, SMALLINT, INTEGER, BIGINT, REAL, FLOAT,
267+
// DOUBLE, DECIAML, NUMERIC, BIT, BOOLEAN, CHAR, VARCHAR, LONGVARCHAR
268+
269+
// There is no TINYINT in PostgreSQL
270+
testgetBoolean("int2"); // SMALLINT
271+
testgetBoolean("int4"); // INTEGER
272+
testgetBoolean("int8"); // BIGINT
273+
testgetBoolean("float4"); // REAL
274+
testgetBoolean("float8"); // FLOAT, DOUBLE
275+
testgetBoolean("numeric"); // DECIMAL, NUMERIC
276+
testgetBoolean("bpchar"); // CHAR
277+
testgetBoolean("varchar"); // VARCHAR
278+
testgetBoolean("text"); // LONGVARCHAR?
279+
}
280+
281+
public void testgetBoolean(String dataType) throws SQLException {
282+
Statement stmt = con.createStatement();
283+
ResultSet rs = stmt.executeQuery("select 1::" + dataType + ", 0::" + dataType + ", 2::" + dataType);
284+
assertTrue(rs.next());
285+
assertEquals(true, rs.getBoolean(1));
286+
assertEquals(false, rs.getBoolean(2));
287+
288+
try {
289+
// The JDBC ResultSet JavaDoc states that only 1 and 0 are valid values, so 2 should return error.
290+
rs.getBoolean(3);
291+
fail();
292+
} catch (SQLException e) {
293+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
294+
assertEquals("Cannot cast to boolean: \"2\"", e.getMessage());
295+
}
296+
rs.close();
297+
stmt.close();
298+
}
299+
300+
@Test
301+
public void testgetBadBoolean() throws SQLException {
302+
testBadBoolean("'2017-03-13 14:25:48.130861'::timestamp", "2017-03-13 14:25:48.130861");
303+
testBadBoolean("'2017-03-13'::date", "2017-03-13");
304+
testBadBoolean("'2017-03-13 14:25:48.130861'::time", "14:25:48.130861");
305+
testBadBoolean("ARRAY[[1,0],[0,1]]", "{{1,0},{0,1}}");
306+
testBadBoolean("'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11");
307+
testBadBoolean("29::bit(4)", "1101");
308+
}
309+
310+
public void testBadBoolean(String select, String value) throws SQLException {
311+
Statement stmt = con.createStatement();
312+
ResultSet rs = stmt.executeQuery("select " + select);
313+
assertTrue(rs.next());
314+
try {
315+
rs.getBoolean(1);
316+
fail();
317+
} catch (SQLException e) {
318+
assertEquals(org.postgresql.util.PSQLState.CANNOT_COERCE.getState(), e.getSQLState());
319+
assertEquals("Cannot cast to boolean: \"" + value + "\"", e.getMessage());
320+
}
321+
rs.close();
322+
stmt.close();
323+
}
324+
264325
@Test
265326
public void testgetByte() throws SQLException {
266327
ResultSet rs = con.createStatement().executeQuery("select * from testnumeric");

0 commit comments

Comments
 (0)