Skip to content

Commit

Permalink
[jOOQ#12465] [jOOQ#12432] Extract more CompareConditions
Browse files Browse the repository at this point in the history
Including:
- IN
- NOT_IN
  • Loading branch information
lukaseder committed Sep 24, 2021
1 parent 2e06113 commit b286fe1
Show file tree
Hide file tree
Showing 16 changed files with 350 additions and 145 deletions.
15 changes: 15 additions & 0 deletions jOOQ/src/main/java/org/jooq/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,21 @@ public interface Context<C extends Context<C>> extends Scope {
@NotNull
C visit(QueryPart part) throws DataAccessException;

/**
* Visit a <code>QueryPart</code> as a subquery in the current
* <code>Context</code>.
* <p>
* This method is called by certain <code>QueryPart</code> implementations
* to recursively visit component <code>QueryPart</code>s.
*
* @param part The component <code>QueryPart</code>
* @throws DataAccessException If something went wrong while visiting the
* component <code>QueryPart</code>, e.g. when binding a
* variable
*/
@NotNull
C visitSubquery(QueryPart part) throws DataAccessException;

/**
* TODO [#2667]
*
Expand Down
60 changes: 28 additions & 32 deletions jOOQ/src/main/java/org/jooq/Field.java
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,17 @@ <U> Field<U> convert(
@Support
Condition gt(Field<T> arg2);

/**
* The <code>IN</code> operator.
* <p>
* The subquery must return exactly one field. This is not checked
* by jOOQ and will result in syntax errors in the database, if not used
* correctly.
*/
@NotNull
@Support
Condition in(Select<? extends Record1<T>> arg2);

/**
* The <code>IS_DISTINCT_FROM</code> operator.
* <p>
Expand Down Expand Up @@ -1052,6 +1063,21 @@ <U> Field<U> convert(
@Support
Condition notEqual(Field<T> arg2);

/**
* The <code>NOT_IN</code> operator.
* <p>
* The subquery must return exactly one field. This is not checked
* by jOOQ and will result in syntax errors in the database, if not used
* correctly.
* <p>
* If any of the passed values is <code>NULL</code>, then the
* condition will be <code>NULL</code> (or <code>false</code>, depending on
* the dialect) as well. This is standard SQL behaviour.
*/
@NotNull
@Support
Condition notIn(Select<? extends Record1<T>> arg2);

/**
* The <code>NOT_LIKE</code> operator.
*
Expand Down Expand Up @@ -1428,7 +1454,7 @@ <U> Field<U> convert(
* also to express the "ARRAY contains" operator. For example: <code><pre>
* // Use this expression
* val(new Integer[] { 1, 2, 3 }).contains(new Integer[] { 1, 2 })
*
*
* // ... to render this SQL
* ARRAY[1, 2, 3] @&gt; ARRAY[1, 2]
* </pre></code>
Expand Down Expand Up @@ -1457,7 +1483,7 @@ <U> Field<U> convert(
* also to express the "ARRAY contains" operator. For example: <code><pre>
* // Use this expression
* val(new Integer[] { 1, 2, 3 }).contains(new Integer[] { 1, 2 })
*
*
* // ... to render this SQL
* ARRAY[1, 2, 3] @&gt; ARRAY[1, 2]
* </pre></code>
Expand Down Expand Up @@ -2415,19 +2441,6 @@ <U> Field<U> convert(
@Support
Condition in(Field<?>... values);

/**
* Create a condition to check this field against a subquery.
* <p>
* Note that the subquery must return exactly one field. This is not checked
* by jOOQ and will result in syntax errors in the database, if not used
* correctly.
* <p>
* SQL: <code>this in (select...)</code>
*/
@NotNull
@Support
Condition in(Select<? extends Record1<T>> query);

/**
* Create a condition to check this field against several values.
* <p>
Expand Down Expand Up @@ -2520,23 +2533,6 @@ <U> Field<U> convert(
@Support
Condition notIn(Field<?>... values);

/**
* Create a condition to check this field against a subquery.
* <p>
* Note that the subquery must return exactly one field. This is not checked
* by jOOQ and will result in syntax errors in the database, if not used
* correctly.
* <p>
* Note that if any of the passed values is <code>NULL</code>, then the
* condition will be <code>NULL</code> (or <code>false</code>, depending on
* the dialect) as well. This is standard SQL behaviour.
* <p>
* SQL: <code>this not in (select...)</code>
*/
@NotNull
@Support
Condition notIn(Select<? extends Record1<T>> query);

// ------------------------------------------------------------------------
// BETWEEN predicates
// ------------------------------------------------------------------------
Expand Down
7 changes: 6 additions & 1 deletion jOOQ/src/main/java/org/jooq/impl/AbstractContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@
import org.jooq.conf.StatementType;
import org.jooq.tools.StringUtils;

import org.jetbrains.annotations.NotNull;

/**
* @author Lukas Eder
Expand Down Expand Up @@ -309,6 +308,12 @@ else if (!castModeOverride && castMode() != CastMode.DEFAULT && !internal.genera
return (C) this;
}

@Override
public final C visitSubquery(QueryPart part) {
Tools.visitSubquery(this, part);
return (C) this;
}

protected abstract void visit0(QueryPartInternal internal);

private final C toggle(boolean b, BooleanSupplier get, BooleanConsumer set, Consumer<? super C> consumer) {
Expand Down
37 changes: 25 additions & 12 deletions jOOQ/src/main/java/org/jooq/impl/AbstractField.java
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,12 @@ public final Condition gt(Field<T> arg2) {
return new Gt(this, nullSafe(arg2, getDataType()));
}

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Condition in(Select<? extends Record1<T>> arg2) {
return new In(this, arg2);
}

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Condition isDistinctFrom(T arg2) {
Expand Down Expand Up @@ -607,6 +613,12 @@ public final Condition notEqual(Field<T> arg2) {
return ne(arg2);
}

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final Condition notIn(Select<? extends Record1<T>> arg2) {
return new NotIn(this, arg2);
}

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public final LikeEscapeStep notLike(String pattern) {
Expand Down Expand Up @@ -1247,11 +1259,6 @@ public final Condition in(Result<? extends Record1<T>> result) {
return in(result.getValues(0, getType()));
}

@Override
public final Condition in(Select<? extends Record1<T>> query) {
return compare(IN, query);
}

@SuppressWarnings("unchecked")
@Override
public final Condition notIn(T... values) {
Expand Down Expand Up @@ -1282,11 +1289,6 @@ public final Condition notIn(Result<? extends Record1<T>> result) {
return notIn(result.getValues(0, getType()));
}

@Override
public final Condition notIn(Select<? extends Record1<T>> query) {
return compare(NOT_IN, query);
}

@Override
public final Condition between(T minValue, T maxValue) {
return between(Tools.field(minValue, this), Tools.field(maxValue, this));
Expand Down Expand Up @@ -1487,9 +1489,20 @@ public final Condition compare(Comparator comparator, Field<T> field) {
case IS_NOT_DISTINCT_FROM:
return new IsNotDistinctFrom<>(this, nullSafe(field, getDataType()));

default:
return new CompareCondition(this, nullSafe(field, getDataType()), comparator);
case IN:
if (field instanceof ScalarSubquery)
return new In<>(this, (Select<? extends Record1<T>>) ((ScalarSubquery<?>) field).query);

break;

case NOT_IN:
if (field instanceof ScalarSubquery)
return new NotIn<>(this, (Select<? extends Record1<T>>) ((ScalarSubquery<?>) field).query);

break;
}

throw new IllegalArgumentException("Comparator not supported: " + comparator);
}

@Override
Expand Down
5 changes: 1 addition & 4 deletions jOOQ/src/main/java/org/jooq/impl/ArraySelect.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ public final void accept(Context<?> ctx) {





case H2: {
Table<?> t = select.asTable("t", "c");
Field<?> c = t.field("c");
Expand All @@ -86,8 +84,7 @@ public final void accept(Context<?> ctx) {
}

default:
ctx.visit(K_ARRAY);
visitSubquery(ctx, select);
ctx.visit(K_ARRAY).visitSubquery(select);

break;
}
Expand Down
80 changes: 1 addition & 79 deletions jOOQ/src/main/java/org/jooq/impl/CompareCondition.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,88 +38,14 @@

package org.jooq.impl;

import static java.lang.Boolean.TRUE;
import static org.jooq.Clause.CONDITION;
import static org.jooq.Clause.CONDITION_COMPARISON;
import static org.jooq.Comparator.IN;
import static org.jooq.Comparator.NOT_IN;
// ...
import static org.jooq.impl.DSL.asterisk;
import static org.jooq.impl.DSL.row;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.Tools.embeddedFields;
import static org.jooq.impl.Tools.nullSafe;
import static org.jooq.impl.Tools.nullableIf;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_MULTISET_CONDITION;
import static org.jooq.impl.Transformations.subqueryWithLimit;
import static org.jooq.impl.Transformations.transformInConditionSubqueryWithLimitToDerivedTable;

import org.jooq.Clause;
import org.jooq.Comparator;
import org.jooq.Context;
import org.jooq.Field;
// ...
import org.jooq.Select;

/**
* @author Lukas Eder
*/
final class CompareCondition extends AbstractCondition {

private static final Clause[] CLAUSES = { CONDITION, CONDITION_COMPARISON };

final Field<?> field1;
final Field<?> field2;
final Comparator comparator;

CompareCondition(Field<?> field1, Field<?> field2, Comparator comparator) {
this.field1 = nullableIf(comparator.supportsNulls(), nullSafe(field1, field2.getDataType()));
this.field2 = nullableIf(comparator.supportsNulls(), nullSafe(field2, field1.getDataType()));
this.comparator = comparator;
}

@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public final void accept(Context<?> ctx) {
boolean field1Embeddable = field1.getDataType().isEmbeddable();
SelectQueryImpl<?> s;

if (field1Embeddable && field2 instanceof ScalarSubquery)
ctx.visit(row(embeddedFields(field1)).compare(comparator, ((ScalarSubquery<?>) field2).query));
else if (field1Embeddable && field2.getDataType().isEmbeddable())
ctx.visit(row(embeddedFields(field1)).compare(comparator, embeddedFields(field2)));
else if ((comparator == IN || comparator == NOT_IN)
&& (s = subqueryWithLimit(field2)) != null
&& transformInConditionSubqueryWithLimitToDerivedTable(ctx.configuration())) {



}
else if (field1.getDataType().isMultiset()
&& field2.getDataType().isMultiset()
&& !TRUE.equals(ctx.data(DATA_MULTISET_CONDITION)))
ctx.data(DATA_MULTISET_CONDITION, true, c -> c.visit(this));
else
accept0(ctx);
}

private final void accept0(Context<?> ctx) {







ctx.visit(field1).sql(' ').visit(comparator.toKeyword()).sql(' ').visit(field2);
}







final class CompareCondition {



Expand All @@ -146,8 +72,4 @@ private final void accept0(Context<?> ctx) {



@Override
public final Clause[] clauses(Context<?> ctx) {
return CLAUSES;
}
}
10 changes: 9 additions & 1 deletion jOOQ/src/main/java/org/jooq/impl/Eq.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public final void accept(Context<?> ctx) {



Eq.acceptCompareCondition(ctx, this, arg1, arg2, RowN::eq, RowN::eq, c -> c.visit(arg1).sql(" = ").visit(arg2));
Eq.acceptCompareCondition(ctx, this, arg1, org.jooq.Comparator.EQUALS, arg2, RowN::eq, RowN::eq, c -> c.visit(arg1).sql(" = ").visit(arg2));
}

@Override
Expand All @@ -113,6 +113,7 @@ static final <T> void acceptCompareCondition(
Context<?> ctx,
AbstractCondition condition,
Field<T> arg1,
org.jooq.Comparator op,
Field<T> arg2,
BiFunction<RowN, Select<?>, Condition> compareRowSubquery,
BiFunction<RowN, RowN, Condition> compareRowRow,
Expand All @@ -125,6 +126,13 @@ static final <T> void acceptCompareCondition(
ctx.visit(compareRowSubquery.apply(row(embeddedFields(arg1)), ((ScalarSubquery<?>) arg2).query));
else if (field1Embeddable && arg2.getDataType().isEmbeddable())
ctx.visit(compareRowRow.apply(row(embeddedFields(arg1)), row(embeddedFields(arg2))));
else if ((op == org.jooq.Comparator.IN || op == org.jooq.Comparator.NOT_IN)
&& (s = Transformations.subqueryWithLimit(arg2)) != null
&& Transformations.transformInConditionSubqueryWithLimitToDerivedTable(ctx.configuration())) {



}
else if (arg1.getDataType().isMultiset()
&& arg2.getDataType().isMultiset()
&& !Boolean.TRUE.equals(ctx.data(DATA_MULTISET_CONDITION)))
Expand Down
2 changes: 1 addition & 1 deletion jOOQ/src/main/java/org/jooq/impl/Ge.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public final void accept(Context<?> ctx) {



Eq.acceptCompareCondition(ctx, this, arg1, arg2, RowN::ge, RowN::ge, c -> c.visit(arg1).sql(" >= ").visit(arg2));
Eq.acceptCompareCondition(ctx, this, arg1, org.jooq.Comparator.GREATER_OR_EQUAL, arg2, RowN::ge, RowN::ge, c -> c.visit(arg1).sql(" >= ").visit(arg2));
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion jOOQ/src/main/java/org/jooq/impl/Gt.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public final void accept(Context<?> ctx) {



Eq.acceptCompareCondition(ctx, this, arg1, arg2, RowN::gt, RowN::gt, c -> c.visit(arg1).sql(" > ").visit(arg2));
Eq.acceptCompareCondition(ctx, this, arg1, org.jooq.Comparator.GREATER, arg2, RowN::gt, RowN::gt, c -> c.visit(arg1).sql(" > ").visit(arg2));
}

@Override
Expand Down
Loading

0 comments on commit b286fe1

Please sign in to comment.