.map(inValue -> process(new ComparisonExpression(EQUAL, node.getValue(), inValue))) .collect(toImmutableList());
@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); }
private PlanNodeStatsEstimate estimateLogicalAnd(Expression left, Expression right) { // first try to estimate in the fair way PlanNodeStatsEstimate leftEstimate = process(left); if (!leftEstimate.isOutputRowCountUnknown()) { PlanNodeStatsEstimate logicalAndEstimate = new FilterExpressionStatsCalculatingVisitor(leftEstimate, session, types).process(right); if (!logicalAndEstimate.isOutputRowCountUnknown()) { return logicalAndEstimate; } } // If some of the filters cannot be estimated, take the smallest estimate. // Apply 0.9 filter factor as "unknown filter" factor. PlanNodeStatsEstimate rightEstimate = process(right); PlanNodeStatsEstimate smallestKnownEstimate; if (leftEstimate.isOutputRowCountUnknown()) { smallestKnownEstimate = rightEstimate; } else if (rightEstimate.isOutputRowCountUnknown()) { smallestKnownEstimate = leftEstimate; } else { smallestKnownEstimate = leftEstimate.getOutputRowCount() <= rightEstimate.getOutputRowCount() ? leftEstimate : rightEstimate; } if (smallestKnownEstimate.isOutputRowCountUnknown()) { return PlanNodeStatsEstimate.unknown(); } return smallestKnownEstimate.mapOutputRowCount(rowCount -> rowCount * UNKNOWN_FILTER_COEFFICIENT); }
private PlanNodeStatsEstimate estimateLogicalOr(Expression left, Expression right) { PlanNodeStatsEstimate leftEstimate = process(left); if (leftEstimate.isOutputRowCountUnknown()) { return PlanNodeStatsEstimate.unknown(); } PlanNodeStatsEstimate rightEstimate = process(right); if (rightEstimate.isOutputRowCountUnknown()) { return PlanNodeStatsEstimate.unknown(); } PlanNodeStatsEstimate andEstimate = new FilterExpressionStatsCalculatingVisitor(leftEstimate, session, types).process(right); if (andEstimate.isOutputRowCountUnknown()) { return PlanNodeStatsEstimate.unknown(); } return capStats( subtractSubsetStats( addStatsAndSumDistinctValues(leftEstimate, rightEstimate), andEstimate), input); }
public PlanNodeStatsEstimate filterStats( PlanNodeStatsEstimate statsEstimate, Expression predicate, Session session, TypeProvider types) { Expression simplifiedExpression = simplifyExpression(session, predicate, types); return new FilterExpressionStatsCalculatingVisitor(statsEstimate, session, types) .process(simplifiedExpression); }