/** * Creates a key for {@link RexNode} which is the same as another key of another RexNode only if * the two have both the same type and textual representation. For example, "10" integer and "10" * bigint result in different keys. */ public static String makeKey(RexNode expr) { String type = expr.getType().getFullTypeString(); String separator = ";"; String node = expr.toString(); StringBuilder keyBuilder = new StringBuilder(type.length() + separator.length() + node.length()); keyBuilder.append(type).append(separator).append(node); return keyBuilder.toString(); }
// override RexShuttle public RexNode visitCall(final RexCall call) { int i = reducibleExps.indexOf(call); if (i == -1) { return super.visitCall(call); } RexNode replacement = reducedValues.get(i); if (addCasts.get(i) && (replacement.getType() != call.getType())) { // Handle change from nullable to NOT NULL by claiming // that the result is still nullable, even though // we know it isn't. // // Also, we cannot reduce CAST('abc' AS VARCHAR(4)) to 'abc'. // If we make 'abc' of type VARCHAR(4), we may later encounter // the same expression in a ProjectRel's digest where it has // type VARCHAR(3), and that's wrong. replacement = rexBuilder.makeCast(call.getType(), replacement); } return replacement; }