diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java b/sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java index 649d27a1f3a..486c23f67c9 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/run/SqlResults.java @@ -41,6 +41,7 @@ import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -70,7 +71,7 @@ public class SqlResults } else if (value instanceof Boolean) { coercedValue = String.valueOf(value); } else { - final Object maybeList = maybeCoerceArrayToList(value, false); + final Object maybeList = coerceArrayToList(value, false); // Check if "maybeList" was originally a Collection of some kind, or was able to be coerced to one. // Then Iterate through the collection, coercing each value. Useful for handling multi-value dimensions. @@ -152,10 +153,7 @@ public class SqlResults // the protobuf jdbc handler prefers lists (it actually can't handle java arrays as sql arrays, only java lists) // the json handler could handle this just fine, but it handles lists as sql arrays as well so just convert // here if needed - coercedValue = maybeCoerceArrayToList(value, true); - if (coercedValue == null) { - throw cannotCoerce(value, sqlTypeName, fieldName); - } + coercedValue = coerceArrayToList(value, true); } } else { throw cannotCoerce(value, sqlTypeName, fieldName); @@ -166,11 +164,11 @@ public class SqlResults /** * Attempt to coerce a value to {@link List}. If it cannot be coerced, either return the original value (if mustCoerce - * is false) or return null (if mustCoerce is true). + * is false) or return the value as a single element list (if mustCoerce is true). */ @VisibleForTesting @Nullable - static Object maybeCoerceArrayToList(Object value, boolean mustCoerce) + static Object coerceArrayToList(Object value, boolean mustCoerce) { if (value instanceof List) { return value; @@ -184,7 +182,7 @@ public class SqlResults final Object[] array = (Object[]) value; final ArrayList lst = new ArrayList<>(array.length); for (Object o : array) { - lst.add(maybeCoerceArrayToList(o, false)); + lst.add(coerceArrayToList(o, false)); } return lst; } else if (value instanceof long[]) { @@ -199,7 +197,7 @@ public class SqlResults } return lst; } else if (mustCoerce) { - return null; + return Collections.singletonList(value); } return value; } diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/run/SqlResultsTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/run/SqlResultsTest.java index 7d846f43454..7148adf40fe 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/run/SqlResultsTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/run/SqlResultsTest.java @@ -62,6 +62,8 @@ public class SqlResultsTest extends InitializedNullHandlingTest assertCoerceArrayToList(stringList, stringList); assertCoerceArrayToList(stringList, stringArray); assertCoerceArrayToList(stringList, stringArray2); + assertCoerceArrayToList(null, null); + assertCoerceArrayToList(Collections.singletonList("a"), "a"); } @Test @@ -76,6 +78,8 @@ public class SqlResultsTest extends InitializedNullHandlingTest assertCoerceArrayToList(listWithNull, arrayWithNull); assertCoerceArrayToList(list, list); assertCoerceArrayToList(list, array); + assertCoerceArrayToList(null, null); + assertCoerceArrayToList(Collections.singletonList(1L), 1L); } @Test @@ -90,6 +94,8 @@ public class SqlResultsTest extends InitializedNullHandlingTest assertCoerceArrayToList(listWithNull, arrayWithNull); assertCoerceArrayToList(list, list); assertCoerceArrayToList(list, array); + assertCoerceArrayToList(null, null); + assertCoerceArrayToList(Collections.singletonList(1.1), 1.1); } @Test @@ -104,6 +110,8 @@ public class SqlResultsTest extends InitializedNullHandlingTest assertCoerceArrayToList(listWithNull, arrayWithNull); assertCoerceArrayToList(list, list); assertCoerceArrayToList(list, array); + assertCoerceArrayToList(null, null); + assertCoerceArrayToList(Collections.singletonList(1.1f), 1.1f); } @Test @@ -225,11 +233,6 @@ public class SqlResultsTest extends InitializedNullHandlingTest Assert.assertEquals("Cannot coerce field [fieldName] from type [Byte Array] to type [BIGINT]", e.getMessage()); } } - @Test - public void testCoerceArrayFails() - { - assertCannotCoerce("xyz", SqlTypeName.ARRAY); - } @Test public void testCoerceUnsupportedType() @@ -238,15 +241,9 @@ public class SqlResultsTest extends InitializedNullHandlingTest } @Test - public void testMustCoerce() + public void testMayNotCoerceList() { - Assert.assertNull(SqlResults.maybeCoerceArrayToList("hello", true)); - } - - @Test - public void testMayNotCoerce() - { - Assert.assertEquals("hello", SqlResults.maybeCoerceArrayToList("hello", false)); + Assert.assertEquals("hello", SqlResults.coerceArrayToList("hello", false)); } private void assertCoerce(Object expected, Object toCoerce, SqlTypeName typeName) @@ -269,9 +266,9 @@ public class SqlResultsTest extends InitializedNullHandlingTest MatcherAssert.assertThat(e, ThrowableMessageMatcher.hasMessage(CoreMatchers.containsString("Cannot coerce"))); } - private static void assertCoerceArrayToList(Object expected, Object toCoerce) + private void assertCoerceArrayToList(Object expected, Object toCoerce) { - Object coerced = SqlResults.maybeCoerceArrayToList(toCoerce, true); + Object coerced = SqlResults.coerce(jsonMapper, DEFAULT_CONTEXT, toCoerce, SqlTypeName.ARRAY, ""); Assert.assertEquals(expected, coerced); } }