From 797b1b5e0f683fb9d8db8a4ab7109135db33e833 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Sun, 17 Feb 2013 19:07:56 +0100 Subject: [PATCH] [#2227] Field.in(T...) doesn't convert argument values to the Field's type --- .../java/org/jooq/impl/AbstractField.java | 4 +- .../main/java/org/jooq/impl/MergeImpl.java | 4 +- jOOQ/src/main/java/org/jooq/impl/Pivot.java | 2 +- jOOQ/src/main/java/org/jooq/impl/Utils.java | 60 ++++++++++++++ .../test/java/org/jooq/test/DataTypeTest.java | 81 +++++++++++++++++++ 5 files changed, 146 insertions(+), 5 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java index 66e0719fdb..123c506a4b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractField.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractField.java @@ -511,7 +511,7 @@ abstract class AbstractField extends AbstractQueryPart implements Field { @Override public final Condition in(T... values) { - return in(Utils.fields(values).toArray(new Field[0])); + return in(Utils.fields(values, this).toArray(new Field[0])); } @Override @@ -546,7 +546,7 @@ abstract class AbstractField extends AbstractQueryPart implements Field { return trueCondition(); } else { - return notIn(Utils.fields(values).toArray(new Field[0])); + return notIn(Utils.fields(values, this).toArray(new Field[0])); } } diff --git a/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java b/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java index 5dbc77d3cc..3db8e17562 100644 --- a/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/MergeImpl.java @@ -518,11 +518,11 @@ implements // syntax, in case of which, the USING() was not added if (using == null) { h2Style = true; - getH2Values().addAll(Utils.fields(convert(values, getH2Fields().toArray(new Field[0])))); + getH2Values().addAll(Utils.fields(values, getH2Fields().toArray(new Field[0]))); } else { Field[] fields = notMatchedInsert.keySet().toArray(new Field[0]); - notMatchedInsert.putValues(Utils.fields(convert(values, fields))); + notMatchedInsert.putValues(Utils.fields(values, fields)); } return this; diff --git a/jOOQ/src/main/java/org/jooq/impl/Pivot.java b/jOOQ/src/main/java/org/jooq/impl/Pivot.java index 3aabc715f1..31ede03302 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Pivot.java +++ b/jOOQ/src/main/java/org/jooq/impl/Pivot.java @@ -340,7 +340,7 @@ implements @Override public final Table in(Object... values) { - return in(Utils.fields(values).toArray(new Field[0])); + return in(Utils.fields(values, on).toArray(new Field[0])); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/Utils.java b/jOOQ/src/main/java/org/jooq/impl/Utils.java index 10390063ce..7b0538b8d8 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Utils.java +++ b/jOOQ/src/main/java/org/jooq/impl/Utils.java @@ -501,6 +501,26 @@ final class Utils { return result; } + /** + * Be sure that a given set of objects are fields. + * + * @param values The argument objects + * @param field The field to take the bind value types from + * @return The argument objects themselves, if they are {@link Field}s, or a bind + * values created from the argument objects. + */ + static final List> fields(Object[] values, Field field) { + List> result = new ArrayList>(); + + if (values != null && field != null) { + for (int i = 0; i < values.length; i++) { + result.add(field(values[i], field)); + } + } + + return result; + } + /** * Be sure that a given set of objects are fields. * @@ -521,6 +541,26 @@ final class Utils { return result; } + /** + * Be sure that a given set of objects are fields. + * + * @param values The argument objects + * @param type The type to take the bind value types from + * @return The argument objects themselves, if they are {@link Field}s, or a bind + * values created from the argument objects. + */ + static final List> fields(Object[] values, Class type) { + List> result = new ArrayList>(); + + if (values != null && type != null) { + for (int i = 0; i < values.length; i++) { + result.add(field(values[i], type)); + } + } + + return result; + } + /** * Be sure that a given set of objects are fields. * @@ -541,6 +581,26 @@ final class Utils { return result; } + /** + * Be sure that a given set of objects are fields. + * + * @param values The argument objects + * @param type The type to take the bind value types from + * @return The argument objects themselves, if they are {@link Field}s, or a bind + * values created from the argument objects. + */ + static final List> fields(Object[] values, DataType type) { + List> result = new ArrayList>(); + + if (values != null && type != null) { + for (int i = 0; i < values.length; i++) { + result.add(field(values[i], type)); + } + } + + return result; + } + /** * Be sure that a given set of objects are fields. * diff --git a/jOOQ/src/test/java/org/jooq/test/DataTypeTest.java b/jOOQ/src/test/java/org/jooq/test/DataTypeTest.java index d380a49ed7..43e6dbf882 100644 --- a/jOOQ/src/test/java/org/jooq/test/DataTypeTest.java +++ b/jOOQ/src/test/java/org/jooq/test/DataTypeTest.java @@ -152,6 +152,87 @@ public class DataTypeTest extends AbstractTest { } } + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void testInPredicateTypeCoercion() throws Exception { + // [#2227] This test checks whether automatic type coercion works well for + // IN predicates + + Field integer = Table1.FIELD_ID1; + Field string = Table1.FIELD_NAME1; + Field object = fieldByName("ANY"); + + // Check if a correct type was coerced correctly + // --------------------------------------------- + { + Condition int_int = integer.in(1); + assertEquals("\"TABLE1\".\"ID1\" in (1)", r_refI().render(int_int)); + context.checking(new Expectations() {{ + oneOf(statement).setInt(1, 1); + }}); + + assertEquals(2, b_ref().bind(int_int).peekIndex()); + context.assertIsSatisfied(); + } + + { + Condition string_string = string.in("1"); + assertEquals("\"TABLE1\".\"NAME1\" in ('1')", r_refI().render(string_string)); + context.checking(new Expectations() {{ + oneOf(statement).setString(1, "1"); + }}); + + assertEquals(2, b_ref().bind(string_string).peekIndex()); + context.assertIsSatisfied(); + } + + // Check if a convertible type was coerced correctly + // ------------------------------------------------- + { + Condition int_string = integer.in("1"); + assertEquals("\"TABLE1\".\"ID1\" in (1)", r_refI().render(int_string)); + context.checking(new Expectations() {{ + oneOf(statement).setInt(1, 1); + }}); + + assertEquals(2, b_ref().bind(int_string).peekIndex()); + context.assertIsSatisfied(); + + Condition string_int = string.in(1); + assertEquals("\"TABLE1\".\"NAME1\" in ('1')", r_refI().render(string_int)); + context.checking(new Expectations() {{ + oneOf(statement).setString(1, "1"); + }}); + + assertEquals(2, b_ref().bind(string_int).peekIndex()); + context.assertIsSatisfied(); + } + + // Check if ... + // ------------ + { + Condition object_int = object.in(1); + assertEquals("\"ANY\" in (1)", r_refI().render(object_int)); + context.checking(new Expectations() {{ + oneOf(statement).setInt(1, 1); + }}); + + assertEquals(2, b_ref().bind(object_int).peekIndex()); + context.assertIsSatisfied(); + } + + { + Condition object_string = object.in("1"); + assertEquals("\"ANY\" in ('1')", r_refI().render(object_string)); + context.checking(new Expectations() {{ + oneOf(statement).setString(1, "1"); + }}); + + assertEquals(2, b_ref().bind(object_string).peekIndex()); + context.assertIsSatisfied(); + } + } + @Test public void testYearToMonth() { for (int i = 0; i <= 5; i++) {