@Override protected Type visitBetweenPredicate(BetweenPredicate node, StackableAstVisitorContext<Context> context) { return getOperator(context, node, OperatorType.BETWEEN, node.getValue(), node.getMin(), node.getMax()); }
@Override protected Type visitBetweenPredicate(BetweenPredicate node, StackableAstVisitorContext<Context> context) { return getOperator(context, node, OperatorType.BETWEEN, node.getValue(), node.getMin(), node.getMax()); }
@Override protected String visitBetweenPredicate(BetweenPredicate node, Void context) { return "(" + process(node.getValue(), context) + " BETWEEN " + process(node.getMin(), context) + " AND " + process(node.getMax(), context) + ")"; }
@Override protected R visitBetweenPredicate(BetweenPredicate node, C context) { process(node.getValue(), context); process(node.getMin(), context); process(node.getMax(), context); return null; }
@Override protected String visitBetweenPredicate(BetweenPredicate node, Void context) { return "(" + process(node.getValue(), context) + " BETWEEN " + process(node.getMin(), context) + " AND " + process(node.getMax(), context) + ")"; }
@Override protected Boolean visitBetweenPredicate(BetweenPredicate node, Void context) { return process(node.getMin(), context) && process(node.getValue(), context) && process(node.getMax(), context); }
@Override protected R visitBetweenPredicate(BetweenPredicate node, C context) { process(node.getValue(), context); process(node.getMin(), context); process(node.getMax(), context); return null; }
@Override protected Boolean visitBetweenPredicate(BetweenPredicate node, Void context) { return process(node.getMin(), context) && process(node.getValue(), context) && process(node.getMax(), context); }
@Override protected ExtractionResult visitBetweenPredicate(BetweenPredicate node, Boolean complement) { // Re-write as two comparison expressions return process(and( new ComparisonExpression(GREATER_THAN_OR_EQUAL, node.getValue(), node.getMin()), new ComparisonExpression(LESS_THAN_OR_EQUAL, node.getValue(), node.getMax())), complement); }
@Override protected ExtractionResult visitBetweenPredicate(BetweenPredicate node, Boolean complement) { // Re-write as two comparison expressions return process(and( new ComparisonExpression(GREATER_THAN_OR_EQUAL, node.getValue(), node.getMin()), new ComparisonExpression(LESS_THAN_OR_EQUAL, node.getValue(), node.getMax())), complement); }
@Override protected Object visitBetweenPredicate(BetweenPredicate node, Object context) { Object value = process(node.getValue(), context); if (value == null) { return null; } Object min = process(node.getMin(), context); if (min == null) { return null; } Object max = process(node.getMax(), context); if (max == null) { return null; } if (hasUnresolvedValue(value, min, max)) { return new BetweenPredicate( toExpression(value, type(node.getValue())), toExpression(min, type(node.getMin())), toExpression(max, type(node.getMax()))); } return invokeOperator(OperatorType.BETWEEN, types(node.getValue(), node.getMin(), node.getMax()), ImmutableList.of(value, min, max)); }
@Override protected Object visitBetweenPredicate(BetweenPredicate node, Object context) { Object value = process(node.getValue(), context); if (value == null) { return null; } Object min = process(node.getMin(), context); if (min == null) { return null; } Object max = process(node.getMax(), context); if (max == null) { return null; } if (hasUnresolvedValue(value, min, max)) { return new BetweenPredicate( toExpression(value, type(node.getValue())), toExpression(min, type(node.getMin())), toExpression(max, type(node.getMax()))); } return invokeOperator(OperatorType.BETWEEN, types(node.getValue(), node.getMin(), node.getMax()), ImmutableList.of(value, min, max)); }
@Override protected Boolean visitBetweenPredicate(BetweenPredicate actual, Node expectedExpression) { if (expectedExpression instanceof BetweenPredicate) { BetweenPredicate expected = (BetweenPredicate) expectedExpression; return process(actual.getValue(), expected.getValue()) && process(actual.getMin(), expected.getMin()) && process(actual.getMax(), expected.getMax()); } return false; }
@Override protected Boolean visitBetweenPredicate(BetweenPredicate actual, Node expectedExpression) { if (expectedExpression instanceof BetweenPredicate) { BetweenPredicate expected = (BetweenPredicate) expectedExpression; return process(actual.getValue(), expected.getValue()) && process(actual.getMin(), expected.getMin()) && process(actual.getMax(), expected.getMax()); } return false; }
@Override protected RowExpression visitBetweenPredicate(BetweenPredicate node, Void context) { RowExpression value = process(node.getValue(), context); RowExpression min = process(node.getMin(), context); RowExpression max = process(node.getMax(), context); return call( betweenSignature(value.getType(), min.getType(), max.getType()), BOOLEAN, value, min, max); }
@Override protected RowExpression visitBetweenPredicate(BetweenPredicate node, Void context) { RowExpression value = process(node.getValue(), context); RowExpression min = process(node.getMin(), context); RowExpression max = process(node.getMax(), context); return call( betweenSignature(value.getType(), min.getType(), max.getType()), BOOLEAN, value, min, max); }
@Override protected PlanNodeStatsEstimate visitBetweenPredicate(BetweenPredicate node, Void context) { if (!(node.getValue() instanceof SymbolReference)) { return PlanNodeStatsEstimate.unknown(); } if (!getExpressionStats(node.getMin()).isSingleValue()) { return PlanNodeStatsEstimate.unknown(); } if (!getExpressionStats(node.getMax()).isSingleValue()) { return PlanNodeStatsEstimate.unknown(); } SymbolStatsEstimate valueStats = input.getSymbolStatistics(Symbol.from(node.getValue())); Expression lowerBound = new ComparisonExpression(GREATER_THAN_OR_EQUAL, node.getValue(), node.getMin()); Expression upperBound = new ComparisonExpression(LESS_THAN_OR_EQUAL, node.getValue(), node.getMax()); Expression transformed; if (isInfinite(valueStats.getLowValue())) { // We want to do heuristic cut (infinite range to finite range) ASAP and then do filtering on finite range. // We rely on 'and()' being processed left to right transformed = and(lowerBound, upperBound); } else { transformed = and(upperBound, lowerBound); } return process(transformed); }
@Override protected PlanNodeStatsEstimate visitBetweenPredicate(BetweenPredicate node, Void context) { if (!(node.getValue() instanceof SymbolReference)) { return PlanNodeStatsEstimate.unknown(); } if (!getExpressionStats(node.getMin()).isSingleValue()) { return PlanNodeStatsEstimate.unknown(); } if (!getExpressionStats(node.getMax()).isSingleValue()) { return PlanNodeStatsEstimate.unknown(); } SymbolStatsEstimate valueStats = input.getSymbolStatistics(Symbol.from(node.getValue())); Expression lowerBound = new ComparisonExpression(GREATER_THAN_OR_EQUAL, node.getValue(), node.getMin()); Expression upperBound = new ComparisonExpression(LESS_THAN_OR_EQUAL, node.getValue(), node.getMax()); Expression transformed; if (isInfinite(valueStats.getLowValue())) { // We want to do heuristic cut (infinite range to finite range) ASAP and then do filtering on finite range. // We rely on 'and()' being processed left to right transformed = and(lowerBound, upperBound); } else { transformed = and(upperBound, lowerBound); } return process(transformed); }