From 541d09133de52c26fdfe6ad87e97aab57413a3be Mon Sep 17 00:00:00 2001 From: hantmac Date: Fri, 31 May 2024 21:43:43 +0800 Subject: [PATCH 1/3] fix: handle nan data in response --- .../com/databend/client/DatabendClientV1.java | 3 +- .../com/databend/client/JsonResponse.java | 3 +- .../com/databend/client/data/Int8Handler.java | 16 ++++- .../databend/jdbc/TestPrepareStatement.java | 70 +++++++++++++------ 4 files changed, 67 insertions(+), 25 deletions(-) diff --git a/databend-client/src/main/java/com/databend/client/DatabendClientV1.java b/databend-client/src/main/java/com/databend/client/DatabendClientV1.java index 089f1adf..652e9ecc 100644 --- a/databend-client/src/main/java/com/databend/client/DatabendClientV1.java +++ b/databend-client/src/main/java/com/databend/client/DatabendClientV1.java @@ -159,7 +159,8 @@ private boolean executeInternal(Request request, OptionalLong materializedJsonSi response = JsonResponse.execute(QUERY_RESULTS_CODEC, httpClient, request, materializedJsonSizeLimit); } catch (RuntimeException e) { cause = e; - continue; +// continue; + throw new RuntimeException("Query failed: " + e.getMessage()); } if ((response.getStatusCode() == HTTP_OK) && response.hasValue() && (response.getValue().getError() == null)) { diff --git a/databend-client/src/main/java/com/databend/client/JsonResponse.java b/databend-client/src/main/java/com/databend/client/JsonResponse.java index 71a65327..ecf95fa8 100644 --- a/databend-client/src/main/java/com/databend/client/JsonResponse.java +++ b/databend-client/src/main/java/com/databend/client/JsonResponse.java @@ -68,7 +68,7 @@ private JsonResponse(int statusCode, String statusMessage, Headers headers, @Nul this.hasValue = (exception == null); } - public static JsonResponse execute(JsonCodec codec, OkHttpClient client, Request request, OptionalLong materializedJsonSizeLimit) + public static JsonResponse execute(JsonCodec codec, OkHttpClient client, Request request, OptionalLong materializedJsonSizeLimit) throws RuntimeException { try (Response response = client.newCall(request).execute()) { // TODO: fix in OkHttp: https://github.com/square/okhttp/issues/3111 @@ -106,6 +106,7 @@ public static JsonResponse execute(JsonCodec codec, OkHttpClient clien message = format("Unable to create %s from JSON response", codec.getType()); } exception = new IllegalArgumentException(message, e); + throw exception; } return new JsonResponse<>(response.code(), response.message(), response.headers(), body, value, exception); } diff --git a/databend-client/src/main/java/com/databend/client/data/Int8Handler.java b/databend-client/src/main/java/com/databend/client/data/Int8Handler.java index 398850c9..9cff45c9 100644 --- a/databend-client/src/main/java/com/databend/client/data/Int8Handler.java +++ b/databend-client/src/main/java/com/databend/client/data/Int8Handler.java @@ -465,6 +465,9 @@ private Float parseNullableValue(Object value) { if (value == null || value.equals("NULL")) { return null; } + if (value.equals("NaN") || value.equals("nan")) { + return Float.NaN; + } if (value instanceof String) { return Float.parseFloat((String) value); } @@ -478,6 +481,9 @@ private float parseNonNullValue(Object value) { if (value == null || value.equals("NULL")) { throw new IllegalArgumentException("Float32 type is not nullable"); } + if (value.equals("NaN") || value.equals("nan")) { + return Float.NaN; + } if (value instanceof String) { return Float.parseFloat((String) value); } @@ -518,6 +524,9 @@ private Double parseNullableValue(Object value) { if (value == null || value.equals("NULL")) { return null; } + if (value.equals("NaN") || value.equals("nan")) { + return Double.NaN; + } if (value instanceof String) { return Double.parseDouble((String) value); } @@ -531,6 +540,9 @@ private double parseNonNullValue(Object value) { if (value == null || value.equals("NULL")) { throw new IllegalArgumentException("Float64 type is not nullable"); } + if (value.equals("NaN") || value.equals("nan")) { + return Double.NaN; + } if (value instanceof String) { return Double.parseDouble((String) value); } @@ -631,7 +643,7 @@ private BigDecimal parseNullableValue(Object value) { if (value == null || value.equals("NULL")) { return null; } - if(value instanceof Integer){ + if (value instanceof Integer) { return BigDecimal.valueOf((int) value); } if (value instanceof String) { @@ -647,7 +659,7 @@ private BigDecimal parseNonNullValue(Object value) { if (value == null || value.equals("NULL")) { throw new IllegalArgumentException("decimal type is not nullable"); } - if(value instanceof Integer){ + if (value instanceof Integer) { return BigDecimal.valueOf((int) value); } if (value instanceof String) { diff --git a/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java b/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java index d5ba6c3d..e3940637 100644 --- a/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java +++ b/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java @@ -22,7 +22,7 @@ public class TestPrepareStatement { private Connection createConnection() throws SQLException { - String url = "jdbc:databend://localhost:8000"; + String url = "jdbc:databend://localhost:8000?presigned_url_disabled=true"; return DriverManager.getConnection(url, "databend", "databend"); } @@ -31,26 +31,26 @@ private Connection createConnection(boolean presignDisabled) throws SQLException return DriverManager.getConnection(url, "databend", "databend"); } - @BeforeTest - public void setUp() - throws SQLException { - // create table - Connection c = createConnection(); - System.out.println("-----------------"); - System.out.println("drop all existing test table"); - c.createStatement().execute("drop table if exists test_prepare_statement"); - c.createStatement().execute("drop table if exists test_prepare_time"); - c.createStatement().execute("drop table if exists objects_test1"); - c.createStatement().execute("drop table if exists binary1"); - c.createStatement().execute("drop table if exists test_prepare_statement_null"); - c.createStatement().execute("create table test_prepare_statement (a int, b string)"); - c.createStatement().execute("create table test_prepare_statement_null (a int, b string)"); - c.createStatement().execute("create table test_prepare_time(a DATE, b TIMESTAMP)"); - // json data - c.createStatement().execute("CREATE TABLE IF NOT EXISTS objects_test1(id TINYINT, obj VARIANT, d TIMESTAMP, s String, arr ARRAY(INT64)) Engine = Fuse"); - // Binary data - c.createStatement().execute("create table IF NOT EXISTS binary1 (a binary);"); - } +// @BeforeTest +// public void setUp() +// throws SQLException { +// // create table +// Connection c = createConnection(); +// System.out.println("-----------------"); +// System.out.println("drop all existing test table"); +// c.createStatement().execute("drop table if exists test_prepare_statement"); +// c.createStatement().execute("drop table if exists test_prepare_time"); +// c.createStatement().execute("drop table if exists objects_test1"); +// c.createStatement().execute("drop table if exists binary1"); +// c.createStatement().execute("drop table if exists test_prepare_statement_null"); +// c.createStatement().execute("create table test_prepare_statement (a int, b string)"); +// c.createStatement().execute("create table test_prepare_statement_null (a int, b string)"); +// c.createStatement().execute("create table test_prepare_time(a DATE, b TIMESTAMP)"); +// // json data +// c.createStatement().execute("CREATE TABLE IF NOT EXISTS objects_test1(id TINYINT, obj VARIANT, d TIMESTAMP, s String, arr ARRAY(INT64)) Engine = Fuse"); +// // Binary data +// c.createStatement().execute("create table IF NOT EXISTS binary1 (a binary);"); +// } @Test(groups = "IT") public void TestBatchInsert() throws SQLException { @@ -525,4 +525,32 @@ public void shouldBuildStageAttachmentWithFileFormatOptions() throws SQLExceptio Assertions.assertEquals("true", stageAttachment.getCopyOptions().get("PURGE")); Assertions.assertEquals("\\N", stageAttachment.getCopyOptions().get("NULL_DISPLAY")); } + + @Test + public void testSelectWithClusterKey() throws SQLException { + Connection conn = createConnection(); + conn.createStatement().execute("drop table if exists default.test_clusterkey"); + conn.createStatement().execute("create table default.test_clusterkey (a int, b string)"); + String insertSql = "insert into default.test_clusterkey values (?,?)"; + try (PreparedStatement statement = conn.prepareStatement(insertSql)) { + statement.setInt(1, 1); + statement.setString(2, "b"); + statement.addBatch(); + statement.setInt(1, 2); + statement.setString(2, "c"); + statement.addBatch(); + int[] result = statement.executeBatch(); + System.out.println(result); + Assertions.assertEquals(2, result.length); + } + conn.createStatement().execute("alter table default.test_clusterkey cluster by (a)"); + String selectSQL = "select * from clustering_information('default','test_clusterkey')"; + try (PreparedStatement statement = conn.prepareStatement(selectSQL)) { + ResultSet rs = statement.executeQuery(); + while (rs.next()) { + System.out.println(rs.getString(5)); + Assertions.assertEquals("NaN", rs.getString(5)); + } + } + } } From fb47f2cec83389b2f8d8560d8351a6d201000ede Mon Sep 17 00:00:00 2001 From: hantmac Date: Fri, 31 May 2024 21:46:03 +0800 Subject: [PATCH 2/3] fix tests --- .../databend/jdbc/TestPrepareStatement.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java b/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java index e3940637..b6feea1b 100644 --- a/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java +++ b/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java @@ -22,7 +22,7 @@ public class TestPrepareStatement { private Connection createConnection() throws SQLException { - String url = "jdbc:databend://localhost:8000?presigned_url_disabled=true"; + String url = "jdbc:databend://localhost:8000"; return DriverManager.getConnection(url, "databend", "databend"); } @@ -31,26 +31,26 @@ private Connection createConnection(boolean presignDisabled) throws SQLException return DriverManager.getConnection(url, "databend", "databend"); } -// @BeforeTest -// public void setUp() -// throws SQLException { -// // create table -// Connection c = createConnection(); -// System.out.println("-----------------"); -// System.out.println("drop all existing test table"); -// c.createStatement().execute("drop table if exists test_prepare_statement"); -// c.createStatement().execute("drop table if exists test_prepare_time"); -// c.createStatement().execute("drop table if exists objects_test1"); -// c.createStatement().execute("drop table if exists binary1"); -// c.createStatement().execute("drop table if exists test_prepare_statement_null"); -// c.createStatement().execute("create table test_prepare_statement (a int, b string)"); -// c.createStatement().execute("create table test_prepare_statement_null (a int, b string)"); -// c.createStatement().execute("create table test_prepare_time(a DATE, b TIMESTAMP)"); -// // json data -// c.createStatement().execute("CREATE TABLE IF NOT EXISTS objects_test1(id TINYINT, obj VARIANT, d TIMESTAMP, s String, arr ARRAY(INT64)) Engine = Fuse"); -// // Binary data -// c.createStatement().execute("create table IF NOT EXISTS binary1 (a binary);"); -// } + @BeforeTest + public void setUp() + throws SQLException { + // create table + Connection c = createConnection(); + System.out.println("-----------------"); + System.out.println("drop all existing test table"); + c.createStatement().execute("drop table if exists test_prepare_statement"); + c.createStatement().execute("drop table if exists test_prepare_time"); + c.createStatement().execute("drop table if exists objects_test1"); + c.createStatement().execute("drop table if exists binary1"); + c.createStatement().execute("drop table if exists test_prepare_statement_null"); + c.createStatement().execute("create table test_prepare_statement (a int, b string)"); + c.createStatement().execute("create table test_prepare_statement_null (a int, b string)"); + c.createStatement().execute("create table test_prepare_time(a DATE, b TIMESTAMP)"); + // json data + c.createStatement().execute("CREATE TABLE IF NOT EXISTS objects_test1(id TINYINT, obj VARIANT, d TIMESTAMP, s String, arr ARRAY(INT64)) Engine = Fuse"); + // Binary data + c.createStatement().execute("create table IF NOT EXISTS binary1 (a binary);"); + } @Test(groups = "IT") public void TestBatchInsert() throws SQLException { From 2c7fdae964022581b697a7c48c2bb00ee07a33ce Mon Sep 17 00:00:00 2001 From: hantmac Date: Fri, 31 May 2024 21:46:47 +0800 Subject: [PATCH 3/3] fix --- .../src/test/java/com/databend/jdbc/TestPrepareStatement.java | 1 - 1 file changed, 1 deletion(-) diff --git a/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java b/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java index b6feea1b..f59acf77 100644 --- a/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java +++ b/databend-jdbc/src/test/java/com/databend/jdbc/TestPrepareStatement.java @@ -548,7 +548,6 @@ public void testSelectWithClusterKey() throws SQLException { try (PreparedStatement statement = conn.prepareStatement(selectSQL)) { ResultSet rs = statement.executeQuery(); while (rs.next()) { - System.out.println(rs.getString(5)); Assertions.assertEquals("NaN", rs.getString(5)); } }