use of io.trino.sql.planner.TypeProvider in project trino by trinodb.
the class JoinStatsRule method filterByEquiJoinClauses.
private PlanNodeStatsEstimate filterByEquiJoinClauses(PlanNodeStatsEstimate stats, Collection<EquiJoinClause> clauses, Session session, TypeProvider types) {
checkArgument(!clauses.isEmpty(), "clauses is empty");
// Join equality clauses are usually correlated. Therefore, we shouldn't treat each join equality
// clause separately because stats estimates would be way off.
List<PlanNodeStatsEstimateWithClause> knownEstimates = clauses.stream().map(clause -> {
ComparisonExpression predicate = new ComparisonExpression(EQUAL, clause.getLeft().toSymbolReference(), clause.getRight().toSymbolReference());
return new PlanNodeStatsEstimateWithClause(filterStatsCalculator.filterStats(stats, predicate, session, types), clause);
}).collect(toImmutableList());
double outputRowCount = estimateCorrelatedConjunctionRowCount(stats, knownEstimates.stream().map(PlanNodeStatsEstimateWithClause::getEstimate).collect(toImmutableList()), getJoinMultiClauseIndependenceFactor(session));
if (isNaN(outputRowCount)) {
return PlanNodeStatsEstimate.unknown();
}
return normalizer.normalize(new PlanNodeStatsEstimate(outputRowCount, intersectCorrelatedJoinClause(stats, knownEstimates)), types);
}
use of io.trino.sql.planner.TypeProvider in project trino by trinodb.
the class StatsNormalizer method normalize.
private PlanNodeStatsEstimate normalize(PlanNodeStatsEstimate stats, Optional<Collection<Symbol>> outputSymbols, TypeProvider types) {
if (stats.isOutputRowCountUnknown()) {
return PlanNodeStatsEstimate.unknown();
}
PlanNodeStatsEstimate.Builder normalized = PlanNodeStatsEstimate.buildFrom(stats);
Predicate<Symbol> symbolFilter = outputSymbols.map(ImmutableSet::copyOf).map(set -> (Predicate<Symbol>) set::contains).orElse(symbol -> true);
for (Symbol symbol : stats.getSymbolsWithKnownStatistics()) {
if (!symbolFilter.test(symbol)) {
normalized.removeSymbolStatistics(symbol);
continue;
}
SymbolStatsEstimate symbolStats = stats.getSymbolStatistics(symbol);
SymbolStatsEstimate normalizedSymbolStats = stats.getOutputRowCount() == 0 ? SymbolStatsEstimate.zero() : normalizeSymbolStats(symbol, symbolStats, stats, types);
if (normalizedSymbolStats.isUnknown()) {
normalized.removeSymbolStatistics(symbol);
continue;
}
if (!Objects.equals(normalizedSymbolStats, symbolStats)) {
normalized.addSymbolStatistics(symbol, normalizedSymbolStats);
}
}
return normalized.build();
}
use of io.trino.sql.planner.TypeProvider in project trino by trinodb.
the class PropertyDerivations method deriveProperties.
public static ActualProperties deriveProperties(PlanNode node, List<ActualProperties> inputProperties, PlannerContext plannerContext, Session session, TypeProvider types, TypeAnalyzer typeAnalyzer) {
ActualProperties output = node.accept(new Visitor(plannerContext, session, types, typeAnalyzer), inputProperties);
output.getNodePartitioning().ifPresent(partitioning -> verify(node.getOutputSymbols().containsAll(partitioning.getColumns()), "Node-level partitioning properties contain columns not present in node's output"));
verify(node.getOutputSymbols().containsAll(output.getConstants().keySet()), "Node-level constant properties contain columns not present in node's output");
Set<Symbol> localPropertyColumns = output.getLocalProperties().stream().flatMap(property -> property.getColumns().stream()).collect(Collectors.toSet());
verify(node.getOutputSymbols().containsAll(localPropertyColumns), "Node-level local properties contain columns not present in node's output");
return output;
}
use of io.trino.sql.planner.TypeProvider in project trino by trinodb.
the class PushdownFilterIntoRowNumber method apply.
@Override
public Result apply(FilterNode node, Captures captures, Context context) {
Session session = context.getSession();
TypeProvider types = context.getSymbolAllocator().getTypes();
DomainTranslator.ExtractionResult extractionResult = DomainTranslator.getExtractionResult(plannerContext, session, node.getPredicate(), types);
TupleDomain<Symbol> tupleDomain = extractionResult.getTupleDomain();
RowNumberNode source = captures.get(CHILD);
Symbol rowNumberSymbol = source.getRowNumberSymbol();
OptionalInt upperBound = extractUpperBound(tupleDomain, rowNumberSymbol);
if (upperBound.isEmpty()) {
return Result.empty();
}
if (upperBound.getAsInt() <= 0) {
return Result.ofPlanNode(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
}
RowNumberNode merged = mergeLimit(source, upperBound.getAsInt());
boolean needRewriteSource = !merged.getMaxRowCountPerPartition().equals(source.getMaxRowCountPerPartition());
if (needRewriteSource) {
source = merged;
}
if (!allRowNumberValuesInDomain(tupleDomain, rowNumberSymbol, source.getMaxRowCountPerPartition().get())) {
if (needRewriteSource) {
return Result.ofPlanNode(new FilterNode(node.getId(), source, node.getPredicate()));
} else {
return Result.empty();
}
}
TupleDomain<Symbol> newTupleDomain = tupleDomain.filter((symbol, domain) -> !symbol.equals(rowNumberSymbol));
Expression newPredicate = ExpressionUtils.combineConjuncts(plannerContext.getMetadata(), extractionResult.getRemainingExpression(), new DomainTranslator(plannerContext).toPredicate(session, newTupleDomain));
if (newPredicate.equals(BooleanLiteral.TRUE_LITERAL)) {
return Result.ofPlanNode(source);
}
if (!newPredicate.equals(node.getPredicate())) {
return Result.ofPlanNode(new FilterNode(node.getId(), source, newPredicate));
}
return Result.empty();
}
use of io.trino.sql.planner.TypeProvider in project trino by trinodb.
the class TestCostCalculator method calculateCost.
private PlanCostEstimate calculateCost(PlanNode node, CostCalculator costCalculator, StatsCalculator statsCalculator, Map<String, Type> types) {
TypeProvider typeProvider = TypeProvider.copyOf(types.entrySet().stream().collect(toImmutableMap(entry -> new Symbol(entry.getKey()), Map.Entry::getValue)));
StatsProvider statsProvider = new CachingStatsProvider(statsCalculator, session, typeProvider);
CostProvider costProvider = new CachingCostProvider(costCalculator, statsProvider, Optional.empty(), session, typeProvider);
return costProvider.getCost(node);
}
Aggregations