From 50901345ff0487be7b6761ea0f55b40f099de695 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 27 Mar 2024 13:42:06 +0100 Subject: [PATCH] [jOOQ/jOOQ#15732] Work around https://github.com/duckdb/duckdb/issues/11381 --- .../main/java/org/jooq/impl/BlobBinding.java | 54 +++++++++++-------- .../java/org/jooq/impl/DefaultBinding.java | 25 +++------ 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/BlobBinding.java b/jOOQ/src/main/java/org/jooq/impl/BlobBinding.java index fb752ff576..ab8e552e5f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/BlobBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/BlobBinding.java @@ -48,6 +48,7 @@ import static org.jooq.impl.DefaultExecuteContext.localConnection; import static org.jooq.impl.DefaultExecuteContext.localTargetConnection; import static org.jooq.impl.Tools.asInt; +import java.io.IOException; import java.sql.Blob; import java.sql.Connection; import java.sql.SQLException; @@ -66,7 +67,9 @@ import org.jooq.Converter; import org.jooq.Converters; import org.jooq.ResourceManagingScope; import org.jooq.SQLDialect; +import org.jooq.Scope; import org.jooq.conf.ParamType; +import org.jooq.exception.ExceptionTools; import org.jooq.impl.R2DBC.R2DBCPreparedStatement; import org.jooq.impl.R2DBC.R2DBCResultSet; import org.jooq.tools.jdbc.JDBCUtils; @@ -145,13 +148,7 @@ public class BlobBinding implements Binding { } else if (!NO_SUPPORT_LOBS.contains(ctx.dialect())) { Blob blob = ctx.resultSet().getBlob(ctx.index()); - - try { - ctx.value(blob == null ? null : blob.getBytes(1, asInt(blob.length()))); - } - finally { - JDBCUtils.safeFree(blob); - } + ctx.value(blob == null ? null : readBlob(ctx, blob)); } else ctx.value(ctx.resultSet().getBytes(ctx.index())); @@ -161,13 +158,7 @@ public class BlobBinding implements Binding { public final void get(BindingGetStatementContext ctx) throws SQLException { if (!NO_SUPPORT_LOBS.contains(ctx.dialect())) { Blob blob = ctx.statement().getBlob(ctx.index()); - - try { - ctx.value(blob == null ? null : blob.getBytes(1, asInt(blob.length()))); - } - finally { - JDBCUtils.safeFree(blob); - } + ctx.value(blob == null ? null : readBlob(ctx, blob)); } else ctx.value(ctx.statement().getBytes(ctx.index())); @@ -177,13 +168,7 @@ public class BlobBinding implements Binding { public final void get(BindingGetSQLInputContext ctx) throws SQLException { if (!NO_SUPPORT_LOBS.contains(ctx.dialect())) { Blob blob = ctx.input().readBlob(); - - try { - ctx.value(blob == null ? null : blob.getBytes(1, asInt(blob.length()))); - } - finally { - JDBCUtils.safeFree(blob); - } + ctx.value(blob == null ? null : readBlob(ctx, blob)); } else ctx.value(ctx.input().readBytes()); @@ -217,4 +202,31 @@ public class BlobBinding implements Binding { blob.setBytes(1, bytes); return blob; } + + static final byte[] readBlob(Scope ctx, Blob blob) throws SQLException { + try { + switch (ctx.family()) { + + // [#15732] Work around https://github.com/duckdb/duckdb/issues/11381 + case DUCKDB: + try { + return blob.getBinaryStream().readAllBytes(); + } + catch (IOException e) { + SQLException cause = ExceptionTools.getCause(e, SQLException.class); + + if (cause != null) + throw cause; + else + throw new SQLException(e); + } + + default: + return blob.getBytes(1, asInt(blob.length())); + } + } + finally { + JDBCUtils.safeFree(blob); + } + } } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index 4c9283ad24..2f899d8acc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -91,6 +91,7 @@ import static org.jooq.SQLDialect.TRINO; import static org.jooq.SQLDialect.YUGABYTEDB; import static org.jooq.conf.ParamType.INLINED; import static org.jooq.impl.Array.NO_SUPPORT_SQUARE_BRACKETS; +import static org.jooq.impl.BlobBinding.readBlob; import static org.jooq.impl.Convert.convert; import static org.jooq.impl.Convert.patchIso8601Timestamp; import static org.jooq.impl.DSL.cast; @@ -188,6 +189,7 @@ import static org.jooq.util.postgres.PostgresUtils.toPGArrayString; import static org.jooq.util.postgres.PostgresUtils.toPGInterval; import static org.jooq.util.postgres.PostgresUtils.toYearToMonth; +import java.io.IOException; import java.io.Serializable; import java.io.StringReader; import java.lang.reflect.Modifier; @@ -2294,7 +2296,6 @@ public class DefaultBinding implements Binding { @Override final void set0(BindingSetStatementContext ctx, byte[] value) throws SQLException { switch (ctx.family()) { - case DUCKDB: case H2: blobs.set(new DefaultBindingSetStatementContext<>(ctx.executeContext(), ctx.statement(), ctx.index(), value)); break; @@ -2358,13 +2359,6 @@ public class DefaultBinding implements Binding { - - - - - - - return ctx.input().readBytes(); } @@ -3883,17 +3877,17 @@ public class DefaultBinding implements Binding { @Override final Object get0(BindingGetResultSetContext ctx) throws SQLException { - return unlob(ctx.resultSet().getObject(ctx.index())); + return unlob(ctx, ctx.resultSet().getObject(ctx.index())); } @Override final Object get0(BindingGetStatementContext ctx) throws SQLException { - return unlob(ctx.statement().getObject(ctx.index())); + return unlob(ctx, ctx.statement().getObject(ctx.index())); } @Override final Object get0(BindingGetSQLInputContext ctx) throws SQLException { - return unlob(ctx.input().readObject()); + return unlob(ctx, ctx.input().readObject()); } @Override @@ -3905,14 +3899,9 @@ public class DefaultBinding implements Binding { * [#2534] Extract byte[] or String data from a * LOB, if the argument is a lob. */ - private static final Object unlob(Object object) throws SQLException { + private static final Object unlob(Scope ctx, Object object) throws SQLException { if (object instanceof Blob blob) { - try { - return blob.getBytes(1, asInt(blob.length())); - } - finally { - JDBCUtils.safeFree(blob); - } + return readBlob(ctx, blob); } else if (object instanceof Clob clob) { try {