From 292605a12fe208b29ea68cf7f8600c8594285d05 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Tue, 24 Sep 2019 16:09:51 +0200 Subject: [PATCH] [jOOQ/jOOQ#9263] Support Field with non-standard Converter When a Boolean-typed field's `Converter` is not the default, then `DSL#condition(Field)` will now render the SQL by comparing the field to `true` (as converted by the field's converter). The same applies to `DSL#not(Field)`. --- jOOQ/src/main/java/org/jooq/Converters.java | 34 +-------- .../java/org/jooq/impl/ConditionAsField.java | 14 +++- .../java/org/jooq/impl/FieldCondition.java | 4 +- .../java/org/jooq/impl/IdentityConverter.java | 75 +++++++++++++++++++ .../src/main/java/org/jooq/impl/NotField.java | 7 +- jOOQ/src/main/java/org/jooq/impl/Tools.java | 7 ++ 6 files changed, 101 insertions(+), 40 deletions(-) create mode 100644 jOOQ/src/main/java/org/jooq/impl/IdentityConverter.java diff --git a/jOOQ/src/main/java/org/jooq/Converters.java b/jOOQ/src/main/java/org/jooq/Converters.java index 65727d9452..c0c288ac2d 100644 --- a/jOOQ/src/main/java/org/jooq/Converters.java +++ b/jOOQ/src/main/java/org/jooq/Converters.java @@ -37,6 +37,7 @@ */ package org.jooq; +import org.jooq.impl.IdentityConverter; import org.jooq.impl.SQLDataType; /** @@ -61,38 +62,7 @@ public class Converters implements Converter { * Create an identity converter. */ public static Converter identity(final Class type) { - return new Converter() { - - /** - * Generated UID - */ - private static final long serialVersionUID = -8331976721627671263L; - - @Override - public final T from(T t) { - return t; - } - - @Override - public final T to(T t) { - return t; - } - - @Override - public final Class fromType() { - return type; - } - - @Override - public final Class toType() { - return type; - } - - @Override - public String toString() { - return "IdentityConverter [ " + fromType().getName() + " ]"; - } - }; + return new IdentityConverter(type); } /** diff --git a/jOOQ/src/main/java/org/jooq/impl/ConditionAsField.java b/jOOQ/src/main/java/org/jooq/impl/ConditionAsField.java index 703e91f2c5..4190e79b8f 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ConditionAsField.java +++ b/jOOQ/src/main/java/org/jooq/impl/ConditionAsField.java @@ -39,9 +39,11 @@ package org.jooq.impl; import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.not; +import static org.jooq.impl.SQLDataType.BOOLEAN; import org.jooq.Condition; import org.jooq.Context; +import org.jooq.DataType; /** * @author Lukas Eder @@ -55,7 +57,11 @@ final class ConditionAsField extends AbstractField { final Condition condition; ConditionAsField(Condition condition) { - super(DSL.name(condition.toString()), SQLDataType.BOOLEAN); + this(condition, BOOLEAN); + } + + ConditionAsField(Condition condition, DataType dataType) { + super(DSL.name(condition.toString()), dataType); this.condition = condition; } @@ -80,9 +86,9 @@ final class ConditionAsField extends AbstractField { case FIREBIRD: // [#3206] Correct implementation of three-valued logic is important here - ctx.visit(DSL.when(condition, inline(true)) - .when(not(condition), inline(false)) - .otherwise(inline((Boolean) null))); + ctx.visit(DSL.when(condition, inline(true, getDataType())) + .when(not(condition), inline(false, getDataType())) + .otherwise(inline((Boolean) null, getDataType()))); break; // These databases can inline predicates in column expression contexts diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldCondition.java b/jOOQ/src/main/java/org/jooq/impl/FieldCondition.java index b94fe07ea1..a79bef0e83 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldCondition.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldCondition.java @@ -78,7 +78,7 @@ final class FieldCondition extends AbstractCondition { - ctx.sql('(').visit(field).sql(" = ").visit(inline(true)).sql(')'); + ctx.visit(field.eq(inline(true, field.getDataType()))); break; @@ -97,7 +97,7 @@ final class FieldCondition extends AbstractCondition { case POSTGRES: case SQLITE: default: - ctx.visit(field); + ctx.visit(Tools.hasDefaultConverter(field) ? field : field.eq(inline(true, field.getDataType()))); break; } } diff --git a/jOOQ/src/main/java/org/jooq/impl/IdentityConverter.java b/jOOQ/src/main/java/org/jooq/impl/IdentityConverter.java new file mode 100644 index 0000000000..f863186210 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/IdentityConverter.java @@ -0,0 +1,75 @@ +/* + * 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 org.jooq.Converter; + +public final class IdentityConverter implements Converter { + private static final long serialVersionUID = -8331976721627671263L; + + private final Class type; + + public IdentityConverter(Class type) { + this.type = type; + } + + @Override + public final T from(T t) { + return t; + } + + @Override + public final T to(T t) { + return t; + } + + @Override + public final Class fromType() { + return type; + } + + @Override + public final Class toType() { + return type; + } + + @Override + public String toString() { + return "IdentityConverter [ " + fromType().getName() + " ]"; + } +} \ No newline at end of file diff --git a/jOOQ/src/main/java/org/jooq/impl/NotField.java b/jOOQ/src/main/java/org/jooq/impl/NotField.java index eda3a14999..ca2e9a98e2 100644 --- a/jOOQ/src/main/java/org/jooq/impl/NotField.java +++ b/jOOQ/src/main/java/org/jooq/impl/NotField.java @@ -78,7 +78,7 @@ final class NotField extends AbstractField { - ctx.visit(DSL.field(not(condition(field)))); + ctx.visit(new ConditionAsField(not(condition(field)), field.getDataType())); break; @@ -96,7 +96,10 @@ final class NotField extends AbstractField { case POSTGRES: case SQLITE: default: - ctx.visit(K_NOT).sql('(').visit(field).sql(')'); + ctx.visit(K_NOT) + .sql('(') + .visit(Tools.hasDefaultConverter(field) ? field : condition(field)) + .sql(')'); break; } } diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java index 6715467006..6285c18eb8 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Tools.java +++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java @@ -2976,6 +2976,13 @@ final class Tools { return field instanceof Param; } + /** + * Utility method to check whether a field uses a default {@link Converter} + */ + static final boolean hasDefaultConverter(Field field) { + return field.getConverter() instanceof IdentityConverter; + } + /** * Utility method to extract a value from a field */