[jOOQ/jOOQ#11886] Avoid parentheses when rendering associative concatenation chains
This includes: - [jOOQ/jOOQ#16745] Wrong SQL rendered for MS Access CONCAT function with more than 2 arguments
This commit is contained in:
parent
5a5ac940be
commit
55d044f50f
@ -39,13 +39,16 @@ package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.DSL.function;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
import static org.jooq.impl.DSL.systemName;
|
||||
import static org.jooq.impl.ExpressionOperator.ADD;
|
||||
import static org.jooq.impl.ExpressionOperator.CONCAT;
|
||||
import static org.jooq.impl.Names.N_CONCAT;
|
||||
import static org.jooq.impl.Tools.EMPTY_FIELD;
|
||||
import static org.jooq.impl.Tools.castAllIfNeeded;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Function1;
|
||||
@ -64,6 +67,7 @@ final class Concat extends AbstractField<String> implements QOM.Concat {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
if (arguments.length == 0) {
|
||||
@ -75,24 +79,15 @@ final class Concat extends AbstractField<String> implements QOM.Concat {
|
||||
return;
|
||||
}
|
||||
|
||||
// [#461] Type cast the concat expression, if this isn't a VARCHAR field
|
||||
Field<String>[] cast = castAllIfNeeded(arguments, String.class);
|
||||
|
||||
if (Boolean.TRUE.equals(ctx.settings().isRenderCoalesceToEmptyStringInConcat()) && ctx.configuration().commercial(() -> "Auto-coalescing of CONCAT arguments is available in the jOOQ 3.15 Professional Edition and jOOQ Enterprise Edition, see https://github.com/jOOQ/jOOQ/issues/11757")) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Field<String>[] cast = (Field<String>[]) cast(ctx).toArray(EMPTY_FIELD);
|
||||
ExpressionOperator op = CONCAT;
|
||||
|
||||
switch (ctx.family()) {
|
||||
|
||||
|
||||
case MARIADB:
|
||||
case MYSQL:
|
||||
ctx.visit(function(systemName("concat"), SQLDataType.VARCHAR, cast));
|
||||
ctx.visit(function(N_CONCAT, SQLDataType.VARCHAR, cast));
|
||||
return;
|
||||
|
||||
|
||||
@ -110,11 +105,55 @@ final class Concat extends AbstractField<String> implements QOM.Concat {
|
||||
|
||||
}
|
||||
|
||||
Field<?> expression = new Expression<>(op, false, cast[0], cast[1]);
|
||||
ctx.sql('(');
|
||||
Expression.acceptAssociative(
|
||||
ctx,
|
||||
(QOM.UOperator2) toExpression(op, cast),
|
||||
op.toQueryPart(),
|
||||
c -> c.sql(' '),
|
||||
Expression.Associativity.BOTH
|
||||
);
|
||||
ctx.sql(')');
|
||||
}
|
||||
|
||||
private final List<Field<String>> cast(Context<?> ctx) {
|
||||
List<Field<String>> result = cast(ctx, new ArrayList<>());
|
||||
|
||||
if (Boolean.TRUE.equals(ctx.settings().isRenderCoalesceToEmptyStringInConcat()) && ctx.configuration().commercial(() -> "Auto-coalescing of CONCAT arguments is available in the jOOQ 3.15 Professional Edition and jOOQ Enterprise Edition, see https://github.com/jOOQ/jOOQ/issues/11757")) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private final List<Field<String>> cast(Context<?> ctx, List<Field<String>> result) {
|
||||
|
||||
// [#461] Type cast the concat expression, if this isn't a VARCHAR field
|
||||
for (Field<String> f : castAllIfNeeded(arguments, String.class)) {
|
||||
if (f instanceof Concat c)
|
||||
c.cast(ctx, result);
|
||||
else
|
||||
result.add(f);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private final Expression<?> toExpression(ExpressionOperator op, Field<String>[] cast) {
|
||||
Expression<?> expression = new Expression<>(op, false, cast[0], cast[1]);
|
||||
|
||||
for (int i = 2; i < cast.length; i++)
|
||||
expression = new Expression<>(op, false, expression, cast[i]);
|
||||
|
||||
ctx.visit(expression);
|
||||
return expression;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -37,7 +37,11 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.DSL.raw;
|
||||
|
||||
import org.jooq.Name;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.SQL;
|
||||
|
||||
/**
|
||||
* The operator used in <code>Expression</code>
|
||||
@ -74,6 +78,7 @@ enum ExpressionOperator {
|
||||
;
|
||||
|
||||
private final String sql;
|
||||
private final SQL queryPart;
|
||||
private final Name name;
|
||||
private final boolean associative;
|
||||
private final boolean commutative;
|
||||
@ -84,6 +89,7 @@ enum ExpressionOperator {
|
||||
|
||||
private ExpressionOperator(String sql, boolean associative, boolean commutative) {
|
||||
this.sql = sql;
|
||||
this.queryPart = raw(sql);
|
||||
this.name = DSL.name(name().toLowerCase());
|
||||
this.associative = associative;
|
||||
this.commutative = commutative;
|
||||
@ -93,6 +99,10 @@ enum ExpressionOperator {
|
||||
return sql;
|
||||
}
|
||||
|
||||
final QueryPart toQueryPart() {
|
||||
return queryPart;
|
||||
}
|
||||
|
||||
final Name toName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user