[#2227] Field.in(T...) doesn't convert argument values to the Field's

type
This commit is contained in:
Lukas Eder 2013-02-17 19:07:56 +01:00
parent b631eedb23
commit 797b1b5e0f
5 changed files with 146 additions and 5 deletions

View File

@ -511,7 +511,7 @@ abstract class AbstractField<T> extends AbstractQueryPart implements Field<T> {
@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<T> extends AbstractQueryPart implements Field<T> {
return trueCondition();
}
else {
return notIn(Utils.fields(values).toArray(new Field<?>[0]));
return notIn(Utils.fields(values, this).toArray(new Field<?>[0]));
}
}

View File

@ -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;

View File

@ -340,7 +340,7 @@ implements
@Override
public final Table<Record> in(Object... values) {
return in(Utils.fields(values).toArray(new Field<?>[0]));
return in(Utils.fields(values, on).toArray(new Field<?>[0]));
}
@Override

View File

@ -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<Field<?>> fields(Object[] values, Field<?> field) {
List<Field<?>> result = new ArrayList<Field<?>>();
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<Field<?>> fields(Object[] values, Class<?> type) {
List<Field<?>> result = new ArrayList<Field<?>>();
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<Field<?>> fields(Object[] values, DataType<?> type) {
List<Field<?>> result = new ArrayList<Field<?>>();
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.
*

View File

@ -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++) {