[#5764] Add support for inlining SQL Server table valued parameters in SQL
This commit is contained in:
parent
a2670855c5
commit
50db69abbd
@ -86,7 +86,7 @@ import org.jooq.tools.StopWatchListener;
|
||||
* <h3>Types composing its state:</h3>
|
||||
* <ul>
|
||||
* <li>{@link #dialect()}: The {@link SQLDialect} that defines the underlying
|
||||
* database's behaviour when generating SQL syntax, or binding variables, or
|
||||
* database's behaviour when generating SQL syntax, or bind variables, or
|
||||
* when executing the query</li>
|
||||
* <li>{@link #settings()}: The {@link Settings} that define general jOOQ
|
||||
* behaviour</li>
|
||||
|
||||
@ -2254,7 +2254,7 @@ public interface DSLContext extends Scope , AutoCloseable {
|
||||
/**
|
||||
* Create a new query holding plain SQL.
|
||||
* <p>
|
||||
* There must not be any binding variables contained in the SQL
|
||||
* There must not be any bind variables contained in the SQL
|
||||
* <p>
|
||||
* Use this method, when you want to take advantage of the many ways to
|
||||
* fetch results in jOOQ, using {@link ResultQuery}. Some examples:
|
||||
@ -2300,7 +2300,7 @@ public interface DSLContext extends Scope , AutoCloseable {
|
||||
/**
|
||||
* Create a new query holding plain SQL.
|
||||
* <p>
|
||||
* There must not be any binding variables contained in the SQL
|
||||
* There must not be any bind variables contained in the SQL
|
||||
* <p>
|
||||
* Use this method, when you want to take advantage of the many ways to
|
||||
* fetch results in jOOQ, using {@link ResultQuery}. Some examples:
|
||||
|
||||
@ -425,7 +425,7 @@ public interface ExecuteListener extends EventListener, Serializable {
|
||||
void prepareEnd(ExecuteContext ctx);
|
||||
|
||||
/**
|
||||
* Called before binding variables to the <code>PreparedStatement</code>
|
||||
* Called before bind variables to the <code>PreparedStatement</code>
|
||||
* <p>
|
||||
* Available attributes from <code>ExecuteContext</code>:
|
||||
* <ul>
|
||||
@ -468,7 +468,7 @@ public interface ExecuteListener extends EventListener, Serializable {
|
||||
void bindStart(ExecuteContext ctx);
|
||||
|
||||
/**
|
||||
* Called after binding variables to the <code>PreparedStatement</code>
|
||||
* Called after bind variables to the <code>PreparedStatement</code>
|
||||
* <p>
|
||||
* Available attributes from <code>ExecuteContext</code>:
|
||||
* <ul>
|
||||
|
||||
@ -449,14 +449,12 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query {
|
||||
static class Rendered {
|
||||
String sql;
|
||||
QueryPartList<Param<?>> bindValues;
|
||||
int skipUpdateCounts;
|
||||
|
||||
Rendered(String sql) {
|
||||
this(sql, null);
|
||||
}
|
||||
|
||||
Rendered(String sql, QueryPartList<Param<?>> bindValues) {
|
||||
Rendered(String sql, QueryPartList<Param<?>> bindValues, int skipUpdateCounts) {
|
||||
this.sql = sql;
|
||||
this.bindValues = bindValues;
|
||||
this.skipUpdateCounts = skipUpdateCounts;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -471,22 +469,24 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query {
|
||||
// [#3542] [#4977] Some dialects do not support bind values in DDL statements
|
||||
if (ctx.type() == DDL) {
|
||||
ctx.data(DATA_FORCE_STATIC_STATEMENT, true);
|
||||
result = new Rendered(getSQL(INLINED));
|
||||
DefaultRenderContext render = new DefaultRenderContext(configuration);
|
||||
result = new Rendered(render.paramType(INLINED).visit(this).render(), null, render.peekSkipUpdateCounts());
|
||||
}
|
||||
else if (executePreparedStatements(configuration().settings())) {
|
||||
try {
|
||||
DefaultRenderContext render = new DefaultRenderContext(configuration);
|
||||
render.data(DATA_COUNT_BIND_VALUES, true);
|
||||
render.visit(this);
|
||||
result = new Rendered(render.render(), render.bindValues());
|
||||
result = new Rendered(render.visit(this).render(), render.bindValues(), render.peekSkipUpdateCounts());
|
||||
}
|
||||
catch (DefaultRenderContext.ForceInlineSignal e) {
|
||||
ctx.data(DATA_FORCE_STATIC_STATEMENT, true);
|
||||
result = new Rendered(getSQL(INLINED));
|
||||
DefaultRenderContext render = new DefaultRenderContext(configuration);
|
||||
result = new Rendered(render.paramType(INLINED).visit(this).render(), null, render.peekSkipUpdateCounts());
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = new Rendered(getSQL(INLINED));
|
||||
DefaultRenderContext render = new DefaultRenderContext(configuration);
|
||||
result = new Rendered(render.paramType(INLINED).visit(this).render(), null, render.peekSkipUpdateCounts());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -256,7 +256,7 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
|
||||
if (ctx.family() == POSTGRES && f != 0 && ctx.connection().getAutoCommit())
|
||||
log.info("Fetch Size", "A fetch size of " + f + " was set on a auto-commit PostgreSQL connection, which is not recommended. See http://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor");
|
||||
|
||||
executeStatementAndGetFirstResultSet(ctx);
|
||||
executeStatementAndGetFirstResultSet(ctx, rendered.skipUpdateCounts);
|
||||
listener.executeEnd(ctx);
|
||||
|
||||
// Fetch a single result set
|
||||
|
||||
@ -502,7 +502,7 @@ public abstract class AbstractRoutine<T> extends AbstractQueryPart implements Ro
|
||||
private final void execute0(ExecuteContext ctx, ExecuteListener listener) throws SQLException {
|
||||
try {
|
||||
listener.executeStart(ctx);
|
||||
executeStatementAndGetFirstResultSet(ctx);
|
||||
executeStatementAndGetFirstResultSet(ctx, 0);
|
||||
listener.executeEnd(ctx);
|
||||
}
|
||||
|
||||
|
||||
@ -85,6 +85,47 @@ package org.jooq.impl;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -9109,7 +9109,7 @@ public class DSL {
|
||||
* <p>
|
||||
* A plain SQL <code>QueryPart</code> is a <code>QueryPart</code> that can
|
||||
* contain user-defined plain SQL, because sometimes it is easier to express
|
||||
* things directly in SQL. There must be as many binding variables contained
|
||||
* things directly in SQL. There must be as many bind variables contained
|
||||
* in the SQL, as passed in the bindings parameter
|
||||
* <p>
|
||||
* This overload takes a set of bind value arguments which are replaced our
|
||||
@ -9192,7 +9192,7 @@ public class DSL {
|
||||
* <p>
|
||||
* A plain SQL <code>QueryPart</code> is a <code>QueryPart</code> that can
|
||||
* contain user-defined plain SQL, because sometimes it is easier to express
|
||||
* things directly in SQL. There must be as many binding variables contained
|
||||
* things directly in SQL. There must be as many bind variables contained
|
||||
* in the SQL, as passed in the bindings parameter
|
||||
* <p>
|
||||
* <b>NOTE</b>: When inserting plain SQL into jOOQ objects, you must
|
||||
@ -9328,7 +9328,7 @@ public class DSL {
|
||||
/**
|
||||
* Create a new query holding plain SQL.
|
||||
* <p>
|
||||
* There must not be any binding variables contained in the SQL
|
||||
* There must not be any bind variables contained in the SQL
|
||||
* <p>
|
||||
* Use this method, when you want to take advantage of the many ways to
|
||||
* fetch results in jOOQ, using {@link ResultQuery}. Some examples:
|
||||
@ -9376,7 +9376,7 @@ public class DSL {
|
||||
/**
|
||||
* Create a new query holding plain SQL.
|
||||
* <p>
|
||||
* There must not be any binding variables contained in the SQL
|
||||
* There must not be any bind variables contained in the SQL
|
||||
* <p>
|
||||
* Use this method, when you want to take advantage of the many ways to
|
||||
* fetch results in jOOQ, using {@link ResultQuery}. Some examples:
|
||||
@ -9568,7 +9568,7 @@ public class DSL {
|
||||
* A plain SQL table is a table that can contain user-defined plain SQL,
|
||||
* because sometimes it is easier to express things directly in SQL, for
|
||||
* instance complex, but static subqueries or tables from different schemas.
|
||||
* There must be as many binding variables contained in the SQL, as passed
|
||||
* There must be as many bind variables contained in the SQL, as passed
|
||||
* in the bindings parameter
|
||||
* <p>
|
||||
* Example
|
||||
@ -10144,7 +10144,7 @@ public class DSL {
|
||||
/**
|
||||
* Create a new condition holding plain SQL.
|
||||
* <p>
|
||||
* There must not be any binding variables contained in the SQL.
|
||||
* There must not be any bind variables contained in the SQL.
|
||||
* <p>
|
||||
* Example:
|
||||
* <p>
|
||||
@ -10169,7 +10169,7 @@ public class DSL {
|
||||
/**
|
||||
* Create a new condition holding plain SQL.
|
||||
* <p>
|
||||
* There must not be any binding variables contained in the SQL.
|
||||
* There must not be any bind variables contained in the SQL.
|
||||
* <p>
|
||||
* Example:
|
||||
* <p>
|
||||
@ -10194,7 +10194,7 @@ public class DSL {
|
||||
/**
|
||||
* Create a new condition holding plain SQL.
|
||||
* <p>
|
||||
* There must be as many binding variables contained in the SQL, as passed
|
||||
* There must be as many bind variables contained in the SQL, as passed
|
||||
* in the bindings parameter
|
||||
* <p>
|
||||
* Example:
|
||||
|
||||
@ -91,6 +91,7 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
|
||||
private int printMargin = 80;
|
||||
private boolean separator;
|
||||
private boolean newline;
|
||||
private int skipUpdateCounts;
|
||||
|
||||
// [#1632] Cached values from Settings
|
||||
RenderKeywordStyle cachedRenderKeywordStyle;
|
||||
@ -143,6 +144,14 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
|
||||
// RenderContext API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
final int peekSkipUpdateCounts() {
|
||||
return skipUpdateCounts;
|
||||
}
|
||||
|
||||
final void incrementSkipUpdateCounts() {
|
||||
skipUpdateCounts++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String peekAlias() {
|
||||
return "alias_" + (alias + 1);
|
||||
|
||||
@ -47,6 +47,7 @@ import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
// ...
|
||||
import static org.jooq.conf.BackslashEscaping.DEFAULT;
|
||||
import static org.jooq.conf.BackslashEscaping.ON;
|
||||
import static org.jooq.conf.ParamType.INLINED;
|
||||
@ -433,6 +434,25 @@ final class Tools {
|
||||
* list's parentheses).
|
||||
*/
|
||||
DATA_INSERT_SELECT_WITHOUT_INSERT_COLUMN_LIST,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3073,7 +3093,7 @@ final class Tools {
|
||||
* [#5666] Handle the complexity of each dialect's understanding of
|
||||
* correctly calling {@link Statement#execute()}.
|
||||
*/
|
||||
static final void executeStatementAndGetFirstResultSet(ExecuteContext ctx) throws SQLException {
|
||||
static final void executeStatementAndGetFirstResultSet(ExecuteContext ctx, int skipUpdateCounts) throws SQLException {
|
||||
PreparedStatement stmt = ctx.statement();
|
||||
|
||||
|
||||
@ -3100,6 +3120,39 @@ final class Tools {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -3831,4 +3884,11 @@ final class Tools {
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
static final void increment(Map<Object, Object> data, DataKey key) {
|
||||
Integer updateCounts = (Integer) data.get(key);
|
||||
if (updateCounts == null)
|
||||
updateCounts = 0;
|
||||
data.put(key, updateCounts + 1);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user