@Override public Type visitCast(Cast node, StackableAstVisitorContext<AnalysisContext> context) { Type type = typeManager.getType(parseTypeSignature(node.getType())); if (type == null) { throw new SemanticException(TYPE_MISMATCH, node, "Unknown type: " + node.getType()); } if (type.equals(UNKNOWN)) { throw new SemanticException(TYPE_MISMATCH, node, "UNKNOWN is not a valid type"); } Type value = process(node.getExpression(), context); if (!value.equals(UNKNOWN)) { try { functionRegistry.getCoercion(value, type); } catch (OperatorNotFoundException e) { throw new SemanticException(TYPE_MISMATCH, node, "Cannot cast %s to %s", value, type); } } expressionTypes.put(node, type); return type; }
@Override protected RowExpression visitCast(Cast node, Void context) { RowExpression value = process(node.getExpression(), context); if (node.isSafe()) { return call(tryCastSignature(types.get(node), value.getType()), types.get(node), value); } return call(castSignature(types.get(node), value.getType()), types.get(node), value); }
@Override public Object visitCast(Cast node, Object context) { Object value = process(node.getExpression(), context); if (value instanceof Expression) { return new Cast((Expression) value, node.getType(), node.isSafe()); } // hack!!! don't optimize CASTs for types that cannot be represented in the SQL AST // TODO: this will not be an issue when we migrate to RowExpression tree for this, which allows arbitrary literals. if (optimize && !FunctionRegistry.isSupportedLiteralType(expressionTypes.get(node))) { return new Cast(toExpression(value, expressionTypes.get(node.getExpression())), node.getType(), node.isSafe()); } if (value == null) { return null; } Type type = metadata.getType(parseTypeSignature(node.getType())); if (type == null) { throw new IllegalArgumentException("Unsupported type: " + node.getType()); } Signature operator = metadata.getFunctionRegistry().getCoercion(expressionTypes.get(node.getExpression()), type); try { return invoke(session, metadata.getFunctionRegistry().getScalarFunctionImplementation(operator), ImmutableList.of(value)); } catch (RuntimeException e) { if (node.isSafe()) { return null; } throw e; } }
@VisibleForTesting @NotNull public static Expression createFailureFunction(RuntimeException exception, Type type) { requireNonNull(exception, "Exception is null"); String failureInfo = JsonCodec.jsonCodec(FailureInfo.class).toJson(Failures.toFailure(exception).toFailureInfo()); FunctionCall jsonParse = new FunctionCall(QualifiedName.of("json_parse"), ImmutableList.of(new StringLiteral(failureInfo))); FunctionCall failureFunction = new FunctionCall(QualifiedName.of("fail"), ImmutableList.of(jsonParse)); return new Cast(failureFunction, type.getTypeSignature().toString()); }
@Override public String visitCast(Cast node, Void context) { return (node.isSafe() ? "TRY_CAST" : "CAST") + "(" + process(node.getExpression(), context) + " AS " + node.getType() + ")"; }
@Override public String visitCast(Cast node, StackableAstVisitorContext<Integer> indent) { return (node.isSafe() ? "TRY_CAST" : "CAST") + "(" + process(node.getExpression(), indent) + " AS " + node.getType() + ")"; }
@Override protected Boolean visitCast(Cast node, Void context) { return process(node.getExpression(), context); }
@Override public Node visitCast(SqlBaseParser.CastContext context) { boolean isTryCast = context.TRY_CAST() != null; return new Cast(getLocation(context), (Expression) visit(context.expression()), getType(context.type()), isTryCast); }
@Override public String visitCast(Cast node, Boolean unmangleNames) { return (node.isSafe() ? "TRY_CAST" : "CAST") + "(" + process(node.getExpression(), unmangleNames) + " AS " + node.getType() + ")"; }
private static void assertCast(String type, String expected) { assertExpression("CAST(null AS " + type + ")", new Cast(new NullLiteral(), expected)); }