[jOOQ/jOOQ#12465] [jOOQ/jOOQ#12432] Extract more CompareConditions
Including: - IN - NOT_IN
This commit is contained in:
parent
2e061133ea
commit
b286fe1abc
@ -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]
|
||||
*
|
||||
|
||||
@ -806,6 +806,17 @@ extends
|
||||
@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>
|
||||
@ -1052,6 +1063,21 @@ extends
|
||||
@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.
|
||||
*
|
||||
@ -1428,7 +1454,7 @@ extends
|
||||
* 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] @> ARRAY[1, 2]
|
||||
* </pre></code>
|
||||
@ -1457,7 +1483,7 @@ extends
|
||||
* 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] @> ARRAY[1, 2]
|
||||
* </pre></code>
|
||||
@ -2415,19 +2441,6 @@ extends
|
||||
@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>
|
||||
@ -2520,23 +2533,6 @@ extends
|
||||
@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
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@ -95,7 +95,6 @@ import org.jooq.conf.SettingsTools;
|
||||
import org.jooq.conf.StatementType;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
@ -309,6 +308,12 @@ abstract class AbstractContext<C extends Context<C>> extends AbstractScope imple
|
||||
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) {
|
||||
|
||||
@ -438,6 +438,12 @@ abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T
|
||||
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) {
|
||||
@ -607,6 +613,12 @@ abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T
|
||||
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) {
|
||||
@ -1247,11 +1259,6 @@ abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T
|
||||
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) {
|
||||
@ -1282,11 +1289,6 @@ abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T
|
||||
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));
|
||||
@ -1487,9 +1489,20 @@ abstract class AbstractField<T> extends AbstractTypedNamed<T> implements Field<T
|
||||
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
|
||||
|
||||
@ -73,8 +73,6 @@ final class ArraySelect<T> extends AbstractField<T[]> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
case H2: {
|
||||
Table<?> t = select.asTable("t", "c");
|
||||
Field<?> c = t.field("c");
|
||||
@ -86,8 +84,7 @@ final class ArraySelect<T> extends AbstractField<T[]> {
|
||||
}
|
||||
|
||||
default:
|
||||
ctx.visit(K_ARRAY);
|
||||
visitSubquery(ctx, select);
|
||||
ctx.visit(K_ARRAY).visitSubquery(select);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -38,81 +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 {
|
||||
|
||||
|
||||
|
||||
@ -139,15 +72,4 @@ final class CompareCondition extends AbstractCondition {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public final Clause[] clauses(Context<?> ctx) {
|
||||
return CLAUSES;
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ extends
|
||||
|
||||
|
||||
|
||||
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
|
||||
@ -113,6 +113,7 @@ extends
|
||||
Context<?> ctx,
|
||||
AbstractCondition condition,
|
||||
Field<T> arg1,
|
||||
org.jooq.Comparator op,
|
||||
Field<T> arg2,
|
||||
BiFunction<RowN, Select<?>, Condition> compareRowSubquery,
|
||||
BiFunction<RowN, RowN, Condition> compareRowRow,
|
||||
@ -125,6 +126,13 @@ extends
|
||||
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)))
|
||||
|
||||
@ -95,7 +95,7 @@ extends
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
@ -95,7 +95,7 @@ extends
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
128
jOOQ/src/main/java/org/jooq/impl/In.java
Normal file
128
jOOQ/src/main/java/org/jooq/impl/In.java
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.DSL.*;
|
||||
import static org.jooq.impl.Internal.*;
|
||||
import static org.jooq.impl.Keywords.*;
|
||||
import static org.jooq.impl.Names.*;
|
||||
import static org.jooq.impl.SQLDataType.*;
|
||||
import static org.jooq.impl.Tools.*;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.*;
|
||||
import static org.jooq.impl.Tools.DataExtendedKey.*;
|
||||
import static org.jooq.impl.Tools.DataKey.*;
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import org.jooq.*;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.conf.*;
|
||||
import org.jooq.impl.*;
|
||||
import org.jooq.tools.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
|
||||
/**
|
||||
* The <code>IN</code> statement.
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
|
||||
final class In<T>
|
||||
extends
|
||||
AbstractCondition
|
||||
{
|
||||
|
||||
final Field<T> arg1;
|
||||
final Select<? extends Record1<T>> arg2;
|
||||
|
||||
In(
|
||||
Field<T> arg1,
|
||||
Select<? extends Record1<T>> arg2
|
||||
) {
|
||||
|
||||
this.arg1 = nullSafeNotNull(arg1, (DataType) OTHER);
|
||||
this.arg2 = arg2;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XXX: QueryPart API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ScalarSubquery<T> f = new ScalarSubquery<>(arg2, arg1.getDataType());
|
||||
Eq.acceptCompareCondition(ctx, this, arg1, org.jooq.Comparator.IN, f, RowN::eq, RowN::eq, c -> c.visit(arg1).sql(' ').visit(K_IN).sql(' ').visit(f));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// The Object API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that instanceof In) {
|
||||
return
|
||||
StringUtils.equals(arg1, ((In) that).arg1) &&
|
||||
StringUtils.equals(arg2, ((In) that).arg2)
|
||||
;
|
||||
}
|
||||
else
|
||||
return super.equals(that);
|
||||
}
|
||||
}
|
||||
@ -95,7 +95,7 @@ extends
|
||||
|
||||
|
||||
|
||||
Eq.acceptCompareCondition(ctx, this, arg1, arg2, RowN::le, RowN::le, c -> c.visit(arg1).sql(" <= ").visit(arg2));
|
||||
Eq.acceptCompareCondition(ctx, this, arg1, org.jooq.Comparator.LESS_OR_EQUAL, arg2, RowN::le, RowN::le, c -> c.visit(arg1).sql(" <= ").visit(arg2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -46,12 +46,6 @@ import static org.jooq.impl.Tools.*;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.*;
|
||||
import static org.jooq.impl.Tools.DataExtendedKey.*;
|
||||
import static org.jooq.impl.Tools.DataKey.*;
|
||||
import static org.jooq.Comparator.LIKE;
|
||||
import static org.jooq.Comparator.LIKE_IGNORE_CASE;
|
||||
import static org.jooq.Comparator.NOT_LIKE;
|
||||
import static org.jooq.Comparator.NOT_LIKE_IGNORE_CASE;
|
||||
import static org.jooq.Comparator.NOT_SIMILAR_TO;
|
||||
import static org.jooq.Comparator.SIMILAR_TO;
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import org.jooq.*;
|
||||
@ -165,7 +159,7 @@ implements
|
||||
|
||||
// [#1159] [#1725] Some dialects cannot auto-convert the LHS operand to a
|
||||
// VARCHAR when applying a LIKE predicate
|
||||
if ((op == LIKE || op == NOT_LIKE || op == SIMILAR_TO || op == NOT_SIMILAR_TO)
|
||||
if ((op == org.jooq.Comparator.LIKE || op == org.jooq.Comparator.NOT_LIKE || op == org.jooq.Comparator.SIMILAR_TO || op == org.jooq.Comparator.NOT_SIMILAR_TO)
|
||||
&& arg1.getType() != String.class
|
||||
&& REQUIRES_CAST_ON_LIKE.contains(ctx.dialect())) {
|
||||
arg1 = castIfNeeded(arg1, String.class);
|
||||
@ -173,10 +167,10 @@ implements
|
||||
|
||||
// [#1423] [#9889] PostgreSQL and H2 support ILIKE natively. Other dialects
|
||||
// need to emulate this as LOWER(lhs) LIKE LOWER(rhs)
|
||||
else if ((op == LIKE_IGNORE_CASE || op == NOT_LIKE_IGNORE_CASE) && NO_SUPPORT_ILIKE.contains(ctx.dialect())) {
|
||||
else if ((op == org.jooq.Comparator.LIKE_IGNORE_CASE || op == org.jooq.Comparator.NOT_LIKE_IGNORE_CASE) && NO_SUPPORT_ILIKE.contains(ctx.dialect())) {
|
||||
arg1 = DSL.lower((Field) arg1);
|
||||
arg2 = DSL.lower((Field) arg2);
|
||||
op = (op == LIKE_IGNORE_CASE ? LIKE : NOT_LIKE);
|
||||
op = (op == org.jooq.Comparator.LIKE_IGNORE_CASE ? org.jooq.Comparator.LIKE : org.jooq.Comparator.NOT_LIKE);
|
||||
}
|
||||
|
||||
boolean castRhs = castRhs(ctx, arg2);
|
||||
|
||||
@ -95,7 +95,7 @@ extends
|
||||
|
||||
|
||||
|
||||
Eq.acceptCompareCondition(ctx, this, arg1, arg2, RowN::lt, RowN::lt, c -> c.visit(arg1).sql(" < ").visit(arg2));
|
||||
Eq.acceptCompareCondition(ctx, this, arg1, org.jooq.Comparator.LESS, arg2, RowN::lt, RowN::lt, c -> c.visit(arg1).sql(" < ").visit(arg2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -95,7 +95,7 @@ extends
|
||||
|
||||
|
||||
|
||||
Eq.acceptCompareCondition(ctx, this, arg1, arg2, RowN::ne, RowN::ne, c -> c.visit(arg1).sql(" <> ").visit(arg2));
|
||||
Eq.acceptCompareCondition(ctx, this, arg1, org.jooq.Comparator.NOT_EQUALS, arg2, RowN::ne, RowN::ne, c -> c.visit(arg1).sql(" <> ").visit(arg2));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
128
jOOQ/src/main/java/org/jooq/impl/NotIn.java
Normal file
128
jOOQ/src/main/java/org/jooq/impl/NotIn.java
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Other licenses:
|
||||
* -----------------------------------------------------------------------------
|
||||
* Commercial licenses for this work are available. These replace the above
|
||||
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
|
||||
* database integrations.
|
||||
*
|
||||
* For more information, please visit: http://www.jooq.org/licenses
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.DSL.*;
|
||||
import static org.jooq.impl.Internal.*;
|
||||
import static org.jooq.impl.Keywords.*;
|
||||
import static org.jooq.impl.Names.*;
|
||||
import static org.jooq.impl.SQLDataType.*;
|
||||
import static org.jooq.impl.Tools.*;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.*;
|
||||
import static org.jooq.impl.Tools.DataExtendedKey.*;
|
||||
import static org.jooq.impl.Tools.DataKey.*;
|
||||
import static org.jooq.SQLDialect.*;
|
||||
|
||||
import org.jooq.*;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.conf.*;
|
||||
import org.jooq.impl.*;
|
||||
import org.jooq.tools.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
|
||||
/**
|
||||
* The <code>NOT IN</code> statement.
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
|
||||
final class NotIn<T>
|
||||
extends
|
||||
AbstractCondition
|
||||
{
|
||||
|
||||
final Field<T> arg1;
|
||||
final Select<? extends Record1<T>> arg2;
|
||||
|
||||
NotIn(
|
||||
Field<T> arg1,
|
||||
Select<? extends Record1<T>> arg2
|
||||
) {
|
||||
|
||||
this.arg1 = nullSafeNotNull(arg1, (DataType) OTHER);
|
||||
this.arg2 = arg2;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XXX: QueryPart API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ScalarSubquery<T> f = new ScalarSubquery<>(arg2, arg1.getDataType());
|
||||
Eq.acceptCompareCondition(ctx, this, arg1, org.jooq.Comparator.NOT_IN, f, RowN::eq, RowN::eq, c -> c.visit(arg1).sql(' ').visit(K_NOT_IN).sql(' ').visit(f));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// The Object API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (that instanceof NotIn) {
|
||||
return
|
||||
StringUtils.equals(arg1, ((NotIn) that).arg1) &&
|
||||
StringUtils.equals(arg2, ((NotIn) that).arg2)
|
||||
;
|
||||
}
|
||||
else
|
||||
return super.equals(that);
|
||||
}
|
||||
}
|
||||
@ -50,6 +50,7 @@ import java.util.Set;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Select;
|
||||
|
||||
@ -77,8 +78,6 @@ final class ScalarSubquery<T> extends AbstractField<T> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// HSQLDB allows for using WITH inside of IN, see: https://sourceforge.net/p/hsqldb/bugs/1617/
|
||||
// We'll still emulate CTE in scalar subqueries with a derived tables in all cases.
|
||||
if (q != null && q.with != null && NO_SUPPORT_WITH_IN_SCALAR_SUBQUERY.contains(ctx.dialect()))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user