Search in sources :

Example 1 with QuantifiedComparisonExpression

use of io.trino.sql.tree.QuantifiedComparisonExpression in project trino by trinodb.

the class UnwrapSingleColumnRowInApply method apply.

@Override
public Result apply(ApplyNode node, Captures captures, Context context) {
    Assignments.Builder inputAssignments = Assignments.builder().putIdentities(node.getInput().getOutputSymbols());
    Assignments.Builder nestedPlanAssignments = Assignments.builder().putIdentities(node.getSubquery().getOutputSymbols());
    boolean applied = false;
    Assignments.Builder applyAssignments = Assignments.builder();
    for (Map.Entry<Symbol, Expression> assignment : node.getSubqueryAssignments().entrySet()) {
        Symbol output = assignment.getKey();
        Expression expression = assignment.getValue();
        Optional<Unwrapping> unwrapped = Optional.empty();
        if (expression instanceof InPredicate) {
            InPredicate predicate = (InPredicate) expression;
            unwrapped = unwrapSingleColumnRow(context, predicate.getValue(), predicate.getValueList(), (value, list) -> new InPredicate(value.toSymbolReference(), list.toSymbolReference()));
        } else if (expression instanceof QuantifiedComparisonExpression) {
            QuantifiedComparisonExpression comparison = (QuantifiedComparisonExpression) expression;
            unwrapped = unwrapSingleColumnRow(context, comparison.getValue(), comparison.getSubquery(), (value, list) -> new QuantifiedComparisonExpression(comparison.getOperator(), comparison.getQuantifier(), value.toSymbolReference(), list.toSymbolReference()));
        }
        if (unwrapped.isPresent()) {
            applied = true;
            Unwrapping unwrapping = unwrapped.get();
            inputAssignments.add(unwrapping.getInputAssignment());
            nestedPlanAssignments.add(unwrapping.getNestedPlanAssignment());
            applyAssignments.put(output, unwrapping.getExpression());
        } else {
            applyAssignments.put(assignment);
        }
    }
    if (!applied) {
        return Result.empty();
    }
    return Result.ofPlanNode(new ProjectNode(context.getIdAllocator().getNextId(), new ApplyNode(node.getId(), new ProjectNode(context.getIdAllocator().getNextId(), node.getInput(), inputAssignments.build()), new ProjectNode(context.getIdAllocator().getNextId(), node.getSubquery(), nestedPlanAssignments.build()), applyAssignments.build(), node.getCorrelation(), node.getOriginSubquery()), Assignments.identity(node.getOutputSymbols())));
}
Also used : Assignment(io.trino.sql.planner.plan.Assignments.Assignment) Symbol(io.trino.sql.planner.Symbol) RowType(io.trino.spi.type.RowType) BiFunction(java.util.function.BiFunction) Type(io.trino.spi.type.Type) Assignments(io.trino.sql.planner.plan.Assignments) InPredicate(io.trino.sql.tree.InPredicate) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) Pattern(io.trino.matching.Pattern) TypeAnalyzer(io.trino.sql.planner.TypeAnalyzer) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) Captures(io.trino.matching.Captures) LongLiteral(io.trino.sql.tree.LongLiteral) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) ApplyNode(io.trino.sql.planner.plan.ApplyNode) Optional(java.util.Optional) Rule(io.trino.sql.planner.iterative.Rule) Expression(io.trino.sql.tree.Expression) Patterns.applyNode(io.trino.sql.planner.plan.Patterns.applyNode) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Symbol(io.trino.sql.planner.Symbol) ApplyNode(io.trino.sql.planner.plan.ApplyNode) Assignments(io.trino.sql.planner.plan.Assignments) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) InPredicate(io.trino.sql.tree.InPredicate) SubscriptExpression(io.trino.sql.tree.SubscriptExpression) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) Expression(io.trino.sql.tree.Expression) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Map(java.util.Map)

Example 2 with QuantifiedComparisonExpression

use of io.trino.sql.tree.QuantifiedComparisonExpression in project trino by trinodb.

the class TestSqlParser method testQuantifiedComparison.

@Test
public void testQuantifiedComparison() {
    assertExpression("col1 < ANY (SELECT col2 FROM table1)", new QuantifiedComparisonExpression(ComparisonExpression.Operator.LESS_THAN, QuantifiedComparisonExpression.Quantifier.ANY, identifier("col1"), new SubqueryExpression(simpleQuery(selectList(new SingleColumn(identifier("col2"))), table(QualifiedName.of("table1"))))));
    assertExpression("col1 = ALL (VALUES ROW(1), ROW(2))", new QuantifiedComparisonExpression(ComparisonExpression.Operator.EQUAL, QuantifiedComparisonExpression.Quantifier.ALL, identifier("col1"), new SubqueryExpression(query(values(row(new LongLiteral("1")), row(new LongLiteral("2")))))));
    assertExpression("col1 >= SOME (SELECT 10)", new QuantifiedComparisonExpression(ComparisonExpression.Operator.GREATER_THAN_OR_EQUAL, QuantifiedComparisonExpression.Quantifier.SOME, identifier("col1"), new SubqueryExpression(simpleQuery(selectList(new LongLiteral("10"))))));
}
Also used : LongLiteral(io.trino.sql.tree.LongLiteral) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) SingleColumn(io.trino.sql.tree.SingleColumn) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) Test(org.junit.jupiter.api.Test)

Example 3 with QuantifiedComparisonExpression

use of io.trino.sql.tree.QuantifiedComparisonExpression in project trino by trinodb.

the class SubqueryPlanner method planQuantifiedComparison.

private PlanBuilder planQuantifiedComparison(PlanBuilder subPlan, ComparisonExpression.Operator operator, Quantifier quantifier, Expression value, Expression subquery, Symbol assignment, Analysis.PredicateCoercions predicateCoercions) {
    PlanAndMappings subqueryPlan = planSubquery(subquery, predicateCoercions.getSubqueryCoercion(), subPlan.getTranslations());
    PlanAndMappings valuePlan = planValue(subPlan, value, predicateCoercions.getValueType(), predicateCoercions.getValueCoercion());
    return new PlanBuilder(valuePlan.getSubPlan().getTranslations(), new ApplyNode(idAllocator.getNextId(), valuePlan.getSubPlan().getRoot(), subqueryPlan.getSubPlan().getRoot(), Assignments.of(assignment, new QuantifiedComparisonExpression(operator, quantifier, valuePlan.get(value).toSymbolReference(), subqueryPlan.get(subquery).toSymbolReference())), valuePlan.getSubPlan().getRoot().getOutputSymbols(), subquery));
}
Also used : ApplyNode(io.trino.sql.planner.plan.ApplyNode) PlanAndMappings(io.trino.sql.planner.QueryPlanner.PlanAndMappings) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder)

Example 4 with QuantifiedComparisonExpression

use of io.trino.sql.tree.QuantifiedComparisonExpression in project trino by trinodb.

the class SubqueryPlanner method planQuantifiedComparison.

private PlanBuilder planQuantifiedComparison(PlanBuilder subPlan, Cluster<QuantifiedComparisonExpression> cluster, Analysis.SubqueryAnalysis subqueries) {
    // Plan one of the predicates from the cluster
    QuantifiedComparisonExpression quantifiedComparison = cluster.getRepresentative();
    ComparisonExpression.Operator operator = quantifiedComparison.getOperator();
    Quantifier quantifier = quantifiedComparison.getQuantifier();
    Expression value = quantifiedComparison.getValue();
    SubqueryExpression subquery = (SubqueryExpression) quantifiedComparison.getSubquery();
    subPlan = handleSubqueries(subPlan, value, subqueries);
    Symbol output = symbolAllocator.newSymbol(quantifiedComparison, BOOLEAN);
    Analysis.PredicateCoercions predicateCoercions = analysis.getPredicateCoercions(quantifiedComparison);
    switch(operator) {
        case EQUAL:
            switch(quantifier) {
                case ALL:
                    subPlan = planQuantifiedComparison(subPlan, operator, quantifier, value, subquery, output, predicateCoercions);
                    return new PlanBuilder(subPlan.getTranslations().withAdditionalMappings(ImmutableMap.of(scopeAwareKey(quantifiedComparison, analysis, subPlan.getScope()), output)), subPlan.getRoot());
                case ANY:
                case SOME:
                    // A = ANY B <=> A IN B
                    subPlan = planInPredicate(subPlan, value, subquery, output, quantifiedComparison, predicateCoercions);
                    return new PlanBuilder(subPlan.getTranslations().withAdditionalMappings(mapAll(cluster, subPlan.getScope(), output)), subPlan.getRoot());
            }
            break;
        case NOT_EQUAL:
            switch(quantifier) {
                case ALL:
                    {
                        // A <> ALL B <=> !(A IN B)
                        subPlan = planInPredicate(subPlan, value, subquery, output, quantifiedComparison, predicateCoercions);
                        return addNegation(subPlan, cluster, output);
                    }
                case ANY:
                case SOME:
                    {
                        // A <> ANY B <=> min B <> max B || A <> min B <=> !(min B = max B && A = min B) <=> !(A = ALL B)
                        // "A <> ANY B" is equivalent to "NOT (A = ALL B)" so add a rewrite for the initial quantifiedComparison to notAll
                        subPlan = planQuantifiedComparison(subPlan, EQUAL, Quantifier.ALL, value, subquery, output, predicateCoercions);
                        return addNegation(subPlan, cluster, output);
                    }
            }
            break;
        case LESS_THAN:
        case LESS_THAN_OR_EQUAL:
        case GREATER_THAN:
        case GREATER_THAN_OR_EQUAL:
            subPlan = planQuantifiedComparison(subPlan, operator, quantifier, value, subquery, output, predicateCoercions);
            return new PlanBuilder(subPlan.getTranslations().withAdditionalMappings(mapAll(cluster, subPlan.getScope(), output)), subPlan.getRoot());
        case IS_DISTINCT_FROM:
    }
    // all cases are checked, so this exception should never be thrown
    throw new IllegalArgumentException(format("Unexpected quantified comparison: '%s %s'", operator.getValue(), quantifier));
}
Also used : ComparisonExpression(io.trino.sql.tree.ComparisonExpression) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) Expression(io.trino.sql.tree.Expression) SubqueryExpression(io.trino.sql.tree.SubqueryExpression) NotExpression(io.trino.sql.tree.NotExpression) Analysis(io.trino.sql.analyzer.Analysis) Quantifier(io.trino.sql.tree.QuantifiedComparisonExpression.Quantifier) QuantifiedComparisonExpression(io.trino.sql.tree.QuantifiedComparisonExpression) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder) SubqueryExpression(io.trino.sql.tree.SubqueryExpression)

Aggregations

QuantifiedComparisonExpression (io.trino.sql.tree.QuantifiedComparisonExpression)4 PlanBuilder.newPlanBuilder (io.trino.sql.planner.PlanBuilder.newPlanBuilder)2 ApplyNode (io.trino.sql.planner.plan.ApplyNode)2 Expression (io.trino.sql.tree.Expression)2 LongLiteral (io.trino.sql.tree.LongLiteral)2 SubqueryExpression (io.trino.sql.tree.SubqueryExpression)2 Captures (io.trino.matching.Captures)1 Pattern (io.trino.matching.Pattern)1 RowType (io.trino.spi.type.RowType)1 Type (io.trino.spi.type.Type)1 Analysis (io.trino.sql.analyzer.Analysis)1 PlanAndMappings (io.trino.sql.planner.QueryPlanner.PlanAndMappings)1 Symbol (io.trino.sql.planner.Symbol)1 TypeAnalyzer (io.trino.sql.planner.TypeAnalyzer)1 Rule (io.trino.sql.planner.iterative.Rule)1 Assignments (io.trino.sql.planner.plan.Assignments)1 Assignment (io.trino.sql.planner.plan.Assignments.Assignment)1 Patterns.applyNode (io.trino.sql.planner.plan.Patterns.applyNode)1 ProjectNode (io.trino.sql.planner.plan.ProjectNode)1 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)1