Source:
<code>private RexNode simplifyCast(RexCall e) { RexNode operand = e.getOperands().get(0); operand = simplify(operand, UNKNOWN); if (sameTypeOrNarrowsNullability(e.getType(), operand.getType())) { return operand; } if (RexUtil.isLosslessCast(operand)) { RexNode intExpr = ((RexCall) operand).operands.get(0); if ((intExpr.getType().getSqlTypeName() == SqlTypeName.CHAR || operand.getType().getSqlTypeName() != SqlTypeName.CHAR) && sameTypeOrNarrowsNullability(e.getType(), intExpr.getType())) { return intExpr; } if (RexUtil.isLosslessCast(intExpr.getType(), operand.getType()) && (e.getType().getSqlTypeName() == operand.getType().getSqlTypeName() || e.getType().getSqlTypeName() == SqlTypeName.CHAR || operand.getType().getSqlTypeName() != SqlTypeName.CHAR) && SqlTypeAssignmentRule.instance() .canApplyFrom(intExpr.getType().getSqlTypeName(), e.getType().getSqlTypeName())) { <START> return rexBuilder.makeCast(e.getType(), intExpr); <END> } } switch (operand.getKind()) { case LITERAL: final RexLiteral literal = (RexLiteral) operand; final Comparable value = literal.getValueAs(Comparable.class); final SqlTypeName typeName = literal.getTypeName(); if (rexBuilder.canRemoveCastFromLiteral(e.getType(), value, typeName)) { return rexBuilder.makeCast(e.getType(), operand); } switch (literal.getTypeName()) { case TIME: switch (e.getType().getSqlTypeName()) { case TIMESTAMP: return e; } break; } final List<RexNode> reducedValues = new ArrayList<>(); final RexNode simplifiedExpr = rexBuilder.makeCast(e.getType(), operand); executor.reduce(rexBuilder, ImmutableList.of(simplifiedExpr), reducedValues); return Objects.requireNonNull( Iterables.getOnlyElement(reducedValues)); default: if (operand == e.getOperands().get(0)) { return e; } else { return rexBuilder.makeCast(e.getType(), operand); } } }</code><technical_language>SqlTypeCoercionRule</technical_language>

Target:
private RexNode simplifyCast(RexCall e) { RexNode operand = e.getOperands().get(0); operand = simplify(operand, UNKNOWN); if (sameTypeOrNarrowsNullability(e.getType(), operand.getType())) { return operand; } if (RexUtil.isLosslessCast(operand)) { RexNode intExpr = ((RexCall) operand).operands.get(0); if ((intExpr.getType().getSqlTypeName() == SqlTypeName.CHAR || operand.getType().getSqlTypeName() != SqlTypeName.CHAR) && sameTypeOrNarrowsNullability(e.getType(), intExpr.getType())) { return intExpr; } if (RexUtil.isLosslessCast(intExpr.getType(), operand.getType()) && (e.getType().getSqlTypeName() == operand.getType().getSqlTypeName() || e.getType().getSqlTypeName() == SqlTypeName.CHAR || operand.getType().getSqlTypeName() != SqlTypeName.CHAR) && SqlTypeCoercionRule.instance() .canApplyFrom(intExpr.getType().getSqlTypeName(), e.getType().getSqlTypeName())) { return rexBuilder.makeCast(e.getType(), intExpr); } } switch (operand.getKind()) { case LITERAL: final RexLiteral literal = (RexLiteral) operand; final Comparable value = literal.getValueAs(Comparable.class); final SqlTypeName typeName = literal.getTypeName(); if (rexBuilder.canRemoveCastFromLiteral(e.getType(), value, typeName)) { return rexBuilder.makeCast(e.getType(), operand); } switch (literal.getTypeName()) { case TIME: switch (e.getType().getSqlTypeName()) { case TIMESTAMP: return e; } break; } final List<RexNode> reducedValues = new ArrayList<>(); final RexNode simplifiedExpr = rexBuilder.makeCast(e.getType(), operand); executor.reduce(rexBuilder, ImmutableList.of(simplifiedExpr), reducedValues); return Objects.requireNonNull( Iterables.getOnlyElement(reducedValues)); default: if (operand == e.getOperands().get(0)) { return e; } else { return rexBuilder.makeCast(e.getType(), operand); } } }