private static Expression orNullHashCode(Expression expression) { return new CoalesceExpression(expression, new LongLiteral(String.valueOf(NULL_HASH_CODE))); }
@Override protected R visitCoalesceExpression(CoalesceExpression node, C context) { for (Expression operand : node.getOperands()) { process(operand, context); } return null; }
@Override protected Object visitCoalesceExpression(CoalesceExpression node, Object context) { Type type = type(node); List<Object> values = node.getOperands().stream() .map(value -> processWithExceptionHandling(value, context)) .filter(Objects::nonNull) .collect(Collectors.toList()); if ((!values.isEmpty() && !(values.get(0) instanceof Expression)) || values.size() == 1) { return values.get(0); } List<Expression> expressions = values.stream() .map(value -> toExpression(value, type)) .collect(Collectors.toList()); if (expressions.isEmpty()) { return null; } return new CoalesceExpression(expressions); }
@Override protected Object visitCoalesceExpression(CoalesceExpression node, Object context) { Type type = type(node); List<Object> values = node.getOperands().stream() .map(value -> processWithExceptionHandling(value, context)) .filter(value -> value != null) .collect(Collectors.toList()); if ((!values.isEmpty() && !(values.get(0) instanceof Expression)) || values.size() == 1) { return values.get(0); } List<Expression> expressions = values.stream() .map(value -> toExpression(value, type)) .collect(Collectors.toList()); if (expressions.isEmpty()) { return null; } return new CoalesceExpression(expressions); }
public static SelectItem aliasedNullToEmpty(String column, String alias) { return new SingleColumn(new CoalesceExpression(identifier(column), new StringLiteral("")), identifier(alias)); }
@Override protected String visitCoalesceExpression(CoalesceExpression node, Void context) { return "COALESCE(" + joinExpressions(node.getOperands()) + ")"; }
public static Optional<Expression> getHashExpression(List<Symbol> symbols) { if (symbols.isEmpty()) { return Optional.empty(); } Expression result = new LongLiteral(String.valueOf(INITIAL_HASH_VALUE)); for (Symbol symbol : symbols) { Expression hashField = new FunctionCall( QualifiedName.of(HASH_CODE), Optional.empty(), false, ImmutableList.of(new SymbolReference(symbol.getName()))); hashField = new CoalesceExpression(hashField, new LongLiteral(String.valueOf(NULL_HASH_CODE))); result = new FunctionCall(QualifiedName.of("combine_hash"), ImmutableList.of(result, hashField)); } return Optional.of(result); }
@Override protected Boolean visitCoalesceExpression(CoalesceExpression node, Void context) { return node.getOperands().stream().allMatch(expression -> process(expression, context)); }
for (Symbol symbol : outerJoin.getOutputSymbols()) { if (aggregationNode.getAggregations().containsKey(symbol)) { assignmentsBuilder.put(symbol, new CoalesceExpression(symbol.toSymbolReference(), sourceAggregationToOverNullMapping.get(symbol).toSymbolReference()));
public static Optional<Symbol> rewriteExpression(Map<Symbol, Expression> assignments, Expression expression) { checkArgument(expression instanceof CoalesceExpression, "The rewrite can only handle CoalesceExpression"); // We are using the property that the result of coalesce from full outer join keys would not be null despite of the order // of the arguments. Thus we extract and compare the symbols of the CoalesceExpression as a set rather than compare the // CoalesceExpression directly. for (Map.Entry<Symbol, Expression> entry : assignments.entrySet()) { if (entry.getValue() instanceof CoalesceExpression) { Set<Symbol> symbolsInAssignment = ((CoalesceExpression) entry.getValue()).getOperands().stream() .filter(SymbolReference.class::isInstance) .map(Symbol::from) .collect(toImmutableSet()); Set<Symbol> symbolInExpression = ((CoalesceExpression) expression).getOperands().stream() .filter(SymbolReference.class::isInstance) .map(Symbol::from) .collect(toImmutableSet()); if (symbolsInAssignment.containsAll(symbolInExpression)) { return Optional.of(entry.getKey()); } } } return Optional.empty(); } }
@Test(timeOut = 10_000) public void testPossibleExponentialOptimizationTime() { Expression expression = new LongLiteral("1"); ImmutableMap.Builder<NodeRef<Expression>, Type> types = ImmutableMap.builder(); types.put(NodeRef.of(expression), BIGINT); for (int i = 0; i < 100; i++) { expression = new CoalesceExpression(expression, new LongLiteral("2")); types.put(NodeRef.of(expression), BIGINT); } translateAndOptimize(expression, types.build()); }
@Override protected SymbolStatsEstimate visitCoalesceExpression(CoalesceExpression node, Void context) { requireNonNull(node, "node is null"); SymbolStatsEstimate result = null; for (Expression operand : node.getOperands()) { SymbolStatsEstimate operandEstimates = process(operand); if (result != null) { result = estimateCoalesce(result, operandEstimates); } else { result = operandEstimates; } } return requireNonNull(result, "result is null"); }
for (Symbol symbol : aggregationNode.getOutputSymbols()) { if (coalesceSymbols.containsKey(symbol)) { Expression expression = new CoalesceExpression(symbol.toSymbolReference(), new Cast(new LongLiteral("0"), "bigint")); outputSymbols.put(coalesceSymbols.get(symbol), expression);
@Override protected Type visitCoalesceExpression(CoalesceExpression node, StackableAstVisitorContext<Context> context) { Type type = coerceToSingleType(context, "All COALESCE operands must be the same type: %s", node.getOperands()); return setExpressionType(node, type); }
check(!filter.isPresent(), "FILTER not valid for 'coalesce' function", context); return new CoalesceExpression(getLocation(context), visit(context.expression(), Expression.class));
@Override protected Boolean visitCoalesceExpression(CoalesceExpression actual, Node expected) { if (!(expected instanceof CoalesceExpression)) { return false; } CoalesceExpression expectedCoalesce = (CoalesceExpression) expected; if (actual.getOperands().size() == expectedCoalesce.getOperands().size()) { boolean verified = true; for (int i = 0; i < actual.getOperands().size(); i++) { verified &= process(actual.getOperands().get(i), expectedCoalesce.getOperands().get(i)); } return verified; } return false; }
Symbol output = symbolAllocator.newSymbol(column, analysis.getType(column)); outputs.add(output); assignments.put(output, new CoalesceExpression( leftJoinColumns.get(column).toSymbolReference(), rightJoinColumns.get(column).toSymbolReference()));
@Override protected RowExpression visitCoalesceExpression(CoalesceExpression node, Void context) { List<RowExpression> arguments = node.getOperands().stream() .map(value -> process(value, context)) .collect(toImmutableList()); List<Type> argumentTypes = arguments.stream().map(RowExpression::getType).collect(toImmutableList()); return call(coalesceSignature(getType(node), argumentTypes), getType(node), arguments); }
@Test public void testCoalesce() { assertInvalidExpression("coalesce()", "The 'coalesce' function must have at least two arguments"); assertInvalidExpression("coalesce(5)", "The 'coalesce' function must have at least two arguments"); assertInvalidExpression("coalesce(1, 2) filter (where true)", "FILTER not valid for 'coalesce' function"); assertInvalidExpression("coalesce(1, 2) OVER ()", "OVER clause not valid for 'coalesce' function"); assertExpression("coalesce(13, 42)", new CoalesceExpression(new LongLiteral("13"), new LongLiteral("42"))); assertExpression("coalesce(6, 7, 8)", new CoalesceExpression(new LongLiteral("6"), new LongLiteral("7"), new LongLiteral("8"))); assertExpression("coalesce(13, null)", new CoalesceExpression(new LongLiteral("13"), new NullLiteral())); assertExpression("coalesce(null, 13)", new CoalesceExpression(new NullLiteral(), new LongLiteral("13"))); assertExpression("coalesce(null, null)", new CoalesceExpression(new NullLiteral(), new NullLiteral())); }
@Override protected String visitCoalesceExpression(CoalesceExpression node, Void context) { return "COALESCE(" + joinExpressions(node.getOperands()) + ")"; }