use of io.trino.sql.planner.plan.ValuesNode in project trino by trinodb.
the class RemoveRedundantPredicateAboveTableScan method apply.
@Override
public Result apply(FilterNode filterNode, Captures captures, Context context) {
Session session = context.getSession();
TableScanNode node = captures.get(TABLE_SCAN);
Expression predicate = filterNode.getPredicate();
Expression deterministicPredicate = filterDeterministicConjuncts(plannerContext.getMetadata(), predicate);
Expression nonDeterministicPredicate = filterNonDeterministicConjuncts(plannerContext.getMetadata(), predicate);
ExtractionResult decomposedPredicate = getFullyExtractedPredicates(session, deterministicPredicate, context.getSymbolAllocator().getTypes());
if (decomposedPredicate.getTupleDomain().isAll()) {
// no conjunct could be fully converted to tuple domain
return Result.empty();
}
TupleDomain<ColumnHandle> predicateDomain = decomposedPredicate.getTupleDomain().transformKeys(node.getAssignments()::get);
if (predicateDomain.isNone()) {
// to turn the subtree into a Values node
return Result.ofPlanNode(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
}
if (node.getEnforcedConstraint().isNone()) {
// table scans with none domain should be converted to ValuesNode
return Result.ofPlanNode(new ValuesNode(node.getId(), node.getOutputSymbols(), ImmutableList.of()));
}
// is not NONE
Map<ColumnHandle, Domain> enforcedColumnDomains = node.getEnforcedConstraint().getDomains().orElseThrow();
TupleDomain<ColumnHandle> unenforcedDomain = predicateDomain.transformDomains((columnHandle, predicateColumnDomain) -> {
Type type = predicateColumnDomain.getType();
Domain enforcedColumnDomain = Optional.ofNullable(enforcedColumnDomains.get(columnHandle)).orElseGet(() -> Domain.all(type));
if (predicateColumnDomain.contains(enforcedColumnDomain)) {
// full enforced
return Domain.all(type);
}
return predicateColumnDomain.intersect(enforcedColumnDomain);
});
if (unenforcedDomain.equals(predicateDomain)) {
// no change in filter predicate
return Result.empty();
}
Map<ColumnHandle, Symbol> assignments = ImmutableBiMap.copyOf(node.getAssignments()).inverse();
Expression resultingPredicate = createResultingPredicate(plannerContext, session, context.getSymbolAllocator(), typeAnalyzer, // Dynamic filters are included in decomposedPredicate.getRemainingExpression()
TRUE_LITERAL, new DomainTranslator(plannerContext).toPredicate(session, unenforcedDomain.transformKeys(assignments::get)), nonDeterministicPredicate, decomposedPredicate.getRemainingExpression());
if (!TRUE_LITERAL.equals(resultingPredicate)) {
return Result.ofPlanNode(new FilterNode(context.getIdAllocator().getNextId(), node, resultingPredicate));
}
return Result.ofPlanNode(node);
}
use of io.trino.sql.planner.plan.ValuesNode in project trino by trinodb.
the class ReplaceJoinOverConstantWithProject method isSingleConstantRow.
private boolean isSingleConstantRow(PlanNode node) {
if (!(node instanceof ValuesNode)) {
return false;
}
ValuesNode values = (ValuesNode) node;
if (values.getRowCount() != 1) {
return false;
}
if (values.getRows().isEmpty()) {
return true;
}
Expression row = getOnlyElement(values.getRows().get());
return row instanceof Row;
}
use of io.trino.sql.planner.plan.ValuesNode in project trino by trinodb.
the class TestJoinNodeFlattener method testConvertsBushyTrees.
@Test
public void testConvertsBushyTrees() {
PlanNodeIdAllocator planNodeIdAllocator = new PlanNodeIdAllocator();
PlanBuilder p = planBuilder(planNodeIdAllocator);
Symbol a1 = p.symbol("A1");
Symbol b1 = p.symbol("B1");
Symbol c1 = p.symbol("C1");
Symbol d1 = p.symbol("D1");
Symbol d2 = p.symbol("D2");
Symbol e1 = p.symbol("E1");
Symbol e2 = p.symbol("E2");
ValuesNode valuesA = p.values(a1);
ValuesNode valuesB = p.values(b1);
ValuesNode valuesC = p.values(c1);
ValuesNode valuesD = p.values(d1, d2);
ValuesNode valuesE = p.values(e1, e2);
JoinNode joinNode = p.join(INNER, p.join(INNER, p.join(INNER, valuesA, valuesB, ImmutableList.of(equiJoinClause(a1, b1)), ImmutableList.of(a1), ImmutableList.of(b1), Optional.empty()), valuesC, ImmutableList.of(equiJoinClause(a1, c1)), ImmutableList.of(a1, b1), ImmutableList.of(c1), Optional.empty()), p.join(INNER, valuesD, valuesE, ImmutableList.of(equiJoinClause(d1, e1), equiJoinClause(d2, e2)), ImmutableList.of(d1, d2), ImmutableList.of(e1, e2), Optional.empty()), ImmutableList.of(equiJoinClause(b1, e1)), ImmutableList.of(a1, b1, c1), ImmutableList.of(d1, d2, e1, e2), Optional.empty());
MultiJoinNode expected = MultiJoinNode.builder().setSources(valuesA, valuesB, valuesC, valuesD, valuesE).setFilter(and(createEqualsExpression(a1, b1), createEqualsExpression(a1, c1), createEqualsExpression(d1, e1), createEqualsExpression(d2, e2), createEqualsExpression(b1, e1))).setOutputSymbols(a1, b1, c1, d1, d2, e1, e2).build();
assertEquals(toMultiJoinNode(queryRunner.getPlannerContext(), joinNode, noLookup(), planNodeIdAllocator, 5, false, testSessionBuilder().build(), createTestingTypeAnalyzer(queryRunner.getPlannerContext()), p.getTypes()), expected);
}
use of io.trino.sql.planner.plan.ValuesNode in project trino by trinodb.
the class TestJoinNodeFlattener method testRetainsOutputSymbols.
@Test
public void testRetainsOutputSymbols() {
PlanNodeIdAllocator planNodeIdAllocator = new PlanNodeIdAllocator();
PlanBuilder p = planBuilder(planNodeIdAllocator);
Symbol a1 = p.symbol("A1");
Symbol b1 = p.symbol("B1");
Symbol b2 = p.symbol("B2");
Symbol c1 = p.symbol("C1");
Symbol c2 = p.symbol("C2");
ValuesNode valuesA = p.values(a1);
ValuesNode valuesB = p.values(b1, b2);
ValuesNode valuesC = p.values(c1, c2);
JoinNode joinNode = p.join(INNER, valuesA, p.join(INNER, valuesB, valuesC, ImmutableList.of(equiJoinClause(b1, c1)), ImmutableList.of(b1, b2), ImmutableList.of(c1, c2), Optional.empty()), ImmutableList.of(equiJoinClause(a1, b1)), ImmutableList.of(a1), ImmutableList.of(b1), Optional.empty());
MultiJoinNode expected = MultiJoinNode.builder().setSources(valuesA, valuesB, valuesC).setFilter(and(createEqualsExpression(b1, c1), createEqualsExpression(a1, b1))).setOutputSymbols(a1, b1).build();
assertEquals(toMultiJoinNode(queryRunner.getPlannerContext(), joinNode, noLookup(), planNodeIdAllocator, DEFAULT_JOIN_LIMIT, false, testSessionBuilder().build(), createTestingTypeAnalyzer(queryRunner.getPlannerContext()), p.getTypes()), expected);
}
use of io.trino.sql.planner.plan.ValuesNode in project trino by trinodb.
the class TestJoinNodeFlattener method testDoesNotConvertNestedOuterJoins.
@Test
public void testDoesNotConvertNestedOuterJoins() {
PlanNodeIdAllocator planNodeIdAllocator = new PlanNodeIdAllocator();
PlanBuilder p = planBuilder(planNodeIdAllocator);
Symbol a1 = p.symbol("A1");
Symbol b1 = p.symbol("B1");
Symbol c1 = p.symbol("C1");
JoinNode leftJoin = p.join(LEFT, p.values(a1), p.values(b1), ImmutableList.of(equiJoinClause(a1, b1)), ImmutableList.of(a1), ImmutableList.of(b1), Optional.empty());
ValuesNode valuesC = p.values(c1);
JoinNode joinNode = p.join(INNER, leftJoin, valuesC, ImmutableList.of(equiJoinClause(a1, c1)), ImmutableList.of(a1, b1), ImmutableList.of(c1), Optional.empty());
MultiJoinNode expected = MultiJoinNode.builder().setSources(leftJoin, valuesC).setFilter(createEqualsExpression(a1, c1)).setOutputSymbols(a1, b1, c1).build();
assertEquals(toMultiJoinNode(queryRunner.getPlannerContext(), joinNode, noLookup(), planNodeIdAllocator, DEFAULT_JOIN_LIMIT, false, testSessionBuilder().build(), createTestingTypeAnalyzer(queryRunner.getPlannerContext()), p.getTypes()), expected);
}
Aggregations