[jOOQ/jOOQ#11254] Add lambda constructor in CustomField, CustomCondition, CustomQueryPart

This commit is contained in:
Lukas Eder 2021-01-19 19:33:11 +01:00
parent 7876d6adce
commit 7606c434d4
9 changed files with 123 additions and 103 deletions

View File

@ -78,7 +78,6 @@ final class BoolAnd extends DefaultAggregateFunction<Boolean> {
}
}
@SuppressWarnings("serial")
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -93,13 +92,10 @@ final class BoolAnd extends DefaultAggregateFunction<Boolean> {
break;
default:
final Field<Integer> max = DSL.field("{0}", Integer.class, new CustomQueryPart() {
@Override
public void accept(Context<?> c) {
c.visit(DSL.min(DSL.when(condition, one()).otherwise(zero())));
acceptOverClause(c);
}
});
final Field<Integer> max = DSL.field("{0}", Integer.class, CustomQueryPart.of(c -> {
c.visit(DSL.min(DSL.when(condition, one()).otherwise(zero())));
acceptOverClause(c);
}));
ctx.visit(DSL.field(max.eq(one())));
break;

View File

@ -78,7 +78,6 @@ final class BoolOr extends DefaultAggregateFunction<Boolean> {
}
}
@SuppressWarnings("serial")
@Override
public final void accept(Context<?> ctx) {
switch (ctx.family()) {
@ -93,13 +92,10 @@ final class BoolOr extends DefaultAggregateFunction<Boolean> {
break;
default:
final Field<Integer> max = DSL.field("{0}", Integer.class, new CustomQueryPart() {
@Override
public void accept(Context<?> c) {
c.visit(DSL.max(DSL.when(condition, one()).otherwise(zero())));
acceptOverClause(c);
}
});
final Field<Integer> max = DSL.field("{0}", Integer.class, CustomQueryPart.of(c -> {
c.visit(DSL.max(DSL.when(condition, one()).otherwise(zero())));
acceptOverClause(c);
}));
ctx.visit(DSL.field(max.eq(one())));
break;

View File

@ -39,6 +39,8 @@ package org.jooq.impl;
import static org.jooq.Clause.CUSTOM;
import java.util.function.Consumer;
import org.jooq.Clause;
import org.jooq.Condition;
import org.jooq.Context;
@ -66,6 +68,19 @@ public abstract class CustomCondition extends AbstractCondition {
protected CustomCondition() {}
/**
* Create a {@link CustomCondition} from a lambda expression.
*/
@SuppressWarnings("serial")
public static final CustomCondition of(Consumer<? super Context<?>> consumer) {
return new CustomCondition() {
@Override
public void accept(Context<?> ctx) {
consumer.accept(ctx);
}
};
}
// -------------------------------------------------------------------------
// Implementation required
// -------------------------------------------------------------------------

View File

@ -39,6 +39,8 @@ package org.jooq.impl;
import static org.jooq.Clause.CUSTOM;
import java.util.function.Consumer;
import org.jooq.Clause;
import org.jooq.Condition;
import org.jooq.Context;
@ -75,6 +77,26 @@ public abstract class CustomField<T> extends AbstractField<T> {
super(name, type);
}
/**
* Create a {@link CustomField} from a lambda expression.
*/
public static final <T> CustomField<T> of(String name, DataType<T> type, Consumer<? super Context<?>> consumer) {
return of(DSL.name(name), type, consumer);
}
/**
* Create a {@link CustomField} from a lambda expression.
*/
@SuppressWarnings("serial")
public static final <T> CustomField<T> of(Name name, DataType<T> type, Consumer<? super Context<?>> consumer) {
return new CustomField<T>(name, type) {
@Override
public void accept(Context<?> ctx) {
consumer.accept(ctx);
}
};
}
// -------------------------------------------------------------------------
// Implementation required
// -------------------------------------------------------------------------

View File

@ -39,6 +39,8 @@ package org.jooq.impl;
import static org.jooq.Clause.CUSTOM;
import java.util.function.Consumer;
import org.jooq.Clause;
import org.jooq.Condition;
import org.jooq.Context;
@ -79,6 +81,19 @@ public abstract class CustomQueryPart extends AbstractQueryPart {
protected CustomQueryPart() {
}
/**
* Create a {@link CustomQueryPart} from a lambda expression.
*/
@SuppressWarnings("serial")
public static final CustomQueryPart of(Consumer<? super Context<?>> consumer) {
return new CustomQueryPart() {
@Override
public void accept(Context<?> ctx) {
consumer.accept(ctx);
}
};
}
// -------------------------------------------------------------------------
// Implementation required
// -------------------------------------------------------------------------

View File

@ -157,18 +157,15 @@ implements JSONObjectAggNullStep<J> {
}
final Field<?> value1 = value;
final Field<String> listagg = DSL.field("{0}", String.class, new CustomQueryPart() {
@Override
public void accept(Context<?> c) {
c.visit(groupConcat(DSL.concat(
inline('"'),
DSL.replace(entry.key(), inline('"'), inline("\\\"")),
inline("\":"),
nullType == ABSENT_ON_NULL ? value1 : DSL.coalesce(value1, inline("null"))
)));
acceptOverClause(c);
}
});
final Field<String> listagg = DSL.field("{0}", String.class, CustomQueryPart.of(c -> {
c.visit(groupConcat(DSL.concat(
inline('"'),
DSL.replace(entry.key(), inline('"'), inline("\\\"")),
inline("\":"),
nullType == ABSENT_ON_NULL ? value1 : DSL.coalesce(value1, inline("null"))
)));
acceptOverClause(c);
}));
ctx.sql('(').visit(DSL.concat(inline('{'), listagg, inline('}'))).sql(')');
}

View File

@ -73,51 +73,39 @@ final class Product extends AbstractAggregateFunction<BigDecimal> {
final Field<Integer> f = (Field) DSL.field("{0}", arguments.get(0).getDataType(), arguments.get(0));
final Field<Integer> negatives = DSL.when(f.lt(zero()), inline(-1));
@SuppressWarnings("serial")
Field<BigDecimal> negativesSum = new CustomField<BigDecimal>("sum", NUMERIC) {
@Override
public void accept(Context<?> c) {
c.visit(distinct
? DSL.sumDistinct(negatives)
: DSL.sum(negatives));
Field<BigDecimal> negativesSum = CustomField.of("sum", NUMERIC, c -> {
c.visit(distinct
? DSL.sumDistinct(negatives)
: DSL.sum(negatives));
acceptFilterClause(c);
acceptOverClause(c);
}
};
acceptFilterClause(c);
acceptOverClause(c);
});
@SuppressWarnings("serial")
Field<BigDecimal> zerosSum = new CustomField<BigDecimal>("sum", NUMERIC) {
@Override
public void accept(Context<?> c) {
c.visit(DSL.sum(choose(f).when(zero(), one())));
Field<BigDecimal> zerosSum = CustomField.of("sum", NUMERIC, c -> {
c.visit(DSL.sum(choose(f).when(zero(), one())));
acceptFilterClause(c);
acceptOverClause(c);
}
};
acceptFilterClause(c);
acceptOverClause(c);
});
@SuppressWarnings("serial")
Field<BigDecimal> logarithmsSum = new CustomField<BigDecimal>("sum", NUMERIC) {
@Override
public void accept(Context<?> c) {
Field<Integer> abs = DSL.abs(DSL.nullif(f, zero()));
Field<BigDecimal> ln =
Field<BigDecimal> logarithmsSum = CustomField.of("sum", NUMERIC, c -> {
Field<Integer> abs = DSL.abs(DSL.nullif(f, zero()));
Field<BigDecimal> ln =
DSL.ln(abs);
DSL.ln(abs);
c.visit(distinct
? DSL.sumDistinct(ln)
: DSL.sum(ln));
c.visit(distinct
? DSL.sumDistinct(ln)
: DSL.sum(ln));
acceptFilterClause(c);
acceptOverClause(c);
}
};
acceptFilterClause(c);
acceptOverClause(c);
});
ctx.visit(imul(
when(zerosSum.gt(inline(BigDecimal.ZERO)), zero())

View File

@ -1595,46 +1595,42 @@ final class SelectQueryImpl<R extends Record> extends AbstractResultQuery<R> imp
(Field<?>) null
);
alternativeFields[alternativeFields.length - 1] =
new CustomField<Integer>("rn", SQLDataType.INTEGER) {
@Override
public void accept(Context<?> c) {
boolean wrapQueryExpressionBodyInDerivedTable = wrapQueryExpressionBodyInDerivedTable(c);
alternativeFields[alternativeFields.length - 1] = CustomField.of("rn", SQLDataType.INTEGER, c -> {
boolean wrapQueryExpressionBodyInDerivedTable = wrapQueryExpressionBodyInDerivedTable(c);
// [#3575] Ensure that no column aliases from the surrounding SELECT clause
// are referenced from the below ranking functions' ORDER BY clause.
c.data(DATA_UNALIAS_ALIASED_EXPRESSIONS, !wrapQueryExpressionBodyInDerivedTable);
// [#3575] Ensure that no column aliases from the surrounding SELECT clause
// are referenced from the below ranking functions' ORDER BY clause.
c.data(DATA_UNALIAS_ALIASED_EXPRESSIONS, !wrapQueryExpressionBodyInDerivedTable);
boolean q = c.qualify();
boolean q = c.qualify();
c.data(DATA_OVERRIDE_ALIASES_IN_ORDER_BY, new Object[] { originalFields, alternativeFields });
if (wrapQueryExpressionBodyInDerivedTable)
c.qualify(false);
c.data(DATA_OVERRIDE_ALIASES_IN_ORDER_BY, new Object[] { originalFields, alternativeFields });
if (wrapQueryExpressionBodyInDerivedTable)
c.qualify(false);
// [#2580] FETCH NEXT n ROWS ONLY emulation:
// -----------------------------------------
// When DISTINCT is applied, we mustn't use ROW_NUMBER() OVER(),
// which changes the DISTINCT semantics. Instead, use DENSE_RANK() OVER(),
// ordering by the SELECT's ORDER BY clause AND all the expressions from
// the projection
//
// [#6197] FETCH NEXT n ROWS WITH TIES emulation:
// ----------------------------------------------
// DISTINCT seems irrelevant here (to be proven)
// [#2580] FETCH NEXT n ROWS ONLY emulation:
// -----------------------------------------
// When DISTINCT is applied, we mustn't use ROW_NUMBER() OVER(),
// which changes the DISTINCT semantics. Instead, use DENSE_RANK() OVER(),
// ordering by the SELECT's ORDER BY clause AND all the expressions from
// the projection
//
// [#6197] FETCH NEXT n ROWS WITH TIES emulation:
// ----------------------------------------------
// DISTINCT seems irrelevant here (to be proven)
c.visit(getLimit().withTies()
? DSL.rank().over(orderBy(getNonEmptyOrderBy(c.configuration())))
: distinct
? DSL.denseRank().over(orderBy(getNonEmptyOrderByForDistinct(c.configuration())))
: DSL.rowNumber().over(orderBy(getNonEmptyOrderBy(c.configuration())))
);
c.visit(getLimit().withTies()
? DSL.rank().over(orderBy(getNonEmptyOrderBy(c.configuration())))
: distinct
? DSL.denseRank().over(orderBy(getNonEmptyOrderByForDistinct(c.configuration())))
: DSL.rowNumber().over(orderBy(getNonEmptyOrderBy(c.configuration())))
);
c.data().remove(DATA_UNALIAS_ALIASED_EXPRESSIONS);
c.data().remove(DATA_OVERRIDE_ALIASES_IN_ORDER_BY);
if (wrapQueryExpressionBodyInDerivedTable)
c.qualify(q);
}
}.as("rn");
c.data().remove(DATA_UNALIAS_ALIASED_EXPRESSIONS);
c.data().remove(DATA_OVERRIDE_ALIASES_IN_ORDER_BY);
if (wrapQueryExpressionBodyInDerivedTable)
c.qualify(q);
}).as("rn");
// v1 as ID, v2 as ID, v3 as TITLE
final Field<?>[] unaliasedFields = Tools.unaliasedFields(originalFields);

View File

@ -1892,13 +1892,8 @@ final class Tools {
return result;
}
static final <T> Field<T> inlined(final Field<T> field) {
return new CustomField<T>(field.getQualifiedName(), field.getDataType()) {
@Override
public void accept(Context<?> ctx) {
ctx.visit(field, INLINED);
}
};
static final <T> Field<T> inlined(Field<T> field) {
return CustomField.of(field.getQualifiedName(), field.getDataType(), c -> c.visit(field, INLINED));
}
static final IllegalArgumentException indexFail(Row row, Field<?> field) {