mirror of https://github.com/apache/druid.git
fix sql results mixed array and scalar values (#16105)
* fix sql results mixed array and scalar values * simplify
This commit is contained in:
parent
82fced571b
commit
795e342ba8
|
@ -41,6 +41,7 @@ import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -70,7 +71,7 @@ public class SqlResults
|
||||||
} else if (value instanceof Boolean) {
|
} else if (value instanceof Boolean) {
|
||||||
coercedValue = String.valueOf(value);
|
coercedValue = String.valueOf(value);
|
||||||
} else {
|
} 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.
|
// 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.
|
// 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 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
|
// the json handler could handle this just fine, but it handles lists as sql arrays as well so just convert
|
||||||
// here if needed
|
// here if needed
|
||||||
coercedValue = maybeCoerceArrayToList(value, true);
|
coercedValue = coerceArrayToList(value, true);
|
||||||
if (coercedValue == null) {
|
|
||||||
throw cannotCoerce(value, sqlTypeName, fieldName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw cannotCoerce(value, sqlTypeName, fieldName);
|
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
|
* 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
|
@VisibleForTesting
|
||||||
@Nullable
|
@Nullable
|
||||||
static Object maybeCoerceArrayToList(Object value, boolean mustCoerce)
|
static Object coerceArrayToList(Object value, boolean mustCoerce)
|
||||||
{
|
{
|
||||||
if (value instanceof List) {
|
if (value instanceof List) {
|
||||||
return value;
|
return value;
|
||||||
|
@ -184,7 +182,7 @@ public class SqlResults
|
||||||
final Object[] array = (Object[]) value;
|
final Object[] array = (Object[]) value;
|
||||||
final ArrayList<Object> lst = new ArrayList<>(array.length);
|
final ArrayList<Object> lst = new ArrayList<>(array.length);
|
||||||
for (Object o : array) {
|
for (Object o : array) {
|
||||||
lst.add(maybeCoerceArrayToList(o, false));
|
lst.add(coerceArrayToList(o, false));
|
||||||
}
|
}
|
||||||
return lst;
|
return lst;
|
||||||
} else if (value instanceof long[]) {
|
} else if (value instanceof long[]) {
|
||||||
|
@ -199,7 +197,7 @@ public class SqlResults
|
||||||
}
|
}
|
||||||
return lst;
|
return lst;
|
||||||
} else if (mustCoerce) {
|
} else if (mustCoerce) {
|
||||||
return null;
|
return Collections.singletonList(value);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,8 @@ public class SqlResultsTest extends InitializedNullHandlingTest
|
||||||
assertCoerceArrayToList(stringList, stringList);
|
assertCoerceArrayToList(stringList, stringList);
|
||||||
assertCoerceArrayToList(stringList, stringArray);
|
assertCoerceArrayToList(stringList, stringArray);
|
||||||
assertCoerceArrayToList(stringList, stringArray2);
|
assertCoerceArrayToList(stringList, stringArray2);
|
||||||
|
assertCoerceArrayToList(null, null);
|
||||||
|
assertCoerceArrayToList(Collections.singletonList("a"), "a");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -76,6 +78,8 @@ public class SqlResultsTest extends InitializedNullHandlingTest
|
||||||
assertCoerceArrayToList(listWithNull, arrayWithNull);
|
assertCoerceArrayToList(listWithNull, arrayWithNull);
|
||||||
assertCoerceArrayToList(list, list);
|
assertCoerceArrayToList(list, list);
|
||||||
assertCoerceArrayToList(list, array);
|
assertCoerceArrayToList(list, array);
|
||||||
|
assertCoerceArrayToList(null, null);
|
||||||
|
assertCoerceArrayToList(Collections.singletonList(1L), 1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -90,6 +94,8 @@ public class SqlResultsTest extends InitializedNullHandlingTest
|
||||||
assertCoerceArrayToList(listWithNull, arrayWithNull);
|
assertCoerceArrayToList(listWithNull, arrayWithNull);
|
||||||
assertCoerceArrayToList(list, list);
|
assertCoerceArrayToList(list, list);
|
||||||
assertCoerceArrayToList(list, array);
|
assertCoerceArrayToList(list, array);
|
||||||
|
assertCoerceArrayToList(null, null);
|
||||||
|
assertCoerceArrayToList(Collections.singletonList(1.1), 1.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -104,6 +110,8 @@ public class SqlResultsTest extends InitializedNullHandlingTest
|
||||||
assertCoerceArrayToList(listWithNull, arrayWithNull);
|
assertCoerceArrayToList(listWithNull, arrayWithNull);
|
||||||
assertCoerceArrayToList(list, list);
|
assertCoerceArrayToList(list, list);
|
||||||
assertCoerceArrayToList(list, array);
|
assertCoerceArrayToList(list, array);
|
||||||
|
assertCoerceArrayToList(null, null);
|
||||||
|
assertCoerceArrayToList(Collections.singletonList(1.1f), 1.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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());
|
Assert.assertEquals("Cannot coerce field [fieldName] from type [Byte Array] to type [BIGINT]", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Test
|
|
||||||
public void testCoerceArrayFails()
|
|
||||||
{
|
|
||||||
assertCannotCoerce("xyz", SqlTypeName.ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCoerceUnsupportedType()
|
public void testCoerceUnsupportedType()
|
||||||
|
@ -238,15 +241,9 @@ public class SqlResultsTest extends InitializedNullHandlingTest
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMustCoerce()
|
public void testMayNotCoerceList()
|
||||||
{
|
{
|
||||||
Assert.assertNull(SqlResults.maybeCoerceArrayToList("hello", true));
|
Assert.assertEquals("hello", SqlResults.coerceArrayToList("hello", false));
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMayNotCoerce()
|
|
||||||
{
|
|
||||||
Assert.assertEquals("hello", SqlResults.maybeCoerceArrayToList("hello", false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertCoerce(Object expected, Object toCoerce, SqlTypeName typeName)
|
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")));
|
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);
|
Assert.assertEquals(expected, coerced);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue