[jOOQ/jOOQ#11254] Add lambda constructor in CustomField, CustomCondition, CustomQueryPart
This commit is contained in:
parent
7876d6adce
commit
7606c434d4
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -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
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -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
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -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(')');
|
||||
}
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user