diff --git a/jOOQ-test/src/test/java/org/jooq/test/all/testcases/BatchTests.java b/jOOQ-test/src/test/java/org/jooq/test/all/testcases/BatchTests.java index 8a1b063cf6..0933be73e2 100644 --- a/jOOQ-test/src/test/java/org/jooq/test/all/testcases/BatchTests.java +++ b/jOOQ-test/src/test/java/org/jooq/test/all/testcases/BatchTests.java @@ -150,6 +150,29 @@ extends BaseTest authors = create().fetch(TAuthor()).sortAsc(TAuthor_ID()); + assertEquals(4, authors.size()); + assertEquals(3, (int) authors.get(2).getValue(TAuthor_ID())); + assertEquals(4, (int) authors.get(3).getValue(TAuthor_ID())); + assertEquals("X", authors.get(2).getValue(TAuthor_LAST_NAME())); + assertEquals("Y", authors.get(3).getValue(TAuthor_LAST_NAME())); + } + public void testBatchSingleWithNulls() throws Exception { Batch batch = create().batch(insertInto(TDates(), TDates_ID(), TDates_D(), TDates_T(), TDates_TS()) .values(1, null, null, null)) diff --git a/jOOQ-test/src/test/java/org/jooq/test/jOOQAbstractTest.java b/jOOQ-test/src/test/java/org/jooq/test/jOOQAbstractTest.java index a5e8f7ec9a..cf4e987809 100644 --- a/jOOQ-test/src/test/java/org/jooq/test/jOOQAbstractTest.java +++ b/jOOQ-test/src/test/java/org/jooq/test/jOOQAbstractTest.java @@ -2796,6 +2796,11 @@ public abstract class jOOQAbstractTest< new BatchTests(this).testBatchSingle(); } + @Test + public void testBatchSinglePlainSQL() throws Exception { + new BatchTests(this).testBatchSinglePlainSQL(); + } + @Test public void testBatchSingleWithNulls() throws Exception { new BatchTests(this).testBatchSingleWithNulls(); diff --git a/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java b/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java index 87f164dad7..5ca6c0164c 100644 --- a/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java +++ b/jOOQ/src/main/java/org/jooq/impl/BatchSingle.java @@ -43,6 +43,8 @@ package org.jooq.impl; import static org.jooq.conf.ParamType.INLINED; import static org.jooq.conf.SettingsTools.executeStaticStatements; import static org.jooq.impl.Utils.consumeWarnings; +import static org.jooq.impl.Utils.fields; +import static org.jooq.impl.Utils.getDataTypes; import static org.jooq.impl.Utils.visitAll; import java.sql.Connection; @@ -53,9 +55,10 @@ import java.util.List; import org.jooq.BatchBindStep; import org.jooq.Configuration; import org.jooq.DSLContext; +import org.jooq.DataType; import org.jooq.ExecuteContext; import org.jooq.ExecuteListener; -import org.jooq.Param; +import org.jooq.Field; import org.jooq.Query; /** @@ -119,12 +122,7 @@ class BatchSingle implements BatchBindStep { Connection connection = ctx.connection(); // [#1371] fetch bind variables to restore them again, later - List> params = new ArrayList>(query.getParams().values()); - List previous = new ArrayList(); - - for (Param param : params) { - previous.add(param.getValue()); - } + DataType[] paramTypes = getDataTypes(query.getParams().values().toArray(new Field[0])); try { listener.renderStart(ctx); @@ -139,12 +137,14 @@ class BatchSingle implements BatchBindStep { for (Object[] bindValues : allBindValues) { listener.bindStart(ctx); - // [#1371] [#2139] Don't bind variables directly onto statement, - // bind them through the collected params list to preserve type - // information - for (int i = 0; i < params.size(); i++) { - params.get(i).setConverted(bindValues[i]); - } + // [#1371] [#2139] Don't bind variables directly onto statement, bind them through the collected params + // list to preserve type information + // [#3547] The original query may have no Params specified - e.g. when it was constructed with + // plain SQL. In that case, infer the bind value type directly from the bind value + List> params = (paramTypes.length > 0) + ? fields(bindValues, paramTypes) + : fields(bindValues); + visitAll(new DefaultBindContext(configuration, ctx.statement()), params); listener.bindEnd(ctx); @@ -178,11 +178,6 @@ class BatchSingle implements BatchBindStep { } finally { Utils.safeClose(listener, ctx); - - // Restore bind variables to values prior to batch execution - for (int i = 0; i < params.size(); i++) { - params.get(i).setConverted(previous.get(i)); - } } }