diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index 950d109da..e70410c6a 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -55,19 +55,19 @@ jobs: if: ${{ inputs.skip_tests != 'true' }} run: make test - - name: Deploy - shell: bash - env: - AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} - run: | - cp build/release/duckdb_jdbc.jar duckdb_jdbc-linux-amd64.jar - ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-linux-amd64.jar - - uses: actions/upload-artifact@v3 - with: - name: java-linux-amd64 - path: | - build/release/duckdb_jdbc.jar + # - name: Deploy + # shell: bash + # env: + # AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} + # AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} + # run: | + # cp build/release/duckdb_jdbc.jar duckdb_jdbc-linux-amd64.jar + # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-linux-amd64.jar + # - uses: actions/upload-artifact@v4 + # with: + # name: java-linux-amd64 + # path: | + # build/release/duckdb_jdbc.jar java-linux-aarch64: name: Java Linux (aarch64) @@ -99,20 +99,20 @@ jobs: shell: bash run: CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ OVERRIDE_JDBC_OS_ARCH=arm64 make release - - name: Deploy - shell: bash - env: - AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} - run: | - cp build/release/duckdb_jdbc.jar duckdb_jdbc-linux-aarch64.jar - # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-linux-aarch64.jar + # - name: Deploy + # shell: bash + # env: + # AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} + # AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} + # run: | + # cp build/release/duckdb_jdbc.jar duckdb_jdbc-linux-aarch64.jar + # # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-linux-aarch64.jar - - uses: actions/upload-artifact@v3 - with: - name: java-linux-aarch64 - path: | - build/release/duckdb_jdbc.jar + # - uses: actions/upload-artifact@v4 + # with: + # name: java-linux-aarch64 + # path: | + # build/release/duckdb_jdbc.jar java-windows-amd64: @@ -142,19 +142,19 @@ jobs: run: | ls -R . make test - - name: Deploy - shell: bash - env: - AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} - run: | - cp build/release/duckdb_jdbc.jar duckdb_jdbc-windows-amd64.jar - ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-windows-amd64.jar - - uses: actions/upload-artifact@v3 - with: - name: java-windows-amd64 - path: | - build/release/duckdb_jdbc.jar + # - name: Deploy + # shell: bash + # env: + # AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} + # AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} + # run: | + # cp build/release/duckdb_jdbc.jar duckdb_jdbc-windows-amd64.jar + # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-windows-amd64.jar + # - uses: actions/upload-artifact@v4 + # with: + # name: java-windows-amd64 + # path: | + # build/release/duckdb_jdbc.jar java-osx-universal: @@ -184,19 +184,19 @@ jobs: - name: See if this actually universal shell: bash run: lipo -archs build/release/libduckdb_java.so_osx_universal | grep "x86_64 arm64" - - name: Deploy - shell: bash - env: - AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} - run: | - cp build/release/duckdb_jdbc.jar duckdb_jdbc-osx-universal.jar - ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-osx-universal.jar - - uses: actions/upload-artifact@v3 - with: - name: java-osx-universal - path: | - build/release/duckdb_jdbc.jar + # - name: Deploy + # shell: bash + # env: + # AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} + # AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} + # run: | + # cp build/release/duckdb_jdbc.jar duckdb_jdbc-osx-universal.jar + # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-osx-universal.jar + # - uses: actions/upload-artifact@v4 + # with: + # name: java-osx-universal + # path: | + # build/release/duckdb_jdbc.jar java-combine: @@ -265,13 +265,13 @@ jobs: fi ls -lahR jdbc-artifacts - - name: Upload artifacts - if: always() - uses: actions/upload-artifact@v3 - with: - name: java-jars - path: | - jdbc-artifacts + # - name: Upload artifacts + # if: always() + # uses: actions/upload-artifact@v4 + # with: + # name: java-jars + # path: | + # jdbc-artifacts jdbc-compliance: name: JDBC Compliance diff --git a/.gitignore b/.gitignore index 427bdb67f..2d635d6bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build .idea cmake-build-debug +out diff --git a/src/main/java/org/duckdb/DuckDBAppender.java b/src/main/java/org/duckdb/DuckDBAppender.java index 08eb5ef35..814be1be3 100644 --- a/src/main/java/org/duckdb/DuckDBAppender.java +++ b/src/main/java/org/duckdb/DuckDBAppender.java @@ -93,6 +93,42 @@ public void append(byte[] value) throws SQLException { } } + private void appendNull() throws SQLException { + DuckDBNative.duckdb_jdbc_appender_append_null(appender_ref); + } + + public void append(Boolean value) throws SQLException { + if (value == null) { + this.appendNull(); + } else { + append(value.booleanValue()); + } + } + + public void append(Long value) throws SQLException { + if (value == null) { + this.appendNull(); + } else { + append(value.longValue()); + } + } + + public void append(Short value) throws SQLException { + if (value == null) { + this.appendNull(); + } else { + append(value.shortValue()); + } + } + + public void append(Integer value) throws SQLException { + if (value == null) { + this.appendNull(); + } else { + append(value.intValue()); + } + } + protected void finalize() throws Throwable { close(); } diff --git a/src/main/main.iml b/src/main/main.iml new file mode 100644 index 000000000..908ad4f52 --- /dev/null +++ b/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/org/duckdb/TestDuckDBJDBC.java b/src/test/java/org/duckdb/TestDuckDBJDBC.java index 1908d89e9..9ed04eda2 100644 --- a/src/test/java/org/duckdb/TestDuckDBJDBC.java +++ b/src/test/java/org/duckdb/TestDuckDBJDBC.java @@ -2713,6 +2713,112 @@ public static void test_appender_null_integer() throws Exception { conn.close(); } + public static void test_appender_Boolean() throws Exception { + try (DuckDBConnection conn = DriverManager.getConnection(JDBC_URL).unwrap(DuckDBConnection.class); + Statement stmt = conn.createStatement();) { + + stmt.execute("CREATE TABLE data (a BOOLEAN)"); + DuckDBAppender appender = conn.createAppender(DuckDBConnection.DEFAULT_SCHEMA, "data"); + Boolean[] values = new Boolean[] {Boolean.TRUE, Boolean.FALSE, null}; + for (Boolean value : values) { + appender.beginRow(); + appender.append(value); + appender.endRow(); + } + appender.flush(); + appender.close(); + + try (ResultSet results = stmt.executeQuery("SELECT count(1) FROM data WHERE a = true");) { + assertTrue(results.next()); + assertEquals(1, results.getInt(1)); + } + try (ResultSet results = stmt.executeQuery("SELECT count(1) FROM data WHERE a = false");) { + assertTrue(results.next()); + assertEquals(1, results.getInt(1)); + } + try (ResultSet results = stmt.executeQuery("SELECT count(1) FROM data WHERE a is null");) { + assertTrue(results.next()); + assertEquals(1, results.getInt(1)); + } + } + } + + public static void test_appender_Integer() throws Exception { + try (DuckDBConnection conn = DriverManager.getConnection(JDBC_URL).unwrap(DuckDBConnection.class); + Statement stmt = conn.createStatement();) { + + stmt.execute("CREATE TABLE data (a INTEGER)"); + DuckDBAppender appender = conn.createAppender(DuckDBConnection.DEFAULT_SCHEMA, "data"); + appender.beginRow(); + + Integer value = Integer.MAX_VALUE - 10; + + appender.append(value); + appender.endRow(); + appender.flush(); + appender.close(); + + try (ResultSet results = stmt.executeQuery("SELECT * FROM data");) { + assertTrue(results.next()); + assertEquals(value, results.getInt(1)); + assertFalse(results.wasNull()); + } + } + } + + public static void test_appender_Long() throws Exception { + try (DuckDBConnection conn = DriverManager.getConnection(JDBC_URL).unwrap(DuckDBConnection.class); + Statement stmt = conn.createStatement();) { + + stmt.execute("CREATE TABLE data (a LONG)"); + DuckDBAppender appender = conn.createAppender(DuckDBConnection.DEFAULT_SCHEMA, "data"); + appender.beginRow(); + + Long value = Long.MAX_VALUE - 10; + + appender.append(value); + appender.endRow(); + appender.flush(); + appender.close(); + + try (ResultSet results = stmt.executeQuery("SELECT * FROM data");) { + assertTrue(results.next()); + assertEquals(value, results.getLong(1)); + assertFalse(results.wasNull()); + } + } + } + + public static void test_appender_Short() throws Exception { + try (DuckDBConnection conn = DriverManager.getConnection(JDBC_URL).unwrap(DuckDBConnection.class); + Statement stmt = conn.createStatement();) { + + stmt.execute("CREATE TABLE data (a SHORT)"); + DuckDBAppender appender = conn.createAppender(DuckDBConnection.DEFAULT_SCHEMA, "data"); + + Short shortValue = Short.MIN_VALUE; + while (true) { + appender.beginRow(); + appender.append(shortValue); + appender.endRow(); + if (shortValue == Short.MAX_VALUE) { + break; + } + shortValue++; + } + appender.flush(); + appender.close(); + + try (ResultSet results = stmt.executeQuery("SELECT min(a), max(a), avg(a) FROM data");) { + assertTrue(results.next()); + assertEquals(Short.MIN_VALUE, results.getShort(1)); + assertEquals(Short.MAX_VALUE, results.getShort(2)); + assertEquals(-0.5f, results.getFloat(3)); + assertFalse(results.wasNull()); + } + } + } + public static void test_appender_null_varchar() throws Exception { DuckDBConnection conn = DriverManager.getConnection(JDBC_URL).unwrap(DuckDBConnection.class); Statement stmt = conn.createStatement(); diff --git a/src/test/test.iml b/src/test/test.iml index a0e49a3ba..5ebc6f48e 100644 --- a/src/test/test.iml +++ b/src/test/test.iml @@ -7,5 +7,6 @@ + \ No newline at end of file