Skip to content

Commit 2631c0d

Browse files
committed
Fix null DECIMAL_DIGITS and CHAR_OCTET_LENGTH
1 parent d42ede2 commit 2631c0d

4 files changed

Lines changed: 60 additions & 14 deletions

File tree

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseColumn.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public final class ClickHouseColumn implements Serializable {
4545
private static ClickHouseColumn update(ClickHouseColumn column) {
4646
column.enumConstants = ClickHouseEnum.EMPTY;
4747
int size = column.parameters.size();
48+
column.precision = column.dataType.getMaxPrecision();
4849
switch (column.dataType) {
4950
case Array:
5051
column.arrayLevel = 1;

clickhouse-client/src/main/java/com/clickhouse/client/ClickHouseDataType.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ public enum ClickHouseDataType {
4444
UInt32(Long.class, false, true, false, 4, 10, 0, 0, 0, "INT UNSIGNED", "INTEGER UNSIGNED", "MEDIUMINT UNSIGNED"),
4545
UInt64(Long.class, false, true, false, 8, 20, 0, 0, 0, "BIGINT UNSIGNED"),
4646
UInt128(BigInteger.class, false, true, false, 16, 39, 0, 0, 0),
47-
UInt256(BigInteger.class, false, true, false, 32, 78, 0, 0, 0), Int8(Byte.class, false, true, true, 1, 3, 0, 0, 0,
48-
"BYTE", "INT1", "INT1 SIGNED", "TINYINT", "TINYINT SIGNED"),
47+
UInt256(BigInteger.class, false, true, false, 32, 78, 0, 0, 0),
48+
Int8(Byte.class, false, true, true, 1, 3, 0, 0, 0, "BYTE", "INT1", "INT1 SIGNED", "TINYINT", "TINYINT SIGNED"),
4949
Int16(Short.class, false, true, true, 2, 5, 0, 0, 0, "SMALLINT", "SMALLINT SIGNED"),
5050
Int32(Integer.class, false, true, true, 4, 10, 0, 0, 0, "INT", "INTEGER", "MEDIUMINT", "INT SIGNED",
5151
"INTEGER SIGNED", "MEDIUMINT SIGNED"),
5252
Int64(Long.class, false, true, true, 8, 19, 0, 0, 0, "BIGINT", "BIGINT SIGNED"),
5353
Int128(BigInteger.class, false, true, true, 16, 39, 0, 0, 0),
5454
Int256(BigInteger.class, false, true, true, 32, 77, 0, 0, 0),
55-
Bool(Boolean.class, false, false, true, 1, 3, 0, 0, 0, "BOOLEAN"),
55+
Bool(Boolean.class, false, false, true, 1, 1, 0, 0, 0, "BOOLEAN"),
5656
Date(LocalDate.class, false, false, false, 2, 10, 0, 0, 0),
5757
Date32(LocalDate.class, false, false, false, 4, 10, 0, 0, 0),
5858
DateTime(LocalDateTime.class, true, false, false, 0, 29, 0, 0, 9, "TIMESTAMP"),
@@ -63,12 +63,15 @@ public enum ClickHouseDataType {
6363
Decimal64(BigDecimal.class, true, false, true, 8, 18, 18, 0, 18),
6464
Decimal128(BigDecimal.class, true, false, true, 16, 38, 38, 0, 38),
6565
Decimal256(BigDecimal.class, true, false, true, 32, 76, 20, 0, 76),
66-
UUID(UUID.class, false, true, false, 16, 69, 0, 0, 0), Enum(String.class, true, true, false, 1, 0, 0, 0, 0),
67-
Enum8(String.class, true, true, false, 1, 0, 0, 0, 0), Enum16(String.class, true, true, false, 2, 0, 0, 0, 0),
66+
UUID(UUID.class, false, true, false, 16, 69, 0, 0, 0),
67+
@Deprecated
68+
Enum(String.class, true, true, false, 1, 0, 0, 0, 0),
69+
Enum8(String.class, true, true, false, 1, 0, 0, 0, 0), // "ENUM"),
70+
Enum16(String.class, true, true, false, 2, 0, 0, 0, 0),
6871
Float32(Float.class, false, true, true, 4, 12, 0, 0, 38, "FLOAT", "REAL", "SINGLE"),
6972
Float64(Double.class, false, true, true, 16, 22, 0, 0, 308, "DOUBLE", "DOUBLE PRECISION"),
70-
IPv4(Inet4Address.class, false, true, false, 4, 0, 0, 0, 0, "INET4"),
71-
IPv6(Inet6Address.class, false, true, false, 16, 0, 0, 0, 0, "INET6"),
73+
IPv4(Inet4Address.class, false, true, false, 4, 10, 0, 0, 0, "INET4"),
74+
IPv6(Inet6Address.class, false, true, false, 16, 39, 0, 0, 0, "INET6"),
7275
FixedString(String.class, true, true, false, 0, 0, 0, 0, 0, "BINARY"),
7376
String(String.class, false, true, false, 0, 0, 0, 0, 0, "BINARY LARGE OBJECT", "BINARY VARYING", "BLOB", "BYTEA",
7477
"CHAR", "CHAR LARGE OBJECT", "CHAR VARYING", "CHARACTER", "CHARACTER LARGE OBJECT", "CHARACTER VARYING",
@@ -77,8 +80,10 @@ public enum ClickHouseDataType {
7780
"NCHAR LARGE OBJECT", "NCHAR VARYING", "NVARCHAR", "TEXT", "TINYBLOB", "TINYTEXT", "VARCHAR", "VARCHAR2"),
7881
AggregateFunction(String.class, true, true, false, 0, 0, 0, 0, 0), // implementation-defined intermediate state
7982
SimpleAggregateFunction(String.class, true, true, false, 0, 0, 0, 0, 0),
80-
Array(Object.class, true, true, false, 0, 0, 0, 0, 0), Map(Map.class, true, true, false, 0, 0, 0, 0, 0),
81-
Nested(Object.class, true, true, false, 0, 0, 0, 0, 0), Tuple(List.class, true, true, false, 0, 0, 0, 0, 0),
83+
Array(Object.class, true, true, false, 0, 0, 0, 0, 0),
84+
Map(Map.class, true, true, false, 0, 0, 0, 0, 0),
85+
Nested(Object.class, true, true, false, 0, 0, 0, 0, 0),
86+
Tuple(List.class, true, true, false, 0, 0, 0, 0, 0),
8287
Point(Object.class, false, true, true, 33, 0, 0, 0, 0), // same as Tuple(Float64, Float64)
8388
Polygon(Object.class, false, true, true, 0, 0, 0, 0, 0), // same as Array(Ring)
8489
MultiPolygon(Object.class, false, true, true, 0, 0, 0, 0, 0), // same as Array(Polygon)

clickhouse-jdbc/src/main/java/com/clickhouse/jdbc/ClickHouseDatabaseMetaData.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -814,9 +814,9 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
814814
String sql = ClickHouseParameterizedQuery
815815
.apply("select null as TABLE_CAT, database as TABLE_SCHEM, table as TABLE_NAME, "
816816
+ "name as COLUMN_NAME, toInt32(:defaultType) as DATA_TYPE, type as TYPE_NAME, toInt32(0) as COLUMN_SIZE, "
817-
+ "0 as BUFFER_LENGTH, toInt32(null) as DECIMAL_DIGITS, 10 as NUM_PREC_RADIX, "
817+
+ "0 as BUFFER_LENGTH, cast(null as Nullable(Int32)) as DECIMAL_DIGITS, 10 as NUM_PREC_RADIX, "
818818
+ "toInt32(position(type, 'Nullable(') >= 1 ? :defaultNullable : :defaultNonNull) as NULLABLE, :comment as REMARKS, default_expression as COLUMN_DEF, "
819-
+ "0 as SQL_DATA_TYPE, 0 as SQL_DATETIME_SUB, toInt32(null) as CHAR_OCTET_LENGTH, position as ORDINAL_POSITION, "
819+
+ "0 as SQL_DATA_TYPE, 0 as SQL_DATETIME_SUB, cast(null as Nullable(Int32)) as CHAR_OCTET_LENGTH, position as ORDINAL_POSITION, "
820820
+ "position(type, 'Nullable(') >= 1 ? 'YES' : 'NO' as IS_NULLABLE, null as SCOPE_CATALOG, null as SCOPE_SCHEMA, null as SCOPE_TABLE, "
821821
+ "null as SOURCE_DATA_TYPE, 'NO' as IS_AUTOINCREMENT, 'NO' as IS_GENERATEDCOLUMN from system.columns\n"
822822
+ "where database like :database and table like :table and name like :column", params);
@@ -825,7 +825,8 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
825825
try {
826826
ClickHouseColumn column = ClickHouseColumn.of("", typeName);
827827
r.getValue("DATA_TYPE").update(JdbcTypeMapping.toJdbcType(typeMaps, column));
828-
r.getValue("COLUMN_SIZE").update(column.getDataType().getByteLength());
828+
r.getValue("COLUMN_SIZE").update(
829+
column.getPrecision() > 0 ? column.getPrecision() : column.getDataType().getByteLength());
829830
if (column.isNullable()) {
830831
r.getValue("NULLABLE").update(DatabaseMetaData.typeNullable);
831832
r.getValue("IS_NULLABLE").update("YES");
@@ -838,7 +839,8 @@ public ResultSet getColumns(String catalog, String schemaPattern, String tableNa
838839
r.getValue("CHAR_OCTET_LENGTH").update(column.getPrecision());
839840
}
840841

841-
if (column.getScale() > 0) {
842+
if (column.getScale() > 0 || column.getDataType() == ClickHouseDataType.Float32
843+
|| column.getDataType() == ClickHouseDataType.Float64) {
842844
r.getValue("DECIMAL_DIGITS").update(column.getScale());
843845
} else {
844846
r.getValue("DECIMAL_DIGITS").resetToNullOrEmpty();

clickhouse-jdbc/src/test/java/com/clickhouse/jdbc/ClickHouseDatabaseMetaDataTest.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,28 @@
66
import java.util.Locale;
77
import java.util.Properties;
88

9+
import com.clickhouse.client.ClickHouseColumn;
10+
911
import org.testng.Assert;
12+
import org.testng.annotations.DataProvider;
1013
import org.testng.annotations.Test;
1114

1215
public class ClickHouseDatabaseMetaDataTest extends JdbcIntegrationTest {
16+
@DataProvider(name = "selectedColumns")
17+
private Object[][] getSelectedColumns() {
18+
return new Object[][] {
19+
// COLUMN_SIZE, DECIMAL_DIGITS, CHAR_OCTET_LENGTH
20+
new Object[] { "Bool", 1, null, null },
21+
new Object[] { "Int8", 3, null, null },
22+
new Object[] { "UInt8", 3, null, null },
23+
new Object[] { "FixedString(3)", 3, null, 3 },
24+
new Object[] { "String", 0, null, null },
25+
new Object[] { "Decimal64(10)", 18, 10, null },
26+
new Object[] { "Decimal(10,2)", 10, 2, null },
27+
new Object[] { "Float32", 12, 0, null },
28+
new Object[] { "Float64", 22, 0, null } };
29+
}
30+
1331
@Test(groups = "integration")
1432
public void testGetTypeInfo() throws SQLException {
1533
Properties props = new Properties();
@@ -21,6 +39,26 @@ public void testGetTypeInfo() throws SQLException {
2139
}
2240
}
2341

42+
@Test(dataProvider = "selectedColumns", groups = "integration")
43+
public void testGetColumns(String columnType, Integer columnSize, Integer decimalDigits, Integer octectLength)
44+
throws SQLException {
45+
ClickHouseColumn c = ClickHouseColumn.of("x", columnType);
46+
String tableName = "test_get_column_" + c.getDataType().name().toLowerCase();
47+
try (ClickHouseConnection conn = newConnection(new Properties());
48+
Statement s = conn.createStatement()) {
49+
s.execute("drop table if exists " + tableName + "; "
50+
+ "create table " + tableName + "(x " + columnType + ") engine=Memory");
51+
try (ResultSet rs = conn.getMetaData().getColumns(conn.getCatalog(), conn.getSchema(), tableName, "%")) {
52+
Assert.assertTrue(rs.next(), "Should have one record");
53+
Assert.assertEquals(rs.getString("cOLUMN_NAME"), "x");
54+
Assert.assertEquals(rs.getObject("COLUMN_SIZE"), columnSize);
55+
Assert.assertEquals(rs.getObject("DECIMAL_DIGITS"), decimalDigits);
56+
Assert.assertEquals(rs.getObject("CHAR_OCTET_LENGTH"), octectLength);
57+
Assert.assertFalse(rs.next(), "Should have only one record");
58+
}
59+
}
60+
}
61+
2462
@Test(groups = "integration")
2563
public void testTableComment() throws SQLException {
2664
String tableName = "test_table_comment";
@@ -35,7 +73,7 @@ public void testTableComment() throws SQLException {
3573
s.execute(String.format(Locale.ROOT,
3674
"drop table if exists %1$s; create table %1$s(s String) engine=Memory comment '%2$s'",
3775
tableName, tableComment));
38-
try (ResultSet rs = conn.getMetaData().getTables(null, "%", tableName, null)) {
76+
try (ResultSet rs = conn.getMetaData().getTables(conn.getCatalog(), conn.getSchema(), tableName, null)) {
3977
Assert.assertTrue(rs.next());
4078
Assert.assertEquals(rs.getString("remarks"), tableComment);
4179
Assert.assertFalse(rs.next());

0 commit comments

Comments
 (0)