package ru.yandex.clickhouse.integration; import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.testng.Assert; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import ru.yandex.clickhouse.ClickHouseArray; import ru.yandex.clickhouse.ClickHouseConnection; import ru.yandex.clickhouse.ClickHouseDataSource; import ru.yandex.clickhouse.ClickHousePreparedStatement; import ru.yandex.clickhouse.ClickHousePreparedStatementImpl; import ru.yandex.clickhouse.domain.ClickHouseDataType; import ru.yandex.clickhouse.response.ClickHouseResponse; import ru.yandex.clickhouse.settings.ClickHouseProperties; import static java.util.Collections.singletonList; public class ClickHousePreparedStatementTest { private ClickHouseDataSource dataSource; private Connection connection; @BeforeTest public void setUp() throws Exception { ClickHouseProperties properties = new ClickHouseProperties(); dataSource = new ClickHouseDataSource("jdbc:clickhouse://localhost:8123", properties); connection = dataSource.getConnection(); connection.createStatement().execute("CREATE DATABASE IF NOT EXISTS test"); } @AfterTest public void tearDown() throws Exception { if (connection != null) { connection.close(); } } @Test public void testArrayTest() throws Exception { connection.createStatement().execute("DROP TABLE IF EXISTS test.array_test"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.array_test (i Int32, a Array(Int32)) ENGINE = TinyLog" ); PreparedStatement statement = connection.prepareStatement("INSERT INTO test.array_test (i, a) VALUES (?, ?)"); statement.setInt(1, 1); statement.setArray(2, new ClickHouseArray(ClickHouseDataType.Int32, new int[]{1, 2, 3})); statement.addBatch(); statement.setInt(1, 2); statement.setArray(2, new ClickHouseArray(ClickHouseDataType.Int32, new int[]{2, 3, 4, 5})); statement.addBatch(); statement.executeBatch(); ResultSet rs = connection.createStatement().executeQuery("SELECT count() as cnt from test.array_test"); rs.next(); Assert.assertEquals(rs.getInt("cnt"), 2); Assert.assertFalse(rs.next()); } @Test public void testArrayOfNullable() throws Exception { connection.createStatement().execute("DROP TABLE IF EXISTS test.array_of_nullable"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.array_of_nullable (" + "str Nullable(String), " + "int Nullable(Int32), " + "strs Array(Nullable(String)), " + "ints Array(Nullable(Int32))) ENGINE = TinyLog" ); PreparedStatement statement = connection.prepareStatement( "INSERT INTO test.array_of_nullable (str, int, strs, ints) VALUES (?, ?, ?, ?)" ); statement.setObject(1, null); statement.setObject(2, null); statement.setObject(3, new String[]{"a", null, "c"}); statement.setArray(4, new ClickHouseArray(ClickHouseDataType.Int32, new Integer[]{1, null, 3})); statement.addBatch(); statement.executeBatch(); ResultSet rs = connection.createStatement().executeQuery("SELECT * FROM test.array_of_nullable"); Assert.assertTrue(rs.next()); Assert.assertNull(rs.getObject("str")); Assert.assertNull(rs.getObject("int")); Assert.assertEquals(rs.getArray("strs").getArray(), new String[]{"a", null, "c"}); Assert.assertEquals(rs.getArray("ints").getArray(), new int[]{1, 0, 3}); Assert.assertFalse(rs.next()); ClickHouseProperties properties = new ClickHouseProperties(); properties.setUseObjectsInArrays(true); ClickHouseDataSource configuredDataSource = new ClickHouseDataSource(dataSource.getUrl(), properties); ClickHouseConnection configuredConnection = configuredDataSource.getConnection(); try { rs = configuredConnection.createStatement().executeQuery("SELECT * FROM test.array_of_nullable"); rs.next(); Assert.assertEquals(rs.getArray("ints").getArray(), new Integer[]{1, null, 3}); } finally { configuredConnection.close(); } } @Test public void testArrayFixedStringTest() throws Exception { connection.createStatement().execute("DROP TABLE IF EXISTS test.array_fixed_string_test"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.array_fixed_string_test (i Int32, a Array(FixedString(16))) ENGINE = TinyLog" ); PreparedStatement statement = connection.prepareStatement("INSERT INTO test.array_fixed_string_test (i, a) VALUES (?, ?)"); statement.setInt(1, 1); statement.setArray(2, new ClickHouseArray(ClickHouseDataType.FixedString, new byte[][]{randomEncodedUUID(), randomEncodedUUID()})); statement.addBatch(); statement.setInt(1, 2); statement.setArray(2, new ClickHouseArray(ClickHouseDataType.FixedString, new byte[][]{randomEncodedUUID(), randomEncodedUUID()})); statement.addBatch(); statement.executeBatch(); ResultSet rs = connection.createStatement().executeQuery("SELECT count() as cnt from test.array_fixed_string_test"); rs.next(); Assert.assertEquals(rs.getInt("cnt"), 2); Assert.assertFalse(rs.next()); } @Test public void testInsertUInt() throws SQLException { connection.createStatement().execute("DROP TABLE IF EXISTS test.unsigned_insert"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.unsigned_insert (ui32 UInt32, ui64 UInt64) ENGINE = TinyLog" ); PreparedStatement stmt = connection.prepareStatement("insert into test.unsigned_insert (ui32, ui64) values (?, ?)"); stmt.setObject(1, 4294967286L); stmt.setObject(2, new BigInteger("18446744073709551606")); stmt.execute(); Statement select = connection.createStatement(); ResultSet rs = select.executeQuery("select ui32, ui64 from test.unsigned_insert"); rs.next(); Object bigUInt32 = rs.getObject(1); Assert.assertTrue(bigUInt32 instanceof Long); Assert.assertEquals(((Long)bigUInt32).longValue(), 4294967286L); Object bigUInt64 = rs.getObject(2); Assert.assertTrue(bigUInt64 instanceof BigInteger); Assert.assertEquals(bigUInt64, new BigInteger("18446744073709551606")); } @Test public void testInsertUUID() throws SQLException { connection.createStatement().execute("DROP TABLE IF EXISTS test.uuid_insert"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.uuid_insert (ui32 UInt32, uuid UUID) ENGINE = TinyLog" ); PreparedStatement stmt = connection.prepareStatement("insert into test.uuid_insert (ui32, uuid) values (?, ?)"); stmt.setObject(1, Long.valueOf(4294967286L)); stmt.setObject(2, UUID.fromString("bef35f40-3b03-45b0-b1bd-8ec6593dcaaa")); stmt.execute(); Statement select = connection.createStatement(); ResultSet rs = select.executeQuery("select ui32, uuid from test.uuid_insert"); rs.next(); Object bigUInt32 = rs.getObject(1); Assert.assertTrue(bigUInt32 instanceof Long); Assert.assertEquals(((Long)bigUInt32).longValue(), 4294967286L); Object uuid = rs.getObject(2); Assert.assertTrue(uuid instanceof UUID); Assert.assertEquals(uuid, UUID.fromString("bef35f40-3b03-45b0-b1bd-8ec6593dcaaa")); } @Test public void testInsertUUIDBatch() throws SQLException { connection.createStatement().execute("DROP TABLE IF EXISTS test.uuid_insert"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.uuid_insert (ui32 UInt32, uuid UUID) ENGINE = TinyLog" ); PreparedStatement stmt = connection.prepareStatement("insert into test.uuid_insert (ui32, uuid) values (?, ?)"); stmt.setObject(1, 4294967286L); stmt.setObject(2, UUID.fromString("bef35f40-3b03-45b0-b1bd-8ec6593dcaaa")); stmt.addBatch(); stmt.executeBatch(); Statement select = connection.createStatement(); ResultSet rs = select.executeQuery("select ui32, uuid from test.uuid_insert"); rs.next(); Object bigUInt32 = rs.getObject(1); Assert.assertTrue(bigUInt32 instanceof Long); Assert.assertEquals(((Long)bigUInt32).longValue(), 4294967286L); Object uuid = rs.getObject(2); Assert.assertTrue(uuid instanceof UUID); Assert.assertEquals(uuid, UUID.fromString("bef35f40-3b03-45b0-b1bd-8ec6593dcaaa")); } @Test public void testInsertNullString() throws SQLException { connection.createStatement().execute("DROP TABLE IF EXISTS test.null_insert"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.null_insert (val Nullable(String)) ENGINE = TinyLog" ); PreparedStatement stmt = connection.prepareStatement("insert into test.null_insert (val) values (?)"); stmt.setNull(1, Types.VARCHAR); stmt.execute(); stmt.setNull(1, Types.VARCHAR); stmt.addBatch(); stmt.executeBatch(); stmt.setString(1, null); stmt.execute(); stmt.setString(1, null); stmt.addBatch(); stmt.executeBatch(); stmt.setObject(1, null); stmt.execute(); stmt.setObject(1, null); stmt.addBatch(); stmt.executeBatch(); Statement select = connection.createStatement(); ResultSet rs = select.executeQuery("select count(*), val from test.null_insert group by val"); rs.next(); Assert.assertEquals(rs.getInt(1), 6); Assert.assertNull(rs.getString(2)); Assert.assertFalse(rs.next()); } @Test public void testSelectNullableTypes() throws SQLException { connection.createStatement().execute("DROP TABLE IF EXISTS test.select_nullable"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.select_nullable (idx Int32, i Nullable(Int32), ui Nullable(UInt64), f Nullable(Float32), s Nullable(String)) ENGINE = TinyLog" ); PreparedStatement stmt = connection.prepareStatement("insert into test.select_nullable (idx, i, ui, f, s) values (?, ?, ?, ?, ?)"); stmt.setInt(1, 1); stmt.setObject(2, null); stmt.setObject(3, null); stmt.setObject(4, null); stmt.setString(5, null); stmt.addBatch(); stmt.setInt(1, 2); stmt.setInt(2, 1); stmt.setInt(3, 1); stmt.setFloat(4, 1.0f); stmt.setString(5, "aaa"); stmt.addBatch(); stmt.executeBatch(); Statement select = connection.createStatement(); ResultSet rs = select.executeQuery("select i, ui, f, s from test.select_nullable order by idx"); rs.next(); Assert.assertEquals(rs.getMetaData().getColumnType(1), Types.INTEGER); Assert.assertEquals(rs.getMetaData().getColumnType(2), Types.BIGINT); Assert.assertEquals(rs.getMetaData().getColumnType(3), Types.FLOAT); Assert.assertEquals(rs.getMetaData().getColumnType(4), Types.VARCHAR); Assert.assertNull(rs.getObject(1)); Assert.assertNull(rs.getObject(2)); Assert.assertNull(rs.getObject(3)); Assert.assertNull(rs.getObject(4)); Assert.assertEquals(rs.getInt(1), 0); Assert.assertEquals(rs.getInt(1), 0); Assert.assertEquals(rs.getFloat(1), 0.0f); Assert.assertEquals(rs.getString(1), null); rs.next(); Assert.assertEquals(rs.getObject(1).getClass(), Integer.class); Assert.assertEquals(rs.getObject(2).getClass(), BigInteger.class); Assert.assertEquals(rs.getObject(3).getClass(), Float.class); Assert.assertEquals(rs.getObject(4).getClass(), String.class); Assert.assertEquals(rs.getObject(1), 1); Assert.assertEquals(rs.getObject(2), BigInteger.ONE); Assert.assertEquals(rs.getObject(3), 1.0f); Assert.assertEquals(rs.getObject(4), "aaa"); } @Test public void testInsertBatchNullValues() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.prep_nullable_value"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.prep_nullable_value " + "(idx Int32, s Nullable(String), i Nullable(Int32), f Nullable(Float32)) " + "ENGINE = TinyLog" ); PreparedStatement stmt = connection.prepareStatement( "INSERT INTO test.prep_nullable_value (idx, s, i, f) VALUES " + "(1, ?, ?, NULL), (2, NULL, NULL, ?)"); stmt.setString(1, "foo"); stmt.setInt(2, 42); stmt.setFloat(3, 42.0F); stmt.addBatch(); int[] updateCount = stmt.executeBatch(); Assert.assertEquals(updateCount.length, 2); ResultSet rs = connection.createStatement().executeQuery( "SELECT s, i, f FROM test.prep_nullable_value " + "ORDER BY idx ASC"); rs.next(); Assert.assertEquals(rs.getString(1), "foo"); Assert.assertEquals(rs.getInt(2), 42); Assert.assertNull(rs.getObject(3)); rs.next(); Assert.assertNull(rs.getObject(1)); Assert.assertNull(rs.getObject(2)); Assert.assertEquals(rs.getFloat(3), 42.0f); } @Test public void testSelectDouble() throws SQLException { Statement select = connection.createStatement(); ResultSet rs = select.executeQuery("select toFloat64(0.1) "); rs.next(); Assert.assertEquals(rs.getMetaData().getColumnType(1), Types.DOUBLE); Assert.assertEquals(rs.getObject(1).getClass(), Double.class); Assert.assertEquals(rs.getDouble(1), 0.1); } @Test public void testExecuteQueryClickhouseResponse() throws SQLException { ClickHousePreparedStatement sth = (ClickHousePreparedStatement) connection.prepareStatement("select ? limit 5"); sth.setObject(1, 314); ClickHouseResponse resp = sth.executeQueryClickhouseResponse(); Assert.assertEquals(resp.getData(), singletonList(singletonList("314"))); } @Test public void clickhouseJdbcFailsBecauseOfCommentInStart() throws Exception { String sqlStatement = "/*comment*/ select * from system.numbers limit 3"; Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(sqlStatement); Assert.assertNotNull(rs); for (int i = 0; i < 3; i++) { rs.next(); Assert.assertEquals(rs.getInt(1), i); } } @Test public void testTrailingParameter() throws Exception { String sqlStatement = // "SELECT 42 AS foo, 23 AS bar " "SELECT 42 AS foo, 23 AS bar from numbers(100) " + "ORDER BY foo DESC LIMIT ?, ?"; PreparedStatement stmt = connection.prepareStatement(sqlStatement); stmt.setInt(1, 42); stmt.setInt(2, 23); ResultSet rs = stmt.executeQuery(); } @Test public void testSetTime() throws Exception { ClickHousePreparedStatement stmt = (ClickHousePreparedStatement) connection.prepareStatement("SELECT toDateTime(?)"); stmt.setTime(1, Time.valueOf("13:37:42")); ResultSet rs = stmt.executeQuery(); rs.next(); Assert.assertEquals(rs.getTime(1), Time.valueOf("13:37:42")); } @Test public void testAsSql() throws Exception { String unbindedStatement = "SELECT test.example WHERE id IN (?, ?)"; ClickHousePreparedStatement statement = (ClickHousePreparedStatement) connection.prepareStatement(unbindedStatement); Assert.assertEquals(statement.asSql(), unbindedStatement); statement.setInt(1, 123); Assert.assertEquals(statement.asSql(), unbindedStatement); statement.setInt(2, 456); Assert.assertEquals(statement.asSql(), "SELECT test.example WHERE id IN (123, 456)"); } @Test public void testMetadataOnlySelect() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.mymetadata"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.mymetadata " + "(idx Int32, s String) " + "ENGINE = TinyLog" ); PreparedStatement insertStmt = connection.prepareStatement( "INSERT INTO test.mymetadata (idx, s) VALUES (?, ?)"); insertStmt.setInt(1, 42); insertStmt.setString(2, "foo"); insertStmt.executeUpdate(); PreparedStatement metaStmt = connection.prepareStatement( "SELECT idx, s FROM test.mymetadata WHERE idx = ?"); metaStmt.setInt(1, 42); ResultSetMetaData metadata = metaStmt.getMetaData(); Assert.assertEquals(metadata.getColumnCount(), 2); Assert.assertEquals(metadata.getColumnName(1), "idx"); Assert.assertEquals(metadata.getColumnName(2), "s"); } @Test public void testMetadataOnlySelectAfterExecution() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.mymetadata"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.mymetadata " + "(idx Int32, s String) " + "ENGINE = TinyLog" ); PreparedStatement insertStmt = connection.prepareStatement( "INSERT INTO test.mymetadata (idx, s) VALUES (?, ?)"); insertStmt.setInt(1, 42); insertStmt.setString(2, "foo"); insertStmt.executeUpdate(); PreparedStatement metaStmt = connection.prepareStatement( "SELECT idx, s FROM test.mymetadata WHERE idx = ?"); metaStmt.setInt(1, 42); metaStmt.executeQuery(); ResultSetMetaData metadata = metaStmt.getMetaData(); Assert.assertEquals(metadata.getColumnCount(), 2); Assert.assertEquals(metadata.getColumnName(1), "idx"); Assert.assertEquals(metadata.getColumnName(2), "s"); } @Test public void testMetadataExecutionAfterMeta() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.mymetadata"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.mymetadata " + "(idx Int32, s String) " + "ENGINE = TinyLog" ); PreparedStatement insertStmt = connection.prepareStatement( "INSERT INTO test.mymetadata (idx, s) VALUES (?, ?)"); insertStmt.setInt(1, 42); insertStmt.setString(2, "foo"); insertStmt.executeUpdate(); PreparedStatement metaStmt = connection.prepareStatement( "SELECT idx, s FROM test.mymetadata WHERE idx = ?"); metaStmt.setInt(1, 42); ResultSetMetaData metadata = metaStmt.getMetaData(); Assert.assertEquals(metadata.getColumnCount(), 2); Assert.assertEquals(metadata.getColumnName(1), "idx"); Assert.assertEquals(metadata.getColumnName(2), "s"); ResultSet rs = metaStmt.executeQuery(); Assert.assertTrue(rs.next()); Assert.assertEquals(rs.getInt(1), 42); Assert.assertEquals(rs.getString(2), "foo"); metadata = metaStmt.getMetaData(); Assert.assertEquals(metadata.getColumnCount(), 2); Assert.assertEquals(metadata.getColumnName(1), "idx"); Assert.assertEquals(metadata.getColumnName(2), "s"); } @Test public void testMetadataOnlyUpdate() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.mymetadata"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.mymetadata " + "(idx Int32, s String) " + "ENGINE = TinyLog" ); PreparedStatement insertStmt = connection.prepareStatement( "INSERT INTO test.mymetadata (idx, s) VALUES (?, ?)"); insertStmt.setInt(1, 42); insertStmt.setString(2, "foo"); insertStmt.executeUpdate(); PreparedStatement metaStmt = connection.prepareStatement( "UPDATE test.mymetadata SET s = ? WHERE idx = ?"); metaStmt.setString(1, "foo"); metaStmt.setInt(2, 42); ResultSetMetaData metadata = metaStmt.getMetaData(); Assert.assertNull(metadata); metaStmt.close(); } @Test public void testInsertWithFunctions() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.insertfunctions"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.insertfunctions " + "(id UInt32, foo String, bar String) " + "ENGINE = TinyLog"); PreparedStatement stmt = connection.prepareStatement( "INSERT INTO test.insertfunctions(id, foo, bar) VALUES " + "(?, lower(reverse(?)), upper(reverse(?)))"); stmt.setInt(1, 42); stmt.setString(2, "Foo"); stmt.setString(3, "Bar"); String sql = stmt.unwrap(ClickHousePreparedStatementImpl.class).asSql(); Assert.assertEquals( sql, "INSERT INTO test.insertfunctions(id, foo, bar) VALUES " + "(42, lower(reverse('Foo')), upper(reverse('Bar')))"); // make sure that there is no exception stmt.execute(); ResultSet rs = connection.createStatement().executeQuery( "SELECT id, foo, bar FROM test.insertfunctions"); rs.next(); Assert.assertEquals(rs.getInt(1), 42); Assert.assertEquals(rs.getString(2), "oof"); Assert.assertEquals(rs.getString(3), "RAB"); rs.close(); } public void testBytes() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.strings_versus_bytes"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.strings_versus_bytes" + "(s String, fs FixedString(8)) " + "ENGINE = TinyLog" ); PreparedStatement insertStmt = connection.prepareStatement( "INSERT INTO test.strings_versus_bytes (s, fs) VALUES (?, ?)"); insertStmt.setBytes(1, "foo".getBytes(Charset.forName("UTF-8"))); insertStmt.setBytes(2, "bar".getBytes(Charset.forName("UTF-8"))); insertStmt.executeUpdate(); ResultSet rs = connection.createStatement().executeQuery( "SELECT s, fs FROM test.strings_versus_bytes"); rs.next(); Assert.assertEquals(rs.getString(1), "foo"); // TODO: The actual String returned by our ResultSet is rather strange // ['b' 'a' 'r' 0 0 0 0 0] Assert.assertEquals(rs.getString(2).trim(), "bar"); } @Test public void testInsertWithFunctionsAddBatch() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.insertfunctions"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.insertfunctions " + "(id UInt32, foo String, bar String) " + "ENGINE = TinyLog"); PreparedStatement stmt = connection.prepareStatement( "INSERT INTO test.insertfunctions(id, foo, bar) VALUES " + "(?, lower(reverse(?)), upper(reverse(?)))"); stmt.setInt(1, 42); stmt.setString(2, "Foo"); stmt.setString(3, "Bar"); stmt.addBatch(); stmt.executeBatch(); // this will _not_ perform the functions, but instead send the parameters // as is to the clickhouse server } @SuppressWarnings("boxing") @Test public void testMultiLineValues() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.multiline"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.multiline" + "(foo Int32, bar String) " + "ENGINE = TinyLog" ); PreparedStatement insertStmt = connection.prepareStatement( "INSERT INTO test.multiline\n" + "\t(foo, bar)\r\n" + "\t\tVALUES\n" + "(?, ?) , \n\r" + "\t(?,?),(?,?)\n"); Map<Integer, String> testData = new HashMap<Integer, String>(); testData.put(23, "baz"); testData.put(42, "bar"); testData.put(1337, "oof"); int i = 0; for (Integer k : testData.keySet()) { insertStmt.setInt(++i, k.intValue()); insertStmt.setString(++i, testData.get(k)); } insertStmt.executeUpdate(); ResultSet rs = connection.createStatement().executeQuery( "SELECT * FROM test.multiline ORDER BY foo"); rs.next(); Assert.assertEquals(rs.getInt(1), 23); Assert.assertEquals(rs.getString(2), "baz"); rs.next(); Assert.assertEquals(rs.getInt(1), 42); Assert.assertEquals(rs.getString(2), "bar"); rs.next(); Assert.assertEquals(rs.getInt(1), 1337); Assert.assertEquals(rs.getString(2), "oof"); Assert.assertFalse(rs.next()); } // Issue 153 public void testArrayDateTime() throws Exception { connection.createStatement().execute( "DROP TABLE IF EXISTS test.date_time_array"); connection.createStatement().execute( "CREATE TABLE IF NOT EXISTS test.date_time_array" + "(foo Array(DateTime)) " + "ENGINE = TinyLog" ); PreparedStatement stmt = connection.prepareStatement( "INSERT INTO test.date_time_array (foo) VALUES (?)"); stmt.setArray(1, connection.createArrayOf("DateTime", new Timestamp[] { new Timestamp(1557136800000L), new Timestamp(1560698526598L) })); stmt.execute(); ResultSet rs = connection.createStatement().executeQuery( "SELECT foo FROM test.date_time_array"); rs.next(); Timestamp[] result = (Timestamp[]) rs.getArray(1).getArray(); Assert.assertEquals(result[0].getTime(), 1557136800000L); Assert.assertEquals(result[1].getTime(), 1560698526598L); } private static byte[] randomEncodedUUID() { UUID uuid = UUID.randomUUID(); return ByteBuffer.allocate(16) .putLong(uuid.getMostSignificantBits()) .putLong(uuid.getLeastSignificantBits()) .array(); } }