IGNITE-29031 SQL Calcite: Support byte[] in UDF and UDTF parameters and results - #13543
IGNITE-29031 SQL Calcite: Support byte[] in UDF and UDTF parameters and results#13543tkalkirill wants to merge 9 commits into
Conversation
|
First of all you need to follow the common process [1] i.e. make a PR from your own ignite mirror, not from origin = https://github.com/apache but from: https://github.com/tkalkirill/ignite |
|
@zstan Okay, subsequent tickets will do as described. |
| if (isA(fromType, Primitive.LONG)) | ||
| return Expressions.call(BuiltInMethod.INTERNAL_TO_TIMESTAMP.method, operand); | ||
| } | ||
| else if (targetType == byte[].class && fromType == ByteString.class) |
There was a problem hiding this comment.
The reverse branch in fromInternal is reachable through RexImpTable.defineReflective. I verified this with an operator backed by binaryLength(byte[]): with the conversion, a binary literal works; without it, generated code fails to compile because it passes ByteString to a method expecting byte[]. I suggest keeping this branch.
There was a problem hiding this comment.
sorry, but still miss it ( do we have a test for it ? suggest it plz ?
There was a problem hiding this comment.
Added a org.apache.ignite.internal.processors.query.calcite.integration.OperatorsExtensionIntegrationTest#testByteArrayFunctions that reproduces the issue if this is removed.
| assertNotSame(row, res); | ||
| assertEquals(1, res.length); | ||
| assertSame(val, res[0]); | ||
| assertSame(val, row[0]); |
| if (isA(fromType, Primitive.LONG)) | ||
| return Expressions.call(BuiltInMethod.INTERNAL_TO_TIMESTAMP.method, operand); | ||
| } | ||
| else if (targetType == byte[].class && fromType == ByteString.class) |
There was a problem hiding this comment.
sorry, but still miss it ( do we have a test for it ? suggest it plz ?
| } | ||
|
|
||
| /** */ | ||
| static List<Expression> fromInternal(RexToLixTranslator translator, |
There was a problem hiding this comment.
Look now you have two identical code, differs only with "RexToLixTranslator translator" param
i mean:
ConverterUtils#fromInternal(java.lang.Class[], List)
and
ConverterUtils#fromInternal(RexToLixTranslator, java.lang.Class[], java.util.List)
seems you can just rewrite your code like :
private static Expression fromInternal(@Nullable Expression root, Expression operand, Type targetType) {
if (Types.isAssignableFrom(targetType, operand.getType())
|| Types.isAssignableFrom(targetType, Primitive.box(operand.getType())))
return operand;
if (!TypeUtils.isConvertableType(targetType))
return targetType == BigDecimal.class ? fromInternal(operand, operand.getType(), targetType) :
convert(operand, operand.getType(), targetType);
Primitive primitive = Primitive.of(targetType);
if (Primitive.is(operand.getType()))
operand = Expressions.box(operand);
Expression converted = Expressions.call(
TypeUtils.class,
"fromInternal",
root,//translator.getRoot(),
operand,
Expressions.constant(targetType)
);
return primitive == null
? Expressions.convert_(converted, targetType)
: Expressions.unbox(Expressions.convert_(converted, primitive.boxClass), primitive);
}
probably some assertions check are helpful, it`s just a prototype
I run this approach through all calcite tests and it`s ok
wdyt ? props: more readable code, less code base
There was a problem hiding this comment.
Thanks, I did it a bit differently, and the duplication went away.
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
Pull request overview
Adds SQL Calcite support for byte[] UDF/UDTF parameters and results, with broader conversion coverage for temporal, primitive, collection, and custom types.
Changes:
- Adds internal/public binary and temporal value conversions.
- Updates reflective scalar and table functions to expose SQL-compatible types.
- Expands integration and execution tests.
File summaries
| File | Description |
|---|---|
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java | Updated as part of this pull request. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/OperatorsExtensionIntegrationTest.java | Updated as part of this pull request. |
| modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/exec/rel/ExecutionTest.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/util/TypeUtils.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/TableFunctionScan.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/LogicalRelImplementor.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/ReflectiveCallNotNullImplementor.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteTableFunction.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteScalarFunction.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteReflectiveFunctionBase.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/IgniteFunctionParameter.java | Updated as part of this pull request. |
| modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/exp/ConverterUtils.java | Updated as part of this pull request. |
Review details
Suppressed comments (1)
modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/exec/TableFunctionScan.java:73
- Using an exact-class check rejects valid array row holders whose runtime type is a subtype of
Object[](for exampleString[]orbyte[][]). These values satisfy the method's documentedObject[]row contract but now fail withIgniteSQLExceptionbefore column conversion; use anObject[]assignability/instanceofcheck while still cloning the array.
if (rowContainer.getClass() != Object[].class && !Collection.class.isAssignableFrom(rowContainer.getClass()))
throw new IgniteSQLException("Unable to process table function data: row type is neither Collection or Object[].");
Object[] rowArr = rowContainer.getClass() == Object[].class
? ((Object[])rowContainer).clone()
- Files reviewed: 12/12 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if (fromType == ByteString.class && toType == byte[].class) | ||
| return Expressions.call(BuiltInMethod.BYTE_STRING_TO_BYTE_ARRAY.method, operand); |
There was a problem hiding this comment.
these conversion still has no test coverage, isn`t it ?
| * <p>The SQL representation is required to validate user-defined function arguments and to convert literal arguments | ||
| * while deriving a table function row type. | ||
| */ | ||
| final class IgniteFunctionParameter implements FunctionParameter { |
There was a problem hiding this comment.
seems all tests are passed if you completelly remote this class, am i right ?
|
|
||
| return primitive == null | ||
| ? Expressions.convert_(converted, targetType) | ||
| : Expressions.unbox(Expressions.convert_(converted, primitive.boxClass), primitive); |
https://issues.apache.org/jira/browse/IGNITE-29031