@Override protected Object visitIfExpression(IfExpression node, Object context) { Object trueValue = processWithExceptionHandling(node.getTrueValue(), context); Object falseValue = processWithExceptionHandling(node.getFalseValue().orElse(null), context); Object condition = processWithExceptionHandling(node.getCondition(), context); if (condition instanceof Expression) { Expression falseValueExpression = (falseValue == null) ? null : toExpression(falseValue, type(node.getFalseValue().get())); return new IfExpression( toExpression(condition, type(node.getCondition())), toExpression(trueValue, type(node.getTrueValue())), falseValueExpression); } else if (Boolean.TRUE.equals(condition)) { return trueValue; } else { return falseValue; } }
@Override protected Boolean visitIfExpression(IfExpression node, Void context) { ImmutableList.Builder<Expression> expressions = ImmutableList.<Expression>builder() .add(node.getCondition()) .add(node.getTrueValue()); if (node.getFalseValue().isPresent()) { expressions.add(node.getFalseValue().get()); } return expressions.build().stream().allMatch(expression -> process(expression, context)); }
private static IfExpression createIfExpression(Expression left, Expression right, ComparisonExpression.Operator operator, Expression result, Type trueValueType) { return new IfExpression( new ComparisonExpression(operator, left, right), result, new Cast(new NullLiteral(), trueValueType.getTypeSignature().toString())); } }
@Override protected Boolean visitIfExpression(IfExpression node, Void context) { ImmutableList.Builder<Expression> expressions = ImmutableList.<Expression>builder() .add(node.getCondition()) .add(node.getTrueValue()); if (node.getFalseValue().isPresent()) { expressions.add(node.getFalseValue().get()); } return expressions.build().stream().allMatch(expression -> process(expression, context)); }
private static IfExpression createIfExpression(Expression left, Expression right, ComparisonExpression.Operator operator, Expression result, Type trueValueType) { return new IfExpression( new ComparisonExpression(operator, left, right), result, new Cast(new NullLiteral(), trueValueType.getTypeSignature().toString())); } }
@Override protected R visitIfExpression(IfExpression node, C context) { process(node.getCondition(), context); process(node.getTrueValue(), context); if (node.getFalseValue().isPresent()) { process(node.getFalseValue().get(), context); } return null; }
@Override protected Object visitIfExpression(IfExpression node, Object context) { Object trueValue = processWithExceptionHandling(node.getTrueValue(), context); Object falseValue = processWithExceptionHandling(node.getFalseValue().orElse(null), context); Object condition = processWithExceptionHandling(node.getCondition(), context); if (condition instanceof Expression) { Expression falseValueExpression = (falseValue == null) ? null : toExpression(falseValue, type(node.getFalseValue().get())); return new IfExpression( toExpression(condition, type(node.getCondition())), toExpression(trueValue, type(node.getTrueValue())), falseValueExpression); } else if (Boolean.TRUE.equals(condition)) { return trueValue; } else { return falseValue; } }
return new IfExpression( getLocation(context), (Expression) visit(context.expression(0)),
@Override protected R visitIfExpression(IfExpression node, C context) { process(node.getCondition(), context); process(node.getTrueValue(), context); if (node.getFalseValue().isPresent()) { process(node.getFalseValue().get(), context); } return null; }
return new IfExpression( getLocation(context), (Expression) visit(context.expression(0)),
@Override protected Type visitIfExpression(IfExpression node, StackableAstVisitorContext<Context> context) { coerceType(context, node.getCondition(), BOOLEAN, "IF condition"); Type type; if (node.getFalseValue().isPresent()) { type = coerceToSingleType(context, node, "Result types for IF must be the same: %s vs %s", node.getTrueValue(), node.getFalseValue().get()); } else { type = process(node.getTrueValue(), context); } return setExpressionType(node, type); }
@Test public void testIf() { assertExpression("if(true, 1, 0)", new IfExpression(new BooleanLiteral("true"), new LongLiteral("1"), new LongLiteral("0"))); assertExpression("if(true, 3, null)", new IfExpression(new BooleanLiteral("true"), new LongLiteral("3"), new NullLiteral())); assertExpression("if(false, null, 4)", new IfExpression(new BooleanLiteral("false"), new NullLiteral(), new LongLiteral("4"))); assertExpression("if(false, null, null)", new IfExpression(new BooleanLiteral("false"), new NullLiteral(), new NullLiteral())); assertExpression("if(true, 3)", new IfExpression(new BooleanLiteral("true"), new LongLiteral("3"), null)); assertInvalidExpression("IF(true)", "Invalid number of arguments for 'if' function"); assertInvalidExpression("IF(true, 1, 0) FILTER (WHERE true)", "FILTER not valid for 'if' function"); assertInvalidExpression("IF(true, 1, 0) OVER()", "OVER clause not valid for 'if' function"); }
@Override protected Type visitIfExpression(IfExpression node, StackableAstVisitorContext<Context> context) { coerceType(context, node.getCondition(), BOOLEAN, "IF condition"); Type type; if (node.getFalseValue().isPresent()) { type = coerceToSingleType(context, node, "Result types for IF must be the same: %s vs %s", node.getTrueValue(), node.getFalseValue().get()); } else { type = process(node.getTrueValue(), context); } return setExpressionType(node, type); }
@Test public void testExpressionsThatMayReturnNullOnNonNullInput() { List<Expression> candidates = ImmutableList.of( new Cast(nameReference("b"), "BIGINT", true), // try_cast new FunctionCall(QualifiedName.of("try"), ImmutableList.of(nameReference("b"))), new NullIfExpression(nameReference("b"), number(1)), new IfExpression(nameReference("b"), number(1), new NullLiteral()), new DereferenceExpression(nameReference("b"), identifier("x")), new InPredicate(nameReference("b"), new InListExpression(ImmutableList.of(new NullLiteral()))), new SearchedCaseExpression(ImmutableList.of(new WhenClause(new IsNotNullPredicate(nameReference("b")), new NullLiteral())), Optional.empty()), new SimpleCaseExpression(nameReference("b"), ImmutableList.of(new WhenClause(number(1), new NullLiteral())), Optional.empty()), new SubscriptExpression(new ArrayConstructor(ImmutableList.of(new NullLiteral())), nameReference("b"))); for (Expression candidate : candidates) { EqualityInference.Builder builder = new EqualityInference.Builder(); builder.extractInferenceCandidates(equals(nameReference("b"), nameReference("x"))); builder.extractInferenceCandidates(equals(nameReference("a"), candidate)); EqualityInference inference = builder.build(); List<Expression> equalities = inference.generateEqualitiesPartitionedBy(matchesSymbols("b")).getScopeStraddlingEqualities(); assertEquals(equalities.size(), 1); assertTrue(equalities.get(0).equals(equals(nameReference("x"), nameReference("b"))) || equalities.get(0).equals(equals(nameReference("b"), nameReference("x")))); } }
@Override protected String visitIfExpression(IfExpression node, Void context) { StringBuilder builder = new StringBuilder(); builder.append("IF(") .append(process(node.getCondition(), context)) .append(", ") .append(process(node.getTrueValue(), context)); if (node.getFalseValue().isPresent()) { builder.append(", ") .append(process(node.getFalseValue().get(), context)); } builder.append(")"); return builder.toString(); }
@Test public void testExpressionsThatMayReturnNullOnNonNullInput() { List<Expression> candidates = ImmutableList.of( new Cast(nameReference("b"), "BIGINT", true), // try_cast new FunctionCall(QualifiedName.of("try"), ImmutableList.of(nameReference("b"))), new NullIfExpression(nameReference("b"), number(1)), new IfExpression(nameReference("b"), number(1), new NullLiteral()), new DereferenceExpression(nameReference("b"), identifier("x")), new InPredicate(nameReference("b"), new InListExpression(ImmutableList.of(new NullLiteral()))), new SearchedCaseExpression(ImmutableList.of(new WhenClause(new IsNotNullPredicate(nameReference("b")), new NullLiteral())), Optional.empty()), new SimpleCaseExpression(nameReference("b"), ImmutableList.of(new WhenClause(number(1), new NullLiteral())), Optional.empty()), new SubscriptExpression(new ArrayConstructor(ImmutableList.of(new NullLiteral())), nameReference("b"))); for (Expression candidate : candidates) { EqualityInference.Builder builder = new EqualityInference.Builder(); builder.extractInferenceCandidates(equals(nameReference("b"), nameReference("x"))); builder.extractInferenceCandidates(equals(nameReference("a"), candidate)); EqualityInference inference = builder.build(); List<Expression> equalities = inference.generateEqualitiesPartitionedBy(matchesSymbols("b")).getScopeStraddlingEqualities(); assertEquals(equalities.size(), 1); assertTrue(equalities.get(0).equals(equals(nameReference("x"), nameReference("b"))) || equalities.get(0).equals(equals(nameReference("b"), nameReference("x")))); } }
@Override protected String visitIfExpression(IfExpression node, Void context) { StringBuilder builder = new StringBuilder(); builder.append("IF(") .append(process(node.getCondition(), context)) .append(", ") .append(process(node.getTrueValue(), context)); if (node.getFalseValue().isPresent()) { builder.append(", ") .append(process(node.getFalseValue().get(), context)); } builder.append(")"); return builder.toString(); }
@Override public Expression rewriteIfExpression(IfExpression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { Expression condition = treeRewriter.rewrite(node.getCondition(), context); Expression trueValue = treeRewriter.rewrite(node.getTrueValue(), context); Optional<Expression> falseValue = node.getFalseValue().map((value) -> treeRewriter.rewrite(value, context)); return new SearchedCaseExpression(ImmutableList.of(new WhenClause(condition, trueValue)), falseValue); }
@Override public Expression rewriteIfExpression(IfExpression node, Void context, ExpressionTreeRewriter<Void> treeRewriter) { Expression condition = treeRewriter.rewrite(node.getCondition(), context); Expression trueValue = treeRewriter.rewrite(node.getTrueValue(), context); Optional<Expression> falseValue = node.getFalseValue().map((value) -> treeRewriter.rewrite(value, context)); return new SearchedCaseExpression(ImmutableList.of(new WhenClause(condition, trueValue)), falseValue); }
@Override protected RowExpression visitIfExpression(IfExpression node, Void context) { ImmutableList.Builder<RowExpression> arguments = ImmutableList.builder(); arguments.add(process(node.getCondition(), context)) .add(process(node.getTrueValue(), context)); if (node.getFalseValue().isPresent()) { arguments.add(process(node.getFalseValue().get(), context)); } else { arguments.add(constantNull(getType(node))); } return call(Signatures.ifSignature(getType(node)), getType(node), arguments.build()); }