Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import org.apache.calcite.avatica.util.ByteString;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.core.Window;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexCall;
import org.apache.calcite.rex.RexInputRef;
Expand Down Expand Up @@ -106,6 +108,14 @@ private static RexNode toRexCall(RelBuilder builder, RexExpression.FunctionCall
// Calcite creates IN as SEARCH
return builder.in(operands.get(0), operands.subList(1, operands.size()));
}
if (operator.kind == SqlKind.CAST) {
// The second operand only holds the target type name (see handleCast). Calcite would use its type as the result.
RexNode operand = operands.get(0);
RelDataTypeFactory typeFactory = builder.getTypeFactory();
RelDataType type = typeFactory.createTypeWithNullability(rexExpression.getDataType().toType(typeFactory),
operand.getType().isNullable());
return builder.getRexBuilder().makeCast(type, operand);
}

return builder.call(operator, operands);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.calcite.rex.RexCall;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUnknownAs;
import org.apache.calcite.sql.SqlCollation;
import org.apache.calcite.sql.SqlKind;
Expand All @@ -47,6 +48,7 @@

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;


/// Tests for RexExpressionUtils, focusing on the handleSearch method and null handling.
Expand Down Expand Up @@ -92,6 +94,18 @@ public void testSqlKindFunctionNames() {
assertSame(RexExpressionUtils.getAggFunction(sum0), SqlStdOperatorTable.SUM0);
}

@Test
public void testCastRoundTrip() {
// Plan nodes hold the target type of CAST as a STRING literal operand. Field "a" is a nullable INTEGER.
RelBuilder relBuilder =
RelBuilder.create(Frameworks.newConfigBuilder().build()).values(new String[]{"a"}, 1, null);
RexExpression castCall = new RexExpression.FunctionCall(ColumnDataType.DOUBLE, SqlKind.CAST.name(),
List.of(new RexExpression.InputRef(0), new RexExpression.Literal(ColumnDataType.STRING, "DOUBLE")));
RexNode rexNode = RexExpressionUtils.toRexNode(relBuilder, castCall);
assertTrue(rexNode.getType().isNullable());
assertEquals(RexExpressionUtils.fromRexNode(rexNode), castCall);
}

@Test
public void testHandleSearchNullLiteralInWithNullAsUnknown() {
// Test: NULL IN (1, 2, 3) (when nullAs = UNKNOWN)
Expand Down
Loading