@Override protected Object visitNullIfExpression(NullIfExpression node, Object context) Object first = process(node.getFirst(), context); if (first == null) { return null; Object second = process(node.getSecond(), context); if (second == null) { return first; Type firstType = type(node.getFirst()); Type secondType = type(node.getSecond()); return new NullIfExpression(toExpression(first, firstType), toExpression(second, secondType));
check(!filter.isPresent(), "FILTER not valid for 'nullif' function", context); return new NullIfExpression( getLocation(context), (Expression) visit(context.expression(0)),
@Override protected Object visitNullIfExpression(NullIfExpression node, Object context) Object first = process(node.getFirst(), context); if (first == null) { return null; Object second = process(node.getSecond(), context); if (second == null) { return first; Type firstType = type(node.getFirst()); Type secondType = type(node.getSecond()); return new NullIfExpression(toExpression(first, firstType), toExpression(second, secondType));
check(!filter.isPresent(), "FILTER not valid for 'nullif' function", context); return new NullIfExpression( getLocation(context), (Expression) visit(context.expression(0)),
@Test public void testNullIf() { assertExpression("nullif(42, 87)", new NullIfExpression(new LongLiteral("42"), new LongLiteral("87"))); assertExpression("nullif(42, null)", new NullIfExpression(new LongLiteral("42"), new NullLiteral())); assertExpression("nullif(null, null)", new NullIfExpression(new NullLiteral(), new NullLiteral())); assertInvalidExpression("nullif(1)", "Invalid number of arguments for 'nullif' function"); assertInvalidExpression("nullif(1, 2, 3)", "Invalid number of arguments for 'nullif' function"); assertInvalidExpression("nullif(42, 87) filter (where true)", "FILTER not valid for 'nullif' function"); assertInvalidExpression("nullif(42, 87) OVER ()", "OVER clause not valid for 'nullif' function"); }
@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")))); } }
@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 Type visitNullIfExpression(NullIfExpression node, StackableAstVisitorContext<Context> context) { Type firstType = process(node.getFirst(), context); Type secondType = process(node.getSecond(), context); if (!typeManager.getCommonSuperType(firstType, secondType).isPresent()) { throw new SemanticException(TYPE_MISMATCH, node, "Types are not comparable with NULLIF: %s vs %s", firstType, secondType); } return setExpressionType(node, firstType); }
@Override protected Type visitNullIfExpression(NullIfExpression node, StackableAstVisitorContext<Context> context) { Type firstType = process(node.getFirst(), context); Type secondType = process(node.getSecond(), context); if (!typeManager.getCommonSuperType(firstType, secondType).isPresent()) { throw new SemanticException(TYPE_MISMATCH, node, "Types are not comparable with NULLIF: %s vs %s", firstType, secondType); } return setExpressionType(node, firstType); }
@Override protected RowExpression visitNullIfExpression(NullIfExpression node, Void context) { RowExpression first = process(node.getFirst(), context); RowExpression second = process(node.getSecond(), context); return call( nullIfSignature(getType(node), first.getType(), second.getType()), getType(node), first, second); }
@Override protected RowExpression visitNullIfExpression(NullIfExpression node, Void context) { RowExpression first = process(node.getFirst(), context); RowExpression second = process(node.getSecond(), context); return call( nullIfSignature(getType(node), first.getType(), second.getType()), getType(node), first, second); }