Skip to content

Commit b567be6

Browse files
committed
Preserve UDT element type for list(ip|binary) aggregates
1 parent ea39ffd commit b567be6

2 files changed

Lines changed: 47 additions & 8 deletions

File tree

core/src/main/java/org/opensearch/sql/executor/analytics/AnalyticsExecutionEngine.java

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ private List<ExprValue> convertRows(Iterable<Object[]> rows, List<RelDataTypeFie
215215
* IpFieldMapper}'s {@code valueFetcher} output).
216216
* <li>{@link BinaryType} + {@code byte[]} &rarr; base64-encoded string (matches the OpenSearch
217217
* {@code binary} field wire format).
218+
* <li>{@code ARRAY<IpType>} / {@code ARRAY<BinaryType>} + {@code List<byte[]>} &rarr; element-wise
219+
* UDT-aware conversion for {@code list(ip|binary)} aggregates.
218220
* <li>Anything else &rarr; existing {@link ExprValueUtils#fromObjectValue} path.
219221
* </ul>
220222
*
@@ -224,19 +226,55 @@ private List<ExprValue> convertRows(Iterable<Object[]> rows, List<RelDataTypeFie
224226
private static ExprValue toExprValue(Object value, RelDataType type) {
225227
if (value instanceof byte[] bytes) {
226228
if (type instanceof IpType) {
227-
try {
228-
return ExprValueUtils.stringValue(
229-
InetAddresses.toAddrString(InetAddress.getByAddress(bytes)));
230-
} catch (UnknownHostException e) {
231-
throw new IllegalStateException("invalid IP buffer length: " + bytes.length, e);
232-
}
229+
return ipBytesToExprValue(bytes);
233230
} else if (type instanceof BinaryType) {
234-
return ExprValueUtils.stringValue(Base64.getEncoder().encodeToString(bytes));
231+
return binaryBytesToExprValue(bytes);
232+
}
233+
}
234+
if (value instanceof List<?> list) {
235+
RelDataType component = type.getComponentType();
236+
if (component instanceof IpType) {
237+
List<ExprValue> elems = new ArrayList<>(list.size());
238+
for (Object elem : list) {
239+
if (elem == null) {
240+
elems.add(ExprValueUtils.nullValue());
241+
} else if (elem instanceof byte[] eb) {
242+
elems.add(ipBytesToExprValue(eb));
243+
} else {
244+
elems.add(ExprValueUtils.fromObjectValue(elem));
245+
}
246+
}
247+
return new org.opensearch.sql.data.model.ExprCollectionValue(elems);
248+
} else if (component instanceof BinaryType) {
249+
List<ExprValue> elems = new ArrayList<>(list.size());
250+
for (Object elem : list) {
251+
if (elem == null) {
252+
elems.add(ExprValueUtils.nullValue());
253+
} else if (elem instanceof byte[] eb) {
254+
elems.add(binaryBytesToExprValue(eb));
255+
} else {
256+
elems.add(ExprValueUtils.fromObjectValue(elem));
257+
}
258+
}
259+
return new org.opensearch.sql.data.model.ExprCollectionValue(elems);
235260
}
236261
}
237262
return ExprValueUtils.fromObjectValue(value);
238263
}
239264

265+
private static ExprValue ipBytesToExprValue(byte[] bytes) {
266+
try {
267+
return ExprValueUtils.stringValue(
268+
InetAddresses.toAddrString(InetAddress.getByAddress(bytes)));
269+
} catch (UnknownHostException e) {
270+
throw new IllegalStateException("invalid IP buffer length: " + bytes.length, e);
271+
}
272+
}
273+
274+
private static ExprValue binaryBytesToExprValue(byte[] bytes) {
275+
return ExprValueUtils.stringValue(Base64.getEncoder().encodeToString(bytes));
276+
}
277+
240278
private Schema buildSchema(List<RelDataTypeField> fields) {
241279
List<Schema.Column> columns = new ArrayList<>();
242280
for (RelDataTypeField field : fields) {

core/src/main/java/org/opensearch/sql/expression/function/PPLBuiltinOperators.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,9 +499,10 @@ public class PPLBuiltinOperators extends ReflectiveSqlOperatorTable {
499499
"pattern",
500500
ReturnTypes.explicit(UserDefinedFunctionUtils.nullablePatternAggList),
501501
null);
502+
// ARG0_ARRAY preserves UDT element type so AnalyticsExecutionEngine can render IP/binary byte[].
502503
public static final SqlAggFunction LIST =
503504
createUserDefinedAggFunction(
504-
ListAggFunction.class, "LIST", PPLReturnTypes.STRING_ARRAY, PPLOperandTypes.ANY_SCALAR);
505+
ListAggFunction.class, "LIST", PPLReturnTypes.ARG0_ARRAY, PPLOperandTypes.ANY_SCALAR);
505506
public static final SqlAggFunction VALUES =
506507
createUserDefinedAggFunction(
507508
ValuesAggFunction.class,

0 commit comments

Comments
 (0)