[#8502] Add support for H2 1.4.198 row value expression subquery syntax

H2 breaks backwards compatibility in 1.4.198 and supports row value expressions at the price of desupporting the "old" vendor specific array syntax. This means we can now remove some H2 specific logic and implement standard row value expression syntax also for H2
This commit is contained in:
lukaseder 2019-04-09 17:49:26 +02:00
parent 19b19411c0
commit a55a362fd8
4 changed files with 37 additions and 45 deletions

View File

@ -42,7 +42,6 @@ import static java.lang.Boolean.TRUE;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.val;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY;
import org.jooq.Configuration;
import org.jooq.Context;
@ -53,6 +52,7 @@ import org.jooq.QueryPartInternal;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.Select;
import org.jooq.impl.Tools.BooleanDataKey;
/**
* @author Lukas Eder
@ -82,23 +82,28 @@ final class QuantifiedSelectImpl<R extends Record> extends AbstractQueryPart imp
@Override
public final void accept(Context<?> ctx) {
boolean extraParentheses = false;
ctx.visit(quantifier.toKeyword());
ctx.visit(quantifier.toKeyword())
.sql(extraParentheses ? " ((" : " (")
.subquery(true)
ctx.subquery(true)
.formatIndentStart()
.formatNewLine()
.visit(delegate(ctx.configuration()))
.formatIndentEnd()
.formatNewLine()
.subquery(false)
.sql(extraParentheses ? "))" : ")");
.subquery(false);
}
private final QueryPartInternal delegate(Configuration ctx) {

View File

@ -59,7 +59,6 @@ import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.notExists;
import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY;
import java.util.EnumSet;
@ -78,6 +77,7 @@ import org.jooq.Row;
import org.jooq.RowN;
import org.jooq.SQLDialect;
import org.jooq.Select;
import org.jooq.impl.Tools.BooleanDataKey;
/**
* @author Lukas Eder
@ -220,15 +220,14 @@ final class RowSubqueryCondition extends AbstractCondition {
if (rightQuantified == null) {
// Some databases need extra parentheses around the RHS
boolean extraParentheses = false
;
ctx.sql(extraParentheses ? "((" : "(");
ctx.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY, true);
ctx.subquery(true)
.formatIndentStart()
.formatNewLine()
@ -236,17 +235,26 @@ final class RowSubqueryCondition extends AbstractCondition {
.formatIndentEnd()
.formatNewLine()
.subquery(false);
ctx.data().remove(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY);
ctx.sql(extraParentheses ? "))" : ")");
}
// [#2054] Quantified row value expression comparison predicates shouldn't have parentheses before ANY or ALL
else {
ctx.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY, true);
ctx.subquery(true)
.visit(rightQuantified)
.subquery(false);
ctx.data().remove(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY);
}
}

View File

@ -134,7 +134,6 @@ import static org.jooq.impl.Tools.BooleanDataKey.DATA_INSERT_SELECT_WITHOUT_INSE
import static org.jooq.impl.Tools.BooleanDataKey.DATA_NESTED_SET_OPERATIONS;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_OMIT_INTO_CLAUSE;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_RENDER_TRAILING_LIMIT_IF_APPLICABLE;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_UNALIAS_ALIASES_IN_ORDER_BY;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_WRAP_DERIVED_TABLES_IN_PARENTHESES;
import static org.jooq.impl.Tools.DataKey.DATA_COLLECTED_SEMI_ANTI_JOIN;
@ -1248,23 +1247,6 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
context.visit(new SelectFieldList<Field<?>>(alternativeFields));
}
// [#1905] H2 only knows arrays, no row value expressions. Subqueries
// in the context of a row value expression predicate have to render
// arrays explicitly, as the subquery doesn't form an implicit RVE
else if (context.subquery() && dialect == H2 && TRUE.equals(context.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY))) {
Object data = context.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY);
try {
context.data().remove(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY);
context.sql('(')
.visit(getSelect1())
.sql(')');
}
finally {
context.data(DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY, data);
}
}
// The default behaviour
else {
context.visit(getSelect1());

View File

@ -310,16 +310,6 @@ final class Tools {
*/
DATA_OMIT_RETURNING_CLAUSE,
/**
* [#1905] This constant is used internally by jOOQ to indicate to
* subqueries that they're being rendered in the context of a row value
* expression predicate.
* <p>
* This is particularly useful for H2, which pretends that ARRAYs and RVEs
* are the same
*/
DATA_ROW_VALUE_EXPRESSION_PREDICATE_SUBQUERY,
/**
* [#1296] This constant is used internally by jOOQ to indicate that
* {@link ResultSet} rows must be locked to emulate a
@ -386,6 +376,13 @@ final class Tools {