Skip to content

Commit fec82ff

Browse files
committed
Preserve raw element type in ListAggFunction
V3 LIST accumulator was stringifying every element via String.valueOf, which conflicted with the ARG0_ARRAY return-type declaration on PPLBuiltinOperators.LIST and threw ClassCastException at runtime (e.g. (Boolean) "true"). Drop the String.valueOf and accumulate raw Object values; update CalciteMultiValueStatsIT numeric/boolean assertions to match the unquoted JSON output. Signed-off-by: Vinay Krishna Pudyodu <vinkrish.neo@gmail.com>
1 parent 08e68e4 commit fec82ff

2 files changed

Lines changed: 16 additions & 17 deletions

File tree

core/src/main/java/org/opensearch/sql/calcite/udf/udaf/ListAggFunction.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,25 +40,24 @@ public Object result(ListAccumulator accumulator) {
4040

4141
@Override
4242
public ListAccumulator add(ListAccumulator acc, Object... values) {
43-
// Handle case where no values are passed
4443
if (values == null || values.length == 0) {
4544
return acc;
4645
}
4746

4847
Object value = values[0];
4948

50-
// Filter out null values and enforce 100-item limit
49+
// Preserve raw element type so the result matches the ARG0_ARRAY return-type
50+
// declaration on PPLBuiltinOperators.LIST. Stringifying here would break Calcite's
51+
// type-checking and the response-boundary UDT dispatch for ip / binary columns.
5152
if (value != null && acc.size() < DEFAULT_LIMIT) {
52-
// Convert value to string, handling all types safely
53-
String stringValue = String.valueOf(value);
54-
acc.add(stringValue);
53+
acc.add(value);
5554
}
5655

5756
return acc;
5857
}
5958

6059
public static class ListAccumulator implements Accumulator {
61-
private final List<String> values;
60+
private final List<Object> values;
6261

6362
public ListAccumulator() {
6463
this.values = new ArrayList<>();
@@ -69,7 +68,7 @@ public Object value(Object... argList) {
6968
return values;
7069
}
7170

72-
public void add(String value) {
71+
public void add(Object value) {
7372
values.add(value);
7473
}
7574

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalciteMultiValueStatsIT.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public void testListFunctionWithBoolean() throws IOException {
4343
"source=%s | stats list(boolean_value) as bool_list",
4444
TEST_INDEX_DATATYPE_NONNUMERIC));
4545
verifySchema(response, schema("bool_list", "array"));
46-
verifyDataRows(response, rows(List.of("true")));
46+
verifyDataRows(response, rows(List.of(true)));
4747
}
4848

4949
@Test
@@ -53,7 +53,7 @@ public void testListFunctionWithByte() throws IOException {
5353
String.format(
5454
"source=%s | stats list(byte_number) as byte_list", TEST_INDEX_DATATYPE_NUMERIC));
5555
verifySchema(response, schema("byte_list", "array"));
56-
verifyDataRows(response, rows(List.of("4")));
56+
verifyDataRows(response, rows(List.of(4)));
5757
}
5858

5959
@Test
@@ -63,7 +63,7 @@ public void testListFunctionWithShort() throws IOException {
6363
String.format(
6464
"source=%s | stats list(short_number) as short_list", TEST_INDEX_DATATYPE_NUMERIC));
6565
verifySchema(response, schema("short_list", "array"));
66-
verifyDataRows(response, rows(List.of("3")));
66+
verifyDataRows(response, rows(List.of(3)));
6767
}
6868

6969
@Test
@@ -73,7 +73,7 @@ public void testListFunctionWithInteger() throws IOException {
7373
String.format(
7474
"source=%s | stats list(integer_number) as int_list", TEST_INDEX_DATATYPE_NUMERIC));
7575
verifySchema(response, schema("int_list", "array"));
76-
verifyDataRows(response, rows(List.of("2")));
76+
verifyDataRows(response, rows(List.of(2)));
7777
}
7878

7979
@Test
@@ -83,7 +83,7 @@ public void testListFunctionWithLong() throws IOException {
8383
String.format(
8484
"source=%s | stats list(long_number) as long_list", TEST_INDEX_DATATYPE_NUMERIC));
8585
verifySchema(response, schema("long_list", "array"));
86-
verifyDataRows(response, rows(List.of("1")));
86+
verifyDataRows(response, rows(List.of(1)));
8787
}
8888

8989
@Test
@@ -93,7 +93,7 @@ public void testListFunctionWithFloat() throws IOException {
9393
String.format(
9494
"source=%s | stats list(float_number) as float_list", TEST_INDEX_DATATYPE_NUMERIC));
9595
verifySchema(response, schema("float_list", "array"));
96-
verifyDataRows(response, rows(List.of("6.2")));
96+
verifyDataRows(response, rows(List.of(6.2)));
9797
}
9898

9999
@Test
@@ -104,7 +104,7 @@ public void testListFunctionWithDouble() throws IOException {
104104
"source=%s | stats list(double_number) as double_list",
105105
TEST_INDEX_DATATYPE_NUMERIC));
106106
verifySchema(response, schema("double_list", "array"));
107-
verifyDataRows(response, rows(List.of("5.1")));
107+
verifyDataRows(response, rows(List.of(5.1)));
108108
}
109109

110110
@Test
@@ -188,7 +188,7 @@ public void testListFunctionWithNullValues() throws IOException {
188188
String.format("source=%s | head 5 | stats list(int0) as int_list", TEST_INDEX_CALCS));
189189
verifySchema(response, schema("int_list", "array"));
190190
// Nulls are filtered out by list function
191-
verifyDataRows(response, rows(List.of("1", "7")));
191+
verifyDataRows(response, rows(List.of(1, 7)));
192192
}
193193

194194
@Test
@@ -217,7 +217,7 @@ public void testListFunctionMultipleFields() throws IOException {
217217
assert response.has("datarows");
218218
// Values should be collected from the first 3 rows (str2 and int2 columns)
219219
// The actual values depend on the test data - int2 column contains 5, -4, 5
220-
verifyDataRows(response, rows(List.of("one", "two", "three"), List.of("5", "-4", "5")));
220+
verifyDataRows(response, rows(List.of("one", "two", "three"), List.of(5, -4, 5)));
221221
}
222222

223223
@Test
@@ -275,7 +275,7 @@ public void testListFunctionWithArithmeticExpression() throws IOException {
275275
String.format(
276276
"source=%s | head 3 | stats list(int3 + 1) as arithmetic_list", TEST_INDEX_CALCS));
277277
verifySchema(response, schema("arithmetic_list", "array"));
278-
verifyDataRows(response, rows(List.of("9", "14", "3")));
278+
verifyDataRows(response, rows(List.of(9, 14, 3)));
279279
}
280280

281281
// ==================== VALUES Function Tests ====================

0 commit comments

Comments
 (0)