From 5f3e7fd17b2318b6ed1bec64e39ad55d345e5c81 Mon Sep 17 00:00:00 2001 From: Mark Zitnik Date: Fri, 27 Dec 2024 18:44:57 +0200 Subject: [PATCH] Metabase Fixes (#2051) * Added Tuple implementation * Enhance Tuple toString implementation --- .../main/java/com/clickhouse/data/Tuple.java | 40 +++++++++++++++++++ .../jdbc/PreparedStatementImpl.java | 16 ++++++++ .../com/clickhouse/jdbc/DataTypeTests.java | 20 ++++++++-- 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 jdbc-v2/src/main/java/com/clickhouse/data/Tuple.java diff --git a/jdbc-v2/src/main/java/com/clickhouse/data/Tuple.java b/jdbc-v2/src/main/java/com/clickhouse/data/Tuple.java new file mode 100644 index 000000000..963efa8ce --- /dev/null +++ b/jdbc-v2/src/main/java/com/clickhouse/data/Tuple.java @@ -0,0 +1,40 @@ +package com.clickhouse.data; + +public class Tuple { + private final Object[] values; + private volatile String output; + public Tuple(Object... values) { + this.values = values; + } + + public Object[] getValues() { + return values; + } + + public Object getValue(int index) { + return values[index]; + } + + public int size() { + return values.length; + } + private String buildOutput() { + StringBuilder sb = new StringBuilder(); + sb.append("("); + for (int i = 0; i < values.length; i++) { + if (i > 0) { + sb.append(", "); + } + sb.append(values[i]); + } + sb.append(")"); + return sb.toString(); + } + @Override + public String toString() { + if (output == null) { + output = buildOutput(); + } + return output; + } +} diff --git a/jdbc-v2/src/main/java/com/clickhouse/jdbc/PreparedStatementImpl.java b/jdbc-v2/src/main/java/com/clickhouse/jdbc/PreparedStatementImpl.java index a547bdbbb..5b8bfcd58 100644 --- a/jdbc-v2/src/main/java/com/clickhouse/jdbc/PreparedStatementImpl.java +++ b/jdbc-v2/src/main/java/com/clickhouse/jdbc/PreparedStatementImpl.java @@ -1,5 +1,6 @@ package com.clickhouse.jdbc; +import com.clickhouse.data.Tuple; import com.clickhouse.jdbc.internal.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -546,6 +547,21 @@ private static String encodeObject(Object x) throws SQLException { arrayString.append("]"); return arrayString.toString(); + } else if (x instanceof Tuple) { + StringBuilder tupleString = new StringBuilder(); + tupleString.append("("); + Tuple t = (Tuple) x; + Object [] values = t.getValues(); + int i = 0; + for (Object item : values) { + if (i > 0) { + tupleString.append(", "); + } + tupleString.append(encodeObject(item)); + i++; + } + tupleString.append(")"); + return tupleString.toString(); } return escapeString(x.toString());//Escape single quotes diff --git a/jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java b/jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java index 00b35dcfe..e2eae0773 100644 --- a/jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java +++ b/jdbc-v2/src/test/java/com/clickhouse/jdbc/DataTypeTests.java @@ -1,6 +1,7 @@ package com.clickhouse.jdbc; import com.clickhouse.client.api.ClientConfigProperties; +import com.clickhouse.data.Tuple; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.BeforeClass; @@ -455,7 +456,7 @@ public void testBooleanTypes() throws SQLException { @Test(groups = { "integration" }) public void testArrayTypes() throws SQLException { runQuery("CREATE TABLE test_arrays (order Int8, " - + "array Array(Int8), arraystr Array(String)" + + "array Array(Int8), arraystr Array(String), arraytuple Array(Tuple(Int8, String))" + ") ENGINE = MergeTree ORDER BY ()"); // Insert random (valid) values @@ -473,11 +474,17 @@ public void testArrayTypes() throws SQLException { arraystr[i] = "string" + rand.nextInt(1000); } + Tuple[] arraytuple = new Tuple[rand.nextInt(10) + 1]; + for (int i = 0; i < arraytuple.length; i++) { + arraytuple[i] = new Tuple(rand.nextInt(256) - 128, "string" + rand.nextInt(1000)); + } + // Insert random (valid) values try (Connection conn = getConnection()) { - try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_arrays VALUES ( 1, ?, ? )")) { + try (PreparedStatement stmt = conn.prepareStatement("INSERT INTO test_arrays VALUES ( 1, ?, ?, ?)")) { stmt.setArray(1, conn.createArrayOf("Int8", array)); stmt.setArray(2, conn.createArrayOf("String", arraystr)); + stmt.setArray(3, conn.createArrayOf("Tuple", arraytuple)); stmt.executeUpdate(); } } @@ -498,7 +505,14 @@ public void testArrayTypes() throws SQLException { for (int i = 0; i < arraystr.length; i++) { assertEquals(arraystrResult[i], arraystr[i]); } - + Object[] arraytupleResult = (Object[]) rs.getArray("arraytuple").getArray(); + assertEquals(arraytupleResult.length, arraytuple.length); + for (int i = 0; i < arraytuple.length; i++) { + Tuple tuple = arraytuple[i]; + Tuple tupleResult = new Tuple(((Object[]) arraytupleResult[i])); + assertEquals(String.valueOf(tupleResult.getValue(0)), String.valueOf(tuple.getValue(0))); + assertEquals(String.valueOf(tupleResult.getValue(1)), String.valueOf(tuple.getValue(1))); + } assertFalse(rs.next()); } }