Skip to content

Commit

Permalink
[CALCITE-4118] RexSimplify might remove CAST from RexNode incorrectly
Browse files Browse the repository at this point in the history
  • Loading branch information
chunweilei committed Jul 31, 2020
1 parent 26b00ea commit 2088488
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
5 changes: 4 additions & 1 deletion core/src/main/java/org/apache/calcite/rex/RexSimplify.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlTypeCoercionRule;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.type.SqlTypeUtil;
import org.apache.calcite.util.Bug;
Expand Down Expand Up @@ -1917,7 +1918,9 @@ && sameTypeOrNarrowsNullability(e.getType(), intExpr.getType())) {
if (RexUtil.isLosslessCast(intExpr.getType(), operand.getType())
&& (e.getType().getSqlTypeName() == operand.getType().getSqlTypeName()
|| e.getType().getSqlTypeName() == SqlTypeName.CHAR
|| operand.getType().getSqlTypeName() != SqlTypeName.CHAR)) {
|| operand.getType().getSqlTypeName() != SqlTypeName.CHAR)
&& SqlTypeCoercionRule.instance()
.canApplyFrom(intExpr.getType().getSqlTypeName(), e.getType().getSqlTypeName())) {
return rexBuilder.makeCast(e.getType(), intExpr);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public abstract class RexProgramBuilderBase {
protected RexLiteral nullSmallInt;
protected RexLiteral nullVarchar;
protected RexLiteral nullDecimal;
protected RexLiteral nullVarbinary;

private RelDataType nullableBool;
private RelDataType nonNullableBool;
Expand All @@ -77,6 +78,9 @@ public abstract class RexProgramBuilderBase {
private RelDataType nullableDecimal;
private RelDataType nonNullableDecimal;

private RelDataType nullableVarbinary;
private RelDataType nonNullableVarbinary;

// Note: JUnit 4 creates new instance for each test method,
// so we initialize these structures on demand
// It maps non-nullable type to struct of (10 nullable, 10 non-nullable) fields
Expand Down Expand Up @@ -142,6 +146,10 @@ public Object get(String name) {
nonNullableDecimal = typeFactory.createSqlType(SqlTypeName.DECIMAL);
nullableDecimal = typeFactory.createTypeWithNullability(nonNullableDecimal, true);
nullDecimal = rexBuilder.makeNullLiteral(nullableDecimal);

nonNullableVarbinary = typeFactory.createSqlType(SqlTypeName.VARBINARY);
nullableVarbinary = typeFactory.createTypeWithNullability(nonNullableVarbinary, true);
nullVarbinary = rexBuilder.makeNullLiteral(nullableVarbinary);
}

private RexDynamicParam getDynamicParam(RelDataType type, String fieldNamePrefix) {
Expand Down Expand Up @@ -430,6 +438,15 @@ protected RelDataType tBigInt(boolean nullable) {
return type;
}

protected RelDataType tVarbinary() {
return nonNullableVarbinary;
}

protected RelDataType tVarbinary(boolean nullable) {
return nullable ? nullableVarbinary : nonNullableVarbinary;
}


protected RelDataType tArray(RelDataType elemType) {
return typeFactory.createArrayType(elemType, -1);
}
Expand Down
4 changes: 4 additions & 0 deletions core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2737,4 +2737,8 @@ private SqlSpecialOperatorWithPolicy(String name, SqlKind kind, int prec, boolea
checkSimplifyUnchanged(rexBuilder.makeCall(opPolicyAny, vIntNotNull()));
checkSimplify3(rexBuilder.makeCall(opPolicyAny, nullInt), "null:BOOLEAN", "false", "true");
}

@Test void testSimplifyVarbinary() {
checkSimplifyUnchanged(cast(cast(vInt(), tVarchar(true, 100)), tVarbinary(true)));
}
}

0 comments on commit 2088488

Please sign in to comment.