Skip to content

Commit 431083f

Browse files
committed
Return precision values for non-dec columns (1.4)
This is a backport of the PR duckdb#367 to `v1.4-andium` stable branch. This PR makes `ResultSetMetaData#getPrecision()` to return non-zero values for integral numbers, floating point, date/time and string columns. Unlike the `DECIMAL` type, where actual column precision is returned, for other types this call is expected to give a hint to a client software how much space the textual representation of the field is going to take. Previously returned 0 value appeared to cause problems in some of such clients. Values returned are consistent with ones returned by Postgres. Testing: new test added for all types. Fixes: duckdb#340
1 parent e9ce2a8 commit 431083f

File tree

2 files changed

+113
-7
lines changed

2 files changed

+113
-7
lines changed

src/main/java/org/duckdb/DuckDBResultSetMetaData.java

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,17 +310,58 @@ public int getColumnDisplaySize(int column) throws SQLException {
310310
}
311311

312312
public int getPrecision(int column) throws SQLException {
313-
DuckDBColumnTypeMetaData typeMetaData = typeMetadataForColumn(column);
313+
checkColumn(column);
314+
DuckDBColumnTypeMetaData typeMetaData = column_types_meta[column - 1];
314315

315-
if (typeMetaData == null) {
316-
return 0;
316+
if (typeMetaData != null) {
317+
return typeMetaData.width;
317318
}
318319

319-
return typeMetaData.width;
320+
DuckDBColumnType colType = column_types[column - 1];
321+
switch (colType) {
322+
case BOOLEAN:
323+
return 5;
324+
case TINYINT:
325+
case UTINYINT:
326+
return 3;
327+
case SMALLINT:
328+
case USMALLINT:
329+
return 5;
330+
case INTEGER:
331+
case UINTEGER:
332+
return 10;
333+
case BIGINT:
334+
case UBIGINT:
335+
return 19;
336+
case HUGEINT:
337+
case UHUGEINT:
338+
return 38;
339+
case FLOAT:
340+
return 8;
341+
case DOUBLE:
342+
return 17;
343+
case TIME:
344+
return 15;
345+
case DATE:
346+
return 13;
347+
case TIMESTAMP:
348+
case TIMESTAMP_MS:
349+
case TIMESTAMP_NS:
350+
case TIMESTAMP_S:
351+
return 29;
352+
case TIMESTAMP_WITH_TIME_ZONE:
353+
return 35;
354+
case VARCHAR:
355+
case BLOB:
356+
return Integer.MAX_VALUE;
357+
default:
358+
return 0;
359+
}
320360
}
321361

322362
public int getScale(int column) throws SQLException {
323-
DuckDBColumnTypeMetaData typeMetaData = typeMetadataForColumn(column);
363+
checkColumn(column);
364+
DuckDBColumnTypeMetaData typeMetaData = column_types_meta[column - 1];
324365

325366
if (typeMetaData == null) {
326367
return 0;
@@ -347,10 +388,9 @@ public boolean isWrapperFor(Class<?> iface) {
347388
return iface.isInstance(this);
348389
}
349390

350-
private DuckDBColumnTypeMetaData typeMetadataForColumn(int columnIndex) throws SQLException {
391+
private void checkColumn(int columnIndex) throws SQLException {
351392
if (columnIndex > column_count) {
352393
throw new SQLException("Column index out of bounds");
353394
}
354-
return column_types_meta[columnIndex - 1];
355395
}
356396
}

src/test/java/org/duckdb/TestResults.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.math.BigInteger;
99
import java.sql.*;
1010
import java.time.LocalDateTime;
11+
import java.time.LocalTime;
1112
import java.util.Properties;
1213
import java.util.UUID;
1314

@@ -297,4 +298,69 @@ public static void test_results_strings_cast() throws Exception {
297298
}
298299
}
299300
}
301+
302+
public static void test_results_precision() throws Exception {
303+
try (Connection conn = DriverManager.getConnection(JDBC_URL); Statement stmt = conn.createStatement()) {
304+
try (ResultSet rs = stmt.executeQuery("SELECT TRUE::BOOLEAN")) {
305+
assertEquals(rs.getMetaData().getPrecision(1), 5);
306+
}
307+
try (ResultSet rs = stmt.executeQuery("SELECT 42::TINYINT")) {
308+
assertEquals(rs.getMetaData().getPrecision(1), 3);
309+
}
310+
try (ResultSet rs = stmt.executeQuery("SELECT 42::UTINYINT")) {
311+
assertEquals(rs.getMetaData().getPrecision(1), 3);
312+
}
313+
try (ResultSet rs = stmt.executeQuery("SELECT 42::SMALLINT")) {
314+
assertEquals(rs.getMetaData().getPrecision(1), 5);
315+
}
316+
try (ResultSet rs = stmt.executeQuery("SELECT 42::USMALLINT")) {
317+
assertEquals(rs.getMetaData().getPrecision(1), 5);
318+
}
319+
try (ResultSet rs = stmt.executeQuery("SELECT 42::INTEGER")) {
320+
assertEquals(rs.getMetaData().getPrecision(1), 10);
321+
}
322+
try (ResultSet rs = stmt.executeQuery("SELECT 42::UINTEGER")) {
323+
assertEquals(rs.getMetaData().getPrecision(1), 10);
324+
}
325+
try (ResultSet rs = stmt.executeQuery("SELECT 42::BIGINT")) {
326+
assertEquals(rs.getMetaData().getPrecision(1), 19);
327+
}
328+
try (ResultSet rs = stmt.executeQuery("SELECT 42::UBIGINT")) {
329+
assertEquals(rs.getMetaData().getPrecision(1), 19);
330+
}
331+
try (ResultSet rs = stmt.executeQuery("SELECT 42::HUGEINT")) {
332+
assertEquals(rs.getMetaData().getPrecision(1), 38);
333+
}
334+
try (ResultSet rs = stmt.executeQuery("SELECT 42::UHUGEINT")) {
335+
assertEquals(rs.getMetaData().getPrecision(1), 38);
336+
}
337+
try (ResultSet rs = stmt.executeQuery("SELECT 42::FLOAT")) {
338+
assertEquals(rs.getMetaData().getPrecision(1), 8);
339+
}
340+
try (ResultSet rs = stmt.executeQuery("SELECT 42::DOUBLE")) {
341+
assertEquals(rs.getMetaData().getPrecision(1), 17);
342+
}
343+
try (ResultSet rs = stmt.executeQuery("SELECT 42::DECIMAL(15,3)")) {
344+
assertEquals(rs.getMetaData().getPrecision(1), 15);
345+
}
346+
try (ResultSet rs = stmt.executeQuery("SELECT NULL::TIME")) {
347+
assertEquals(rs.getMetaData().getPrecision(1), 15);
348+
}
349+
try (ResultSet rs = stmt.executeQuery("SELECT NULL::DATE")) {
350+
assertEquals(rs.getMetaData().getPrecision(1), 13);
351+
}
352+
try (ResultSet rs = stmt.executeQuery("SELECT NULL::TIMESTAMP")) {
353+
assertEquals(rs.getMetaData().getPrecision(1), 29);
354+
}
355+
try (ResultSet rs = stmt.executeQuery("SELECT NULL::TIMESTAMP WITH TIME ZONE")) {
356+
assertEquals(rs.getMetaData().getPrecision(1), 35);
357+
}
358+
try (ResultSet rs = stmt.executeQuery("SELECT NULL::VARCHAR")) {
359+
assertEquals(rs.getMetaData().getPrecision(1), Integer.MAX_VALUE);
360+
}
361+
try (ResultSet rs = stmt.executeQuery("SELECT NULL::BLOB")) {
362+
assertEquals(rs.getMetaData().getPrecision(1), Integer.MAX_VALUE);
363+
}
364+
}
365+
}
300366
}

0 commit comments

Comments
 (0)