private List<Expression> getCaseResultExpressions(List<WhenClause> whenClauses, Optional<Expression> defaultValue) { List<Expression> resultExpressions = new ArrayList<>(); for (WhenClause whenClause : whenClauses) { resultExpressions.add(whenClause.getResult()); } defaultValue.ifPresent(resultExpressions::add); return resultExpressions; }
@Override protected String visitWhenClause(WhenClause node, Void context) { return "WHEN " + process(node.getOperand(), context) + " THEN " + process(node.getResult(), context); }
@Override protected R visitWhenClause(WhenClause node, C context) { process(node.getOperand(), context); process(node.getResult(), context); return null; }
@Override protected Boolean visitSearchedCaseExpression(SearchedCaseExpression node, Void context) { for (WhenClause whenClause : node.getWhenClauses()) { if (!process(whenClause.getOperand(), context) || !process(whenClause.getResult(), context)) { return false; } } return !node.getDefaultValue().isPresent() || process(node.getDefaultValue().get(), context); }
@Override protected RowExpression visitSimpleCaseExpression(SimpleCaseExpression node, Void context) { ImmutableList.Builder<RowExpression> arguments = ImmutableList.builder(); arguments.add(process(node.getOperand(), context)); for (WhenClause clause : node.getWhenClauses()) { arguments.add(call(whenSignature(getType(clause)), getType(clause), process(clause.getOperand(), context), process(clause.getResult(), context))); } Type returnType = getType(node); arguments.add(node.getDefaultValue() .map((value) -> process(value, context)) .orElse(constantNull(returnType))); return call(switchSignature(returnType), returnType, arguments.build()); }
@Override protected Object visitSearchedCaseExpression(SearchedCaseExpression node, Object context) { Object defaultResult = processWithExceptionHandling(node.getDefaultValue().orElse(null), context); List<WhenClause> whenClauses = new ArrayList<>(); for (WhenClause whenClause : node.getWhenClauses()) { Object whenOperand = processWithExceptionHandling(whenClause.getOperand(), context); Object result = processWithExceptionHandling(whenClause.getResult(), context); if (whenOperand instanceof Expression) { // cannot fully evaluate, add updated whenClause whenClauses.add(new WhenClause( toExpression(whenOperand, type(whenClause.getOperand())), toExpression(result, type(whenClause.getResult())))); } else if (Boolean.TRUE.equals(whenOperand)) { // condition is true, use this as defaultResult defaultResult = result; break; } } if (whenClauses.isEmpty()) { return defaultResult; } Expression resultExpression = (defaultResult == null) ? null : toExpression(defaultResult, type(node)); return new SearchedCaseExpression(whenClauses, Optional.ofNullable(resultExpression)); }
@Override protected Boolean visitWhenClause(WhenClause actual, Node expected) { if (!(expected instanceof WhenClause)) { return false; } WhenClause expectedWhenClause = (WhenClause) expected; return process(actual.getOperand(), expectedWhenClause.getOperand()) && process(actual.getResult(), expectedWhenClause.getResult()); }
@Override protected Boolean visitSimpleCaseExpression(SimpleCaseExpression node, Void context) { if (!process(node.getOperand(), context)) { return false; } for (WhenClause whenClause : node.getWhenClauses()) { if (!process(whenClause.getOperand(), context) || !process(whenClause.getResult(), context)) { return false; } } if (node.getDefaultValue().isPresent() && !process(node.getDefaultValue().get(), context)) { return false; } return true; }
private static class ChangeTypeVisitor implements RowExpressionVisitor<RowExpression, Void> { private final Type targetType; private ChangeTypeVisitor(Type targetType) { this.targetType = targetType; } @Override public RowExpression visitCall(CallExpression call, Void context) { return new CallExpression(call.getSignature(), targetType, call.getArguments()); } @Override public RowExpression visitInputReference(InputReferenceExpression reference, Void context) { return field(reference.getField(), targetType); } @Override public RowExpression visitConstant(ConstantExpression literal, Void context) { return constant(literal.getValue(), targetType); } @Override public RowExpression visitLambda(LambdaDefinitionExpression lambda, Void context)
@Override protected Type visitSearchedCaseExpression(SearchedCaseExpression node, StackableAstVisitorContext<Context> context) { for (WhenClause whenClause : node.getWhenClauses()) { coerceType(context, whenClause.getOperand(), BOOLEAN, "CASE WHEN clause"); } Type type = coerceToSingleType(context, "All CASE results must be the same type: %s", getCaseResultExpressions(node.getWhenClauses(), node.getDefaultValue())); setExpressionType(node, type); for (WhenClause whenClause : node.getWhenClauses()) { Type whenClauseType = process(whenClause.getResult(), context); setExpressionType(whenClause, whenClauseType); } return type; }
@Override protected Type visitSimpleCaseExpression(SimpleCaseExpression node, StackableAstVisitorContext<Context> context) { for (WhenClause whenClause : node.getWhenClauses()) { coerceToSingleType(context, whenClause, "CASE operand type does not match WHEN clause operand type: %s vs %s", node.getOperand(), whenClause.getOperand()); } Type type = coerceToSingleType(context, "All CASE results must be the same type: %s", getCaseResultExpressions(node.getWhenClauses(), node.getDefaultValue())); setExpressionType(node, type); for (WhenClause whenClause : node.getWhenClauses()) { Type whenClauseType = process(whenClause.getResult(), context); setExpressionType(whenClause, whenClauseType); } return type; }
@Override protected String visitWhenClause(WhenClause node, Void context) { return "WHEN " + process(node.getOperand(), context) + " THEN " + process(node.getResult(), context); }
private List<Expression> getCaseResultExpressions(List<WhenClause> whenClauses, Optional<Expression> defaultValue) { List<Expression> resultExpressions = new ArrayList<>(); for (WhenClause whenClause : whenClauses) { resultExpressions.add(whenClause.getResult()); } defaultValue.ifPresent(resultExpressions::add); return resultExpressions; }
@Override protected String visitWhenClause(WhenClause node, Boolean unmangleNames) { return "WHEN " + process(node.getOperand(), unmangleNames) + " THEN " + process(node.getResult(), unmangleNames); }
@Override protected String visitWhenClause(WhenClause node, Void context) { return "WHEN " + process(node.getOperand(), context) + " THEN " + process(node.getResult(), context); }
@Override protected R visitWhenClause(WhenClause node, C context) { process(node.getOperand(), context); process(node.getResult(), context); return null; }
@Override protected String visitWhenClause(WhenClause node, Boolean unmangleNames) { return "WHEN " + process(node.getOperand(), unmangleNames) + " THEN " + process(node.getResult(), unmangleNames); }
@Override protected R visitWhenClause(WhenClause node, C context) { process(node.getOperand(), context); process(node.getResult(), context); return null; }
@Override protected Boolean visitSearchedCaseExpression(SearchedCaseExpression node, Void context) { for (WhenClause whenClause : node.getWhenClauses()) { if (!process(whenClause.getOperand(), context) || !process(whenClause.getResult(), context)) { return false; } } return !node.getDefaultValue().isPresent() || process(node.getDefaultValue().get(), context); }