diff --git a/src/jni/duckdb_java.cpp b/src/jni/duckdb_java.cpp index ef051abe..f24b03c0 100644 --- a/src/jni/duckdb_java.cpp +++ b/src/jni/duckdb_java.cpp @@ -397,6 +397,12 @@ struct ConnectionHolder { } }; +// Returns the pointer's memory address of duckdb::DuckDB as a jlong +jlong _duckdb_jdbc_db_memory_address(JNIEnv *env, jclass, jobject conn_ref_buf) { + auto conn_ref = (ConnectionHolder *)env->GetDirectBufferAddress(conn_ref_buf); + return (jlong)conn_ref->db.get(); +} + /** * Throws a SQLException and returns nullptr if a valid Connection can't be retrieved from the buffer. */ diff --git a/src/jni/functions.cpp b/src/jni/functions.cpp index e4f0826b..a78cb9ff 100644 --- a/src/jni/functions.cpp +++ b/src/jni/functions.cpp @@ -26,6 +26,17 @@ JNIEXPORT jobject JNICALL Java_org_duckdb_DuckDBNative_duckdb_1jdbc_1connect(JNI } } +JNIEXPORT jlong JNICALL Java_org_duckdb_DuckDBNative_duckdb_1jdbc_1db_1memory_1address(JNIEnv * env, jclass param0, jobject param1) { + try { + return _duckdb_jdbc_db_memory_address(env, param0, param1); + } catch (const std::exception &e) { + duckdb::ErrorData error(e); + ThrowJNI(env, error.Message().c_str()); + + return -1; + } +} + JNIEXPORT void JNICALL Java_org_duckdb_DuckDBNative_duckdb_1jdbc_1set_1auto_1commit(JNIEnv * env, jclass param0, jobject param1, jboolean param2) { try { return _duckdb_jdbc_set_auto_commit(env, param0, param1, param2); diff --git a/src/jni/functions.hpp b/src/jni/functions.hpp index 1267b3f7..c084499c 100644 --- a/src/jni/functions.hpp +++ b/src/jni/functions.hpp @@ -17,6 +17,10 @@ jobject _duckdb_jdbc_connect(JNIEnv * env, jclass param0, jobject param1); JNIEXPORT jobject JNICALL Java_org_duckdb_DuckDBNative_duckdb_1jdbc_1connect(JNIEnv * env, jclass param0, jobject param1); +jlong _duckdb_jdbc_db_memory_address(JNIEnv * env, jclass param0, jobject param1); + +JNIEXPORT jlong JNICALL Java_org_duckdb_DuckDBNative_duckdb_1jdbc_1db_1memory_1address(JNIEnv * env, jclass param0, jobject param1); + void _duckdb_jdbc_set_auto_commit(JNIEnv * env, jclass param0, jobject param1, jboolean param2); JNIEXPORT void JNICALL Java_org_duckdb_DuckDBNative_duckdb_1jdbc_1set_1auto_1commit(JNIEnv * env, jclass param0, jobject param1, jboolean param2); diff --git a/src/main/java/org/duckdb/DuckDBConnection.java b/src/main/java/org/duckdb/DuckDBConnection.java index 798c7292..642dbe6d 100644 --- a/src/main/java/org/duckdb/DuckDBConnection.java +++ b/src/main/java/org/duckdb/DuckDBConnection.java @@ -371,4 +371,26 @@ public void registerArrowStream(String name, Object arrow_array_stream) { long array_stream_address = getArrowStreamAddress(arrow_array_stream); DuckDBNative.duckdb_jdbc_arrow_register(conn_ref, array_stream_address, name.getBytes(StandardCharsets.UTF_8)); } + + /** + *
Gets the memory address of the DuckDB C++ object from within JNI. With this it is possible to create + * database connections outside the JDBC driver.
+ *Big warning: The JDBC driver does not know anything about these outside connection! Closing the + * database must happen with JDBC! Using outside connections implies keeping at least one JDBC connection open to + * avoid accessing freed memory!
+ * @return The memory address as a Java long. 0 indicates no open connection. + */ + public long getDuckDBMemoryAddress() { + if (this.conn_ref != null) { + return DuckDBNative.duckdb_jdbc_db_memory_address(this.conn_ref); + } + return 0; + } + + /** + *Gets the path and temporal file name of the duckdb_java lib as it was loaded via System.load().
+ */ + public String getDuckDBResourceFile() { + return DuckDBNative.getDuckDBResourceFile(); + } } diff --git a/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java b/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java index 2a6f8f5e..b3a15855 100644 --- a/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java +++ b/src/main/java/org/duckdb/DuckDBDatabaseMetaData.java @@ -689,8 +689,8 @@ public ResultSet getCatalogs() throws SQLException { public ResultSet getSchemas() throws SQLException { Statement statement = conn.createStatement(); statement.closeOnCompletion(); - return statement.executeQuery( - "SELECT schema_name AS 'TABLE_SCHEM', catalog_name AS 'TABLE_CATALOG' FROM information_schema.schemata ORDER BY \"TABLE_CATALOG\", \"TABLE_SCHEM\""); + return statement.executeQuery("SELECT schema_name AS 'TABLE_SCHEM', catalog_name AS 'TABLE_CATALOG' FROM " + + "information_schema.schemata ORDER BY \"TABLE_CATALOG\", \"TABLE_SCHEM\""); } @Override diff --git a/src/main/java/org/duckdb/DuckDBNative.java b/src/main/java/org/duckdb/DuckDBNative.java index d03eff58..560d4eba 100644 --- a/src/main/java/org/duckdb/DuckDBNative.java +++ b/src/main/java/org/duckdb/DuckDBNative.java @@ -50,17 +50,27 @@ class DuckDBNative { URL lib_res = DuckDBNative.class.getResource(lib_res_name); if (lib_res == null) { System.load(Paths.get("build/debug", lib_res_name).normalize().toAbsolutePath().toString()); + duckDBResourceFile = Paths.get("build/debug", lib_res_name).normalize().toAbsolutePath().toString(); } else { try (final InputStream lib_res_input_stream = lib_res.openStream()) { Files.copy(lib_res_input_stream, lib_file, StandardCopyOption.REPLACE_EXISTING); } new File(lib_file.toString()).deleteOnExit(); System.load(lib_file.toAbsolutePath().toString()); + duckDBResourceFile = lib_file.toAbsolutePath().toString(); } } catch (IOException e) { throw new RuntimeException(e); } } + + // Full path and name of the libduckdb_java.so + private static final String duckDBResourceFile; + + protected static String getDuckDBResourceFile() { + return duckDBResourceFile; + } + // We use zero-length ByteBuffer-s as a hacky but cheap way to pass C++ pointers // back and forth @@ -76,6 +86,8 @@ protected static native ByteBuffer duckdb_jdbc_startup(byte[] path, boolean read // returns conn_ref connection reference object protected static native ByteBuffer duckdb_jdbc_connect(ByteBuffer db_ref) throws SQLException; + protected static native long duckdb_jdbc_db_memory_address(ByteBuffer conn_ref); + protected static native void duckdb_jdbc_set_auto_commit(ByteBuffer conn_ref, boolean auto_commit) throws SQLException; diff --git a/src/main/java/org/duckdb/DuckDBPreparedStatement.java b/src/main/java/org/duckdb/DuckDBPreparedStatement.java index 1b078f03..b1dfc36f 100644 --- a/src/main/java/org/duckdb/DuckDBPreparedStatement.java +++ b/src/main/java/org/duckdb/DuckDBPreparedStatement.java @@ -189,8 +189,8 @@ public int executeUpdate() throws SQLException { requireNonBatch(); execute(); if (!(returnsChangedRows || returnsNothing)) { - throw new SQLException( - "executeUpdate() can only be used with queries that return nothing (eg, a DDL statement), or update rows"); + throw new SQLException("executeUpdate() can only be used with queries that return nothing (eg, a DDL " + + "statement), or update rows"); } return getUpdateCountInternal(); } diff --git a/src/test/java/org/duckdb/TestDuckDBJDBC.java b/src/test/java/org/duckdb/TestDuckDBJDBC.java index 1908d89e..92c68b37 100644 --- a/src/test/java/org/duckdb/TestDuckDBJDBC.java +++ b/src/test/java/org/duckdb/TestDuckDBJDBC.java @@ -26,6 +26,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.security.SecureRandom; import java.sql.*; import java.time.Instant; @@ -149,6 +150,31 @@ public static void test_connection() throws Exception { assertThrows(conn::createStatement, SQLException.class); } + public static void test_duckdb_path_to_lib() throws Exception { + Connection conn = DriverManager.getConnection(JDBC_URL); + assertTrue(conn.isValid(0)); + assertFalse(conn.isClosed()); + + Path libPath = Paths.get(((DuckDBConnection) conn).getDuckDBResourceFile()); + assertTrue(Files.exists(libPath)); + conn.close(); + } + + public static void test_duckdb_memory_address() throws Exception { + Connection conn = DriverManager.getConnection(JDBC_URL); + assertTrue(conn.isValid(0)); + assertFalse(conn.isClosed()); + + // Unfortunately it seems to be impossible to test the memory + // address without writing test code inside jni. So the only test here + // is that the result is a long and it is not 0 or negative. + + long memoryAddress = ((DuckDBConnection) conn).getDuckDBMemoryAddress(); + assertTrue(Long.class.isInstance(memoryAddress)); + assertTrue(memoryAddress > 0); + conn.close(); + } + public static void test_prepare_exception() throws Exception { Connection conn = DriverManager.getConnection(JDBC_URL); Statement stmt = conn.createStatement(); @@ -270,60 +296,60 @@ public static void test_enum() throws Exception { "CREATE TYPE enum_long AS ENUM ('enum0' ,'enum1' ,'enum2' ,'enum3' ,'enum4' ,'enum5' ,'enum6'" + ",'enum7' ,'enum8' ,'enum9' ,'enum10' ,'enum11' ,'enum12' ,'enum13' ,'enum14' ,'enum15' ,'enum16' ,'enum17'" - + - ",'enum18' ,'enum19' ,'enum20' ,'enum21' ,'enum22' ,'enum23' ,'enum24' ,'enum25' ,'enum26' ,'enum27' ,'enum28'" - + - ",'enum29' ,'enum30' ,'enum31' ,'enum32' ,'enum33' ,'enum34' ,'enum35' ,'enum36' ,'enum37' ,'enum38' ,'enum39'" - + - ",'enum40' ,'enum41' ,'enum42' ,'enum43' ,'enum44' ,'enum45' ,'enum46' ,'enum47' ,'enum48' ,'enum49' ,'enum50'" - + - ",'enum51' ,'enum52' ,'enum53' ,'enum54' ,'enum55' ,'enum56' ,'enum57' ,'enum58' ,'enum59' ,'enum60' ,'enum61'" - + - ",'enum62' ,'enum63' ,'enum64' ,'enum65' ,'enum66' ,'enum67' ,'enum68' ,'enum69' ,'enum70' ,'enum71' ,'enum72'" - + - ",'enum73' ,'enum74' ,'enum75' ,'enum76' ,'enum77' ,'enum78' ,'enum79' ,'enum80' ,'enum81' ,'enum82' ,'enum83'" - + - ",'enum84' ,'enum85' ,'enum86' ,'enum87' ,'enum88' ,'enum89' ,'enum90' ,'enum91' ,'enum92' ,'enum93' ,'enum94'" + + ",'enum18' ,'enum19' ,'enum20' ,'enum21' ,'enum22' ,'enum23' ,'enum24' ,'enum25' ,'enum26' ,'enum27' " + + ",'enum28'" + + ",'enum29' ,'enum30' ,'enum31' ,'enum32' ,'enum33' ,'enum34' ,'enum35' ,'enum36' ,'enum37' ,'enum38' " + + ",'enum39'" + + ",'enum40' ,'enum41' ,'enum42' ,'enum43' ,'enum44' ,'enum45' ,'enum46' ,'enum47' ,'enum48' ,'enum49' " + + ",'enum50'" + + ",'enum51' ,'enum52' ,'enum53' ,'enum54' ,'enum55' ,'enum56' ,'enum57' ,'enum58' ,'enum59' ,'enum60' " + + ",'enum61'" + + ",'enum62' ,'enum63' ,'enum64' ,'enum65' ,'enum66' ,'enum67' ,'enum68' ,'enum69' ,'enum70' ,'enum71' " + + ",'enum72'" + + ",'enum73' ,'enum74' ,'enum75' ,'enum76' ,'enum77' ,'enum78' ,'enum79' ,'enum80' ,'enum81' ,'enum82' " + + ",'enum83'" + + ",'enum84' ,'enum85' ,'enum86' ,'enum87' ,'enum88' ,'enum89' ,'enum90' ,'enum91' ,'enum92' ,'enum93' " + + ",'enum94'" + ",'enum95' ,'enum96' ,'enum97' ,'enum98' ,'enum99' ,'enum100' ,'enum101' ,'enum102' ,'enum103' ,'enum104' " - + - ",'enum105' ,'enum106' ,'enum107' ,'enum108' ,'enum109' ,'enum110' ,'enum111' ,'enum112' ,'enum113' ,'enum114'" - + - ",'enum115' ,'enum116' ,'enum117' ,'enum118' ,'enum119' ,'enum120' ,'enum121' ,'enum122' ,'enum123' ,'enum124'" - + - ",'enum125' ,'enum126' ,'enum127' ,'enum128' ,'enum129' ,'enum130' ,'enum131' ,'enum132' ,'enum133' ,'enum134'" - + - ",'enum135' ,'enum136' ,'enum137' ,'enum138' ,'enum139' ,'enum140' ,'enum141' ,'enum142' ,'enum143' ,'enum144'" - + - ",'enum145' ,'enum146' ,'enum147' ,'enum148' ,'enum149' ,'enum150' ,'enum151' ,'enum152' ,'enum153' ,'enum154'" - + - ",'enum155' ,'enum156' ,'enum157' ,'enum158' ,'enum159' ,'enum160' ,'enum161' ,'enum162' ,'enum163' ,'enum164'" - + - ",'enum165' ,'enum166' ,'enum167' ,'enum168' ,'enum169' ,'enum170' ,'enum171' ,'enum172' ,'enum173' ,'enum174'" - + - ",'enum175' ,'enum176' ,'enum177' ,'enum178' ,'enum179' ,'enum180' ,'enum181' ,'enum182' ,'enum183' ,'enum184'" - + - ",'enum185' ,'enum186' ,'enum187' ,'enum188' ,'enum189' ,'enum190' ,'enum191' ,'enum192' ,'enum193' ,'enum194'" - + - ",'enum195' ,'enum196' ,'enum197' ,'enum198' ,'enum199' ,'enum200' ,'enum201' ,'enum202' ,'enum203' ,'enum204'" - + - ",'enum205' ,'enum206' ,'enum207' ,'enum208' ,'enum209' ,'enum210' ,'enum211' ,'enum212' ,'enum213' ,'enum214'" - + - ",'enum215' ,'enum216' ,'enum217' ,'enum218' ,'enum219' ,'enum220' ,'enum221' ,'enum222' ,'enum223' ,'enum224'" - + - ",'enum225' ,'enum226' ,'enum227' ,'enum228' ,'enum229' ,'enum230' ,'enum231' ,'enum232' ,'enum233' ,'enum234'" - + - ",'enum235' ,'enum236' ,'enum237' ,'enum238' ,'enum239' ,'enum240' ,'enum241' ,'enum242' ,'enum243' ,'enum244'" - + - ",'enum245' ,'enum246' ,'enum247' ,'enum248' ,'enum249' ,'enum250' ,'enum251' ,'enum252' ,'enum253' ,'enum254'" - + - ",'enum255' ,'enum256' ,'enum257' ,'enum258' ,'enum259' ,'enum260' ,'enum261' ,'enum262' ,'enum263' ,'enum264'" - + - ",'enum265' ,'enum266' ,'enum267' ,'enum268' ,'enum269' ,'enum270' ,'enum271' ,'enum272' ,'enum273' ,'enum274'" - + - ",'enum275' ,'enum276' ,'enum277' ,'enum278' ,'enum279' ,'enum280' ,'enum281' ,'enum282' ,'enum283' ,'enum284'" - + - ",'enum285' ,'enum286' ,'enum287' ,'enum288' ,'enum289' ,'enum290' ,'enum291' ,'enum292' ,'enum293' ,'enum294'" + + ",'enum105' ,'enum106' ,'enum107' ,'enum108' ,'enum109' ,'enum110' ,'enum111' ,'enum112' ,'enum113' " + + ",'enum114'" + + ",'enum115' ,'enum116' ,'enum117' ,'enum118' ,'enum119' ,'enum120' ,'enum121' ,'enum122' ,'enum123' " + + ",'enum124'" + + ",'enum125' ,'enum126' ,'enum127' ,'enum128' ,'enum129' ,'enum130' ,'enum131' ,'enum132' ,'enum133' " + + ",'enum134'" + + ",'enum135' ,'enum136' ,'enum137' ,'enum138' ,'enum139' ,'enum140' ,'enum141' ,'enum142' ,'enum143' " + + ",'enum144'" + + ",'enum145' ,'enum146' ,'enum147' ,'enum148' ,'enum149' ,'enum150' ,'enum151' ,'enum152' ,'enum153' " + + ",'enum154'" + + ",'enum155' ,'enum156' ,'enum157' ,'enum158' ,'enum159' ,'enum160' ,'enum161' ,'enum162' ,'enum163' " + + ",'enum164'" + + ",'enum165' ,'enum166' ,'enum167' ,'enum168' ,'enum169' ,'enum170' ,'enum171' ,'enum172' ,'enum173' " + + ",'enum174'" + + ",'enum175' ,'enum176' ,'enum177' ,'enum178' ,'enum179' ,'enum180' ,'enum181' ,'enum182' ,'enum183' " + + ",'enum184'" + + ",'enum185' ,'enum186' ,'enum187' ,'enum188' ,'enum189' ,'enum190' ,'enum191' ,'enum192' ,'enum193' " + + ",'enum194'" + + ",'enum195' ,'enum196' ,'enum197' ,'enum198' ,'enum199' ,'enum200' ,'enum201' ,'enum202' ,'enum203' " + + ",'enum204'" + + ",'enum205' ,'enum206' ,'enum207' ,'enum208' ,'enum209' ,'enum210' ,'enum211' ,'enum212' ,'enum213' " + + ",'enum214'" + + ",'enum215' ,'enum216' ,'enum217' ,'enum218' ,'enum219' ,'enum220' ,'enum221' ,'enum222' ,'enum223' " + + ",'enum224'" + + ",'enum225' ,'enum226' ,'enum227' ,'enum228' ,'enum229' ,'enum230' ,'enum231' ,'enum232' ,'enum233' " + + ",'enum234'" + + ",'enum235' ,'enum236' ,'enum237' ,'enum238' ,'enum239' ,'enum240' ,'enum241' ,'enum242' ,'enum243' " + + ",'enum244'" + + ",'enum245' ,'enum246' ,'enum247' ,'enum248' ,'enum249' ,'enum250' ,'enum251' ,'enum252' ,'enum253' " + + ",'enum254'" + + ",'enum255' ,'enum256' ,'enum257' ,'enum258' ,'enum259' ,'enum260' ,'enum261' ,'enum262' ,'enum263' " + + ",'enum264'" + + ",'enum265' ,'enum266' ,'enum267' ,'enum268' ,'enum269' ,'enum270' ,'enum271' ,'enum272' ,'enum273' " + + ",'enum274'" + + ",'enum275' ,'enum276' ,'enum277' ,'enum278' ,'enum279' ,'enum280' ,'enum281' ,'enum282' ,'enum283' " + + ",'enum284'" + + ",'enum285' ,'enum286' ,'enum287' ,'enum288' ,'enum289' ,'enum290' ,'enum291' ,'enum292' ,'enum293' " + + ",'enum294'" + ",'enum295' ,'enum296' ,'enum297' ,'enum298' ,'enum299');"); stmt.execute("CREATE TABLE t2 (id INT, e1 enum_long);"); @@ -926,12 +952,11 @@ public static void test_duckdb_getObject_with_class() throws Exception { + " flt FLOAT, dbl DOUBLE, dte DATE, tme TIME, ts TIMESTAMP, dec16 DECIMAL(3,1)," + " dec32 DECIMAL(9,8), dec64 DECIMAL(16,1), dec128 DECIMAL(30,10), tint TINYINT, utint UTINYINT," + " usint USMALLINT, uint UINTEGER, ubig UBIGINT, hin HUGEINT, uhin UHUGEINT, blo BLOB)"); - stmt.execute( - "INSERT INTO b VALUES ('varchary', true, 6, 42, 666, 42.666, 666.42," - + - " '1970-01-02', '01:00:34', '1970-01-03 03:42:23', 42.2, 1.23456789, 987654321012345.6, 111112222233333.44444, " - + " -4, 200, 50001, 4000111222, 18446744073709551615, 18446744073709551616, " - + " 170141183460469231731687303715884105728, 'yeah'::BLOB)"); + stmt.execute("INSERT INTO b VALUES ('varchary', true, 6, 42, 666, 42.666, 666.42," + + " '1970-01-02', '01:00:34', '1970-01-03 03:42:23', 42.2, 1.23456789, 987654321012345.6, " + + "111112222233333.44444, " + + " -4, 200, 50001, 4000111222, 18446744073709551615, 18446744073709551616, " + + " 170141183460469231731687303715884105728, 'yeah'::BLOB)"); PreparedStatement ps = conn.prepareStatement("SELECT * FROM b"); ResultSet rs = ps.executeQuery(); @@ -1035,8 +1060,8 @@ public static void test_multiple_statements_exception() throws Exception { public static void test_bigdecimal() throws Exception { Connection conn = DriverManager.getConnection(JDBC_URL); Statement stmt = conn.createStatement(); - stmt.execute( - "CREATE TABLE q (id DECIMAL(3,0), dec16 DECIMAL(4,1), dec32 DECIMAL(9,4), dec64 DECIMAL(18,7), dec128 DECIMAL(38,10))"); + stmt.execute("CREATE TABLE q (id DECIMAL(3,0), dec16 DECIMAL(4,1), dec32 DECIMAL(9,4), dec64 DECIMAL(18,7), " + + "dec128 DECIMAL(38,10))"); PreparedStatement ps1 = conn.prepareStatement("INSERT INTO q (id, dec16, dec32, dec64, dec128) VALUES (?, ?, ?, ?, ?)"); @@ -1285,8 +1310,8 @@ public static void test_big_data() throws Exception { stmt.execute("INSERT INTO a VALUES (" + i + ")"); } - ResultSet rs = stmt.executeQuery( - "SELECT CAST(i AS SMALLINT), CAST(i AS INTEGER), CAST(i AS BIGINT), CAST(i AS FLOAT), CAST(i AS DOUBLE), CAST(i as STRING), NULL FROM a"); + ResultSet rs = stmt.executeQuery("SELECT CAST(i AS SMALLINT), CAST(i AS INTEGER), CAST(i AS BIGINT), CAST(i " + + "AS FLOAT), CAST(i AS DOUBLE), CAST(i as STRING), NULL FROM a"); int count = 0; while (rs.next()) { for (int col = 1; col <= 6; col++) { @@ -1419,7 +1444,8 @@ public static void test_prepare_types() throws Exception { Connection conn = DriverManager.getConnection(JDBC_URL); PreparedStatement ps = conn.prepareStatement( - "SELECT CAST(? AS BOOLEAN) c1, CAST(? AS TINYINT) c2, CAST(? AS SMALLINT) c3, CAST(? AS INTEGER) c4, CAST(? AS BIGINT) c5, CAST(? AS FLOAT) c6, CAST(? AS DOUBLE) c7, CAST(? AS STRING) c8"); + "SELECT CAST(? AS BOOLEAN) c1, CAST(? AS TINYINT) c2, CAST(? AS SMALLINT) c3, CAST(? AS INTEGER) c4, " + + "CAST(? AS BIGINT) c5, CAST(? AS FLOAT) c6, CAST(? AS DOUBLE) c7, CAST(? AS STRING) c8"); ps.setBoolean(1, true); ps.setByte(2, (byte) 42); ps.setShort(3, (short) 43); @@ -1522,8 +1548,8 @@ public static void test_prepare_insert() throws Exception { } pStmt1.close(); - conn.createStatement().executeUpdate( - "create table ctstable2 (KEY_ID int, COF_NAME varchar(32), PRICE float, TYPE_ID int, primary key(KEY_ID) )"); + conn.createStatement().executeUpdate("create table ctstable2 (KEY_ID int, COF_NAME varchar(32), PRICE float, " + + "TYPE_ID int, primary key(KEY_ID) )"); PreparedStatement pStmt = conn.prepareStatement("insert into ctstable2 values(?, ?, ?, ?)"); for (int i = 1; i <= 10; i++) { @@ -1640,8 +1666,9 @@ public static void test_hugeint() throws Exception { Connection conn = DriverManager.getConnection(JDBC_URL); Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery( - "SELECT 42::hugeint hi1, -42::hugeint hi2, 454564646545646546545646545::hugeint hi3, -454564646545646546545646545::hugeint hi4"); + ResultSet rs = + stmt.executeQuery("SELECT 42::hugeint hi1, -42::hugeint hi2, 454564646545646546545646545::hugeint hi3, " + + "-454564646545646546545646545::hugeint hi4"); assertTrue(rs.next()); assertEquals(rs.getObject("hi1"), new BigInteger("42")); assertEquals(rs.getObject("hi2"), new BigInteger("-42")); @@ -1663,8 +1690,8 @@ public static void test_temporal_types() throws Exception { Connection conn = DriverManager.getConnection(JDBC_URL); Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery( - "SELECT '2019-11-26 21:11:00'::timestamp ts, '2019-11-26'::date dt, interval '5 days' iv, '21:11:00'::time te"); + ResultSet rs = stmt.executeQuery("SELECT '2019-11-26 21:11:00'::timestamp ts, '2019-11-26'::date dt, " + + "interval '5 days' iv, '21:11:00'::time te"); assertTrue(rs.next()); assertEquals(rs.getObject("ts"), Timestamp.valueOf("2019-11-26 21:11:00")); assertEquals(rs.getTimestamp("ts"), Timestamp.valueOf("2019-11-26 21:11:00")); @@ -2995,8 +3022,8 @@ public static void test_unsigned_integers() throws Exception { DuckDBConnection conn = DriverManager.getConnection(JDBC_URL).unwrap(DuckDBConnection.class); Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery( - "SELECT 201::utinyint uint8, 40001::usmallint uint16, 4000000001::uinteger uint32, 18446744073709551615::ubigint uint64"); + ResultSet rs = stmt.executeQuery("SELECT 201::utinyint uint8, 40001::usmallint uint16, 4000000001::uinteger " + + "uint32, 18446744073709551615::ubigint uint64"); assertTrue(rs.next()); assertEquals(rs.getShort("uint8"), Short.valueOf((short) 201)); @@ -3450,9 +3477,9 @@ public static void test_supports_catalogs_in_table_definitions() throws Exceptio statement.execute(String.format("CREATE TABLE %s (id int)", QUALIFIED_TABLE_NAME)); } catch (SQLException ex) { if (supportsCatalogsInTableDefinitions) { - fail( - "supportsCatalogsInTableDefinitions is true but CREATE TABLE in attached database is not allowed. " + - ex.getMessage()); + fail("supportsCatalogsInTableDefinitions is true but CREATE TABLE in attached database is not " + + "allowed. " + + ex.getMessage()); ex.printStackTrace(); } } @@ -3465,9 +3492,9 @@ public static void test_supports_catalogs_in_table_definitions() throws Exceptio statement.execute(String.format("DROP TABLE %s", QUALIFIED_TABLE_NAME)); } catch (SQLException ex) { if (supportsCatalogsInTableDefinitions) { - fail( - "supportsCatalogsInTableDefinitions is true but DROP TABLE in attached database is not allowed. " + - ex.getMessage()); + fail("supportsCatalogsInTableDefinitions is true but DROP TABLE in attached database is not " + + "allowed. " + + ex.getMessage()); ex.printStackTrace(); } } @@ -4022,12 +4049,16 @@ static