fix sql results mixed array and scalar values (#16105)

* fix sql results mixed array and scalar values

* simplify
This commit is contained in:
Clint Wylie 2024-03-12 23:47:35 -07:00 committed by GitHub
parent 82fced571b
commit 795e342ba8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 24 deletions

View File

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

View File

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