Search in sources :

Example 16 with Aggregation

use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.

the class PruneOrderByInAggregation method apply.

@Override
public Result apply(AggregationNode node, Captures captures, Context context) {
    if (!node.hasOrderings()) {
        return Result.empty();
    }
    boolean anyRewritten = false;
    ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder();
    for (Map.Entry<Symbol, Aggregation> entry : node.getAggregations().entrySet()) {
        Aggregation aggregation = entry.getValue();
        if (aggregation.getOrderingScheme().isEmpty()) {
            aggregations.put(entry);
        } else // getAggregateFunctionImplementation can be expensive, so check it last.
        if (metadata.getAggregationFunctionMetadata(aggregation.getResolvedFunction()).isOrderSensitive()) {
            aggregations.put(entry);
        } else {
            anyRewritten = true;
            aggregations.put(entry.getKey(), new Aggregation(aggregation.getResolvedFunction(), aggregation.getArguments(), aggregation.isDistinct(), aggregation.getFilter(), Optional.empty(), aggregation.getMask()));
        }
    }
    if (!anyRewritten) {
        return Result.empty();
    }
    return Result.ofPlanNode(new AggregationNode(node.getId(), node.getSource(), aggregations.buildOrThrow(), node.getGroupingSets(), node.getPreGroupedSymbols(), node.getStep(), node.getHashSymbol(), node.getGroupIdSymbol()));
}
Also used : Aggregation(io.trino.sql.planner.plan.AggregationNode.Aggregation) Symbol(io.trino.sql.planner.Symbol) AggregationNode(io.trino.sql.planner.plan.AggregationNode) ImmutableMap(com.google.common.collect.ImmutableMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 17 with Aggregation

use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.

the class TransformExistsApplyToCorrelatedJoin method rewriteToDefaultAggregation.

private PlanNode rewriteToDefaultAggregation(ApplyNode applyNode, Context context) {
    ResolvedFunction countFunction = plannerContext.getMetadata().resolveFunction(context.getSession(), COUNT, ImmutableList.of());
    Symbol count = context.getSymbolAllocator().newSymbol(COUNT.toString(), BIGINT);
    Symbol exists = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols());
    return new CorrelatedJoinNode(applyNode.getId(), applyNode.getInput(), new ProjectNode(context.getIdAllocator().getNextId(), new AggregationNode(context.getIdAllocator().getNextId(), applyNode.getSubquery(), ImmutableMap.of(count, new Aggregation(countFunction, ImmutableList.of(), false, Optional.empty(), Optional.empty(), Optional.empty())), globalAggregation(), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty()), Assignments.of(exists, new ComparisonExpression(GREATER_THAN, count.toSymbolReference(), new Cast(new LongLiteral("0"), toSqlType(BIGINT))))), applyNode.getCorrelation(), INNER, TRUE_LITERAL, applyNode.getOriginSubquery());
}
Also used : Aggregation(io.trino.sql.planner.plan.AggregationNode.Aggregation) AggregationNode.globalAggregation(io.trino.sql.planner.plan.AggregationNode.globalAggregation) Cast(io.trino.sql.tree.Cast) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) LongLiteral(io.trino.sql.tree.LongLiteral) ResolvedFunction(io.trino.metadata.ResolvedFunction) Symbol(io.trino.sql.planner.Symbol) CorrelatedJoinNode(io.trino.sql.planner.plan.CorrelatedJoinNode) ProjectNode(io.trino.sql.planner.plan.ProjectNode) AggregationNode(io.trino.sql.planner.plan.AggregationNode)

Example 18 with Aggregation

use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.

the class TransformCorrelatedGlobalAggregationWithoutProjection method apply.

@Override
public Result apply(CorrelatedJoinNode correlatedJoinNode, Captures captures, Context context) {
    checkArgument(correlatedJoinNode.getType() == INNER || correlatedJoinNode.getType() == LEFT, "unexpected correlated join type: " + correlatedJoinNode.getType());
    // if there is another aggregation below the AggregationNode, handle both
    PlanNode source = captures.get(SOURCE);
    AggregationNode distinct = null;
    if (isDistinctOperator(source)) {
        distinct = (AggregationNode) source;
        source = distinct.getSource();
    }
    // decorrelate nested plan
    PlanNodeDecorrelator decorrelator = new PlanNodeDecorrelator(plannerContext, context.getSymbolAllocator(), context.getLookup());
    Optional<PlanNodeDecorrelator.DecorrelatedNode> decorrelatedSource = decorrelator.decorrelateFilters(source, correlatedJoinNode.getCorrelation());
    if (decorrelatedSource.isEmpty()) {
        return Result.empty();
    }
    source = decorrelatedSource.get().getNode();
    // append non-null symbol on nested plan. It will be used to restore semantics of null-sensitive aggregations after LEFT join
    Symbol nonNull = context.getSymbolAllocator().newSymbol("non_null", BOOLEAN);
    source = new ProjectNode(context.getIdAllocator().getNextId(), source, Assignments.builder().putIdentities(source.getOutputSymbols()).put(nonNull, TRUE_LITERAL).build());
    // assign unique id on correlated join's input. It will be used to distinguish between original input rows after join
    PlanNode inputWithUniqueId = new AssignUniqueId(context.getIdAllocator().getNextId(), correlatedJoinNode.getInput(), context.getSymbolAllocator().newSymbol("unique", BIGINT));
    JoinNode join = new JoinNode(context.getIdAllocator().getNextId(), JoinNode.Type.LEFT, inputWithUniqueId, source, ImmutableList.of(), inputWithUniqueId.getOutputSymbols(), source.getOutputSymbols(), false, decorrelatedSource.get().getCorrelatedPredicates(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of(), Optional.empty());
    PlanNode root = join;
    // restore distinct aggregation
    if (distinct != null) {
        root = new AggregationNode(distinct.getId(), join, distinct.getAggregations(), singleGroupingSet(ImmutableList.<Symbol>builder().addAll(join.getLeftOutputSymbols()).add(nonNull).addAll(distinct.getGroupingKeys()).build()), ImmutableList.of(), distinct.getStep(), Optional.empty(), Optional.empty());
    }
    // prepare mask symbols for aggregations
    // Every original aggregation agg() will be rewritten to agg() mask(non_null). If the aggregation
    // already has a mask, it will be replaced with conjunction of the existing mask and non_null.
    // This is necessary to restore the original aggregation result in case when:
    // - the nested lateral subquery returned empty result for some input row,
    // - aggregation is null-sensitive, which means that its result over a single null row is different
    // than result for empty input (with global grouping)
    // It applies to the following aggregate functions: count(*), checksum(), array_agg().
    AggregationNode globalAggregation = captures.get(AGGREGATION);
    ImmutableMap.Builder<Symbol, Symbol> masks = ImmutableMap.builder();
    Assignments.Builder assignmentsBuilder = Assignments.builder();
    for (Map.Entry<Symbol, Aggregation> entry : globalAggregation.getAggregations().entrySet()) {
        Aggregation aggregation = entry.getValue();
        if (aggregation.getMask().isPresent()) {
            Symbol newMask = context.getSymbolAllocator().newSymbol("mask", BOOLEAN);
            Expression expression = and(aggregation.getMask().get().toSymbolReference(), nonNull.toSymbolReference());
            assignmentsBuilder.put(newMask, expression);
            masks.put(entry.getKey(), newMask);
        } else {
            masks.put(entry.getKey(), nonNull);
        }
    }
    Assignments maskAssignments = assignmentsBuilder.build();
    if (!maskAssignments.isEmpty()) {
        root = new ProjectNode(context.getIdAllocator().getNextId(), root, Assignments.builder().putIdentities(root.getOutputSymbols()).putAll(maskAssignments).build());
    }
    // restore global aggregation
    globalAggregation = new AggregationNode(globalAggregation.getId(), root, rewriteWithMasks(globalAggregation.getAggregations(), masks.buildOrThrow()), singleGroupingSet(ImmutableList.<Symbol>builder().addAll(join.getLeftOutputSymbols()).addAll(globalAggregation.getGroupingKeys()).build()), ImmutableList.of(), globalAggregation.getStep(), Optional.empty(), Optional.empty());
    // restrict outputs
    Optional<PlanNode> project = restrictOutputs(context.getIdAllocator(), globalAggregation, ImmutableSet.copyOf(correlatedJoinNode.getOutputSymbols()));
    return Result.ofPlanNode(project.orElse(globalAggregation));
}
Also used : Symbol(io.trino.sql.planner.Symbol) CorrelatedJoinNode(io.trino.sql.planner.plan.CorrelatedJoinNode) JoinNode(io.trino.sql.planner.plan.JoinNode) Assignments(io.trino.sql.planner.plan.Assignments) AggregationNode(io.trino.sql.planner.plan.AggregationNode) ImmutableMap(com.google.common.collect.ImmutableMap) Aggregation(io.trino.sql.planner.plan.AggregationNode.Aggregation) PlanNodeDecorrelator(io.trino.sql.planner.optimizations.PlanNodeDecorrelator) PlanNode(io.trino.sql.planner.plan.PlanNode) AssignUniqueId(io.trino.sql.planner.plan.AssignUniqueId) Expression(io.trino.sql.tree.Expression) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 19 with Aggregation

use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.

the class AggregationFunctionMatcher method getAssignedSymbol.

@Override
public Optional<Symbol> getAssignedSymbol(PlanNode node, Session session, Metadata metadata, SymbolAliases symbolAliases) {
    Optional<Symbol> result = Optional.empty();
    if (!(node instanceof AggregationNode)) {
        return result;
    }
    AggregationNode aggregationNode = (AggregationNode) node;
    FunctionCall expectedCall = callMaker.getExpectedValue(symbolAliases);
    for (Map.Entry<Symbol, Aggregation> assignment : aggregationNode.getAggregations().entrySet()) {
        Aggregation aggregation = assignment.getValue();
        if (aggregationMatches(aggregation, expectedCall)) {
            checkState(result.isEmpty(), "Ambiguous function calls in %s", aggregationNode);
            result = Optional.of(assignment.getKey());
        }
    }
    return result;
}
Also used : Aggregation(io.trino.sql.planner.plan.AggregationNode.Aggregation) Symbol(io.trino.sql.planner.Symbol) AggregationNode(io.trino.sql.planner.plan.AggregationNode) FunctionCall(io.trino.sql.tree.FunctionCall) Map(java.util.Map)

Example 20 with Aggregation

use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.

the class QueryPlanner method planAggregation.

private PlanBuilder planAggregation(PlanBuilder subPlan, List<List<Symbol>> groupingSets, Optional<Symbol> groupIdSymbol, List<FunctionCall> aggregates, Function<Expression, Symbol> coercions) {
    ImmutableList.Builder<AggregationAssignment> aggregateMappingBuilder = ImmutableList.builder();
    // deduplicate based on scope-aware equality
    for (FunctionCall function : scopeAwareDistinct(subPlan, aggregates)) {
        Symbol symbol = symbolAllocator.newSymbol(function, analysis.getType(function));
        // TODO: for ORDER BY arguments, rewrite them such that they match the actual arguments to the function. This is necessary to maintain the semantics of DISTINCT + ORDER BY,
        // which requires that ORDER BY be a subset of arguments
        // What can happen currently is that if the argument requires a coercion, the argument will take a different input that the ORDER BY clause, which is undefined behavior
        Aggregation aggregation = new Aggregation(analysis.getResolvedFunction(function), function.getArguments().stream().map(argument -> {
            if (argument instanceof LambdaExpression) {
                return subPlan.rewrite(argument);
            }
            return coercions.apply(argument).toSymbolReference();
        }).collect(toImmutableList()), function.isDistinct(), function.getFilter().map(coercions), function.getOrderBy().map(orderBy -> translateOrderingScheme(orderBy.getSortItems(), coercions)), Optional.empty());
        aggregateMappingBuilder.add(new AggregationAssignment(symbol, function, aggregation));
    }
    List<AggregationAssignment> aggregateMappings = aggregateMappingBuilder.build();
    ImmutableSet.Builder<Integer> globalGroupingSets = ImmutableSet.builder();
    for (int i = 0; i < groupingSets.size(); i++) {
        if (groupingSets.get(i).isEmpty()) {
            globalGroupingSets.add(i);
        }
    }
    ImmutableList.Builder<Symbol> groupingKeys = ImmutableList.builder();
    groupingSets.stream().flatMap(List::stream).distinct().forEach(groupingKeys::add);
    groupIdSymbol.ifPresent(groupingKeys::add);
    AggregationNode aggregationNode = new AggregationNode(idAllocator.getNextId(), subPlan.getRoot(), aggregateMappings.stream().collect(toImmutableMap(AggregationAssignment::getSymbol, AggregationAssignment::getRewritten)), groupingSets(groupingKeys.build(), groupingSets.size(), globalGroupingSets.build()), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), groupIdSymbol);
    return new PlanBuilder(subPlan.getTranslations().withAdditionalMappings(aggregateMappings.stream().collect(toImmutableMap(assignment -> scopeAwareKey(assignment.getAstExpression(), analysis, subPlan.getScope()), AggregationAssignment::getSymbol))), aggregationNode);
}
Also used : PatternRecognitionComponents(io.trino.sql.planner.RelationPlanner.PatternRecognitionComponents) Arrays(java.util.Arrays) TypeSignatureProvider.fromTypes(io.trino.sql.analyzer.TypeSignatureProvider.fromTypes) Delete(io.trino.sql.tree.Delete) PlanNode(io.trino.sql.planner.plan.PlanNode) Node(io.trino.sql.tree.Node) Offset(io.trino.sql.tree.Offset) PlanNodeId(io.trino.sql.planner.plan.PlanNodeId) LongLiteral(io.trino.sql.tree.LongLiteral) Map(java.util.Map) Union(io.trino.sql.tree.Union) FetchFirst(io.trino.sql.tree.FetchFirst) TableScanNode(io.trino.sql.planner.plan.TableScanNode) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Assignments(io.trino.sql.planner.plan.Assignments) Set(java.util.Set) TableSchema(io.trino.metadata.TableSchema) SortItem(io.trino.sql.tree.SortItem) NodeUtils.getSortItemsFromOrderBy(io.trino.sql.NodeUtils.getSortItemsFromOrderBy) DEFAULT_FRAME(io.trino.sql.planner.plan.WindowNode.Frame.DEFAULT_FRAME) RelationType(io.trino.sql.analyzer.RelationType) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) AggregationNode.groupingSets(io.trino.sql.planner.plan.AggregationNode.groupingSets) DeleteTarget(io.trino.sql.planner.plan.TableWriterNode.DeleteTarget) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) DecimalLiteral(io.trino.sql.tree.DecimalLiteral) ValuesNode(io.trino.sql.planner.plan.ValuesNode) ExpressionAnalyzer.isNumericType(io.trino.sql.analyzer.ExpressionAnalyzer.isNumericType) Session(io.trino.Session) Iterables(com.google.common.collect.Iterables) LimitNode(io.trino.sql.planner.plan.LimitNode) TypeCoercion(io.trino.type.TypeCoercion) BOOLEAN(io.trino.spi.type.BooleanType.BOOLEAN) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) UpdateTarget(io.trino.sql.planner.plan.TableWriterNode.UpdateTarget) ScopeAware.scopeAwareKey(io.trino.sql.planner.ScopeAware.scopeAwareKey) VARCHAR(io.trino.spi.type.VarcharType.VARCHAR) NodeRef(io.trino.sql.tree.NodeRef) ColumnHandle(io.trino.spi.connector.ColumnHandle) AggregationNode(io.trino.sql.planner.plan.AggregationNode) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) VARBINARY(io.trino.spi.type.VarbinaryType.VARBINARY) GroupingOperationRewriter.rewriteGroupingOperation(io.trino.sql.planner.GroupingOperationRewriter.rewriteGroupingOperation) NodeUtils(io.trino.sql.NodeUtils) INTERVAL_DAY_TIME(io.trino.type.IntervalDayTimeType.INTERVAL_DAY_TIME) Query(io.trino.sql.tree.Query) StringLiteral(io.trino.sql.tree.StringLiteral) Relation(io.trino.sql.tree.Relation) GroupingSetAnalysis(io.trino.sql.analyzer.Analysis.GroupingSetAnalysis) Iterables.getOnlyElement(com.google.common.collect.Iterables.getOnlyElement) SortOrder(io.trino.spi.connector.SortOrder) AggregationNode.singleGroupingSet(io.trino.sql.planner.plan.AggregationNode.singleGroupingSet) TableHandle(io.trino.metadata.TableHandle) Table(io.trino.sql.tree.Table) GroupIdNode(io.trino.sql.planner.plan.GroupIdNode) YEAR(io.trino.sql.tree.IntervalLiteral.IntervalField.YEAR) OffsetNode(io.trino.sql.planner.plan.OffsetNode) ROWS(io.trino.sql.tree.WindowFrame.Type.ROWS) NullTreatment(io.trino.sql.tree.FunctionCall.NullTreatment) DAY(io.trino.sql.tree.IntervalLiteral.IntervalField.DAY) MeasureDefinition(io.trino.sql.tree.MeasureDefinition) INTERVAL_YEAR_MONTH(io.trino.type.IntervalYearMonthType.INTERVAL_YEAR_MONTH) Aggregation(io.trino.sql.planner.plan.AggregationNode.Aggregation) FilterNode(io.trino.sql.planner.plan.FilterNode) LambdaArgumentDeclaration(io.trino.sql.tree.LambdaArgumentDeclaration) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) OrderingScheme.sortItemToSortOrder(io.trino.sql.planner.OrderingScheme.sortItemToSortOrder) SelectExpression(io.trino.sql.analyzer.Analysis.SelectExpression) GROUPS(io.trino.sql.tree.WindowFrame.Type.GROUPS) DeleteNode(io.trino.sql.planner.plan.DeleteNode) Update(io.trino.sql.tree.Update) FunctionCall(io.trino.sql.tree.FunctionCall) QuerySpecification(io.trino.sql.tree.QuerySpecification) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) ResolvedFunction(io.trino.metadata.ResolvedFunction) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) IntervalLiteral(io.trino.sql.tree.IntervalLiteral) RANGE(io.trino.sql.tree.WindowFrame.Type.RANGE) VariableDefinition(io.trino.sql.tree.VariableDefinition) PatternRecognitionNode(io.trino.sql.planner.plan.PatternRecognitionNode) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) ComparisonExpression(io.trino.sql.tree.ComparisonExpression) String.format(java.lang.String.format) Preconditions.checkState(com.google.common.base.Preconditions.checkState) LESS_THAN_OR_EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.LESS_THAN_OR_EQUAL) GenericLiteral(io.trino.sql.tree.GenericLiteral) SimplePlanRewriter(io.trino.sql.planner.plan.SimplePlanRewriter) List(java.util.List) POSITIVE(io.trino.sql.tree.IntervalLiteral.Sign.POSITIVE) IfExpression(io.trino.sql.tree.IfExpression) ColumnSchema(io.trino.spi.connector.ColumnSchema) BIGINT(io.trino.spi.type.BigintType.BIGINT) WindowFrame(io.trino.sql.tree.WindowFrame) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) WindowNode(io.trino.sql.planner.plan.WindowNode) DecimalType(io.trino.spi.type.DecimalType) OrderBy(io.trino.sql.tree.OrderBy) PlannerContext(io.trino.sql.PlannerContext) Analysis(io.trino.sql.analyzer.Analysis) IntStream(java.util.stream.IntStream) FieldId(io.trino.sql.analyzer.FieldId) UnionNode(io.trino.sql.planner.plan.UnionNode) WindowOperation(io.trino.sql.tree.WindowOperation) Type(io.trino.spi.type.Type) LambdaExpression(io.trino.sql.tree.LambdaExpression) HashMap(java.util.HashMap) SystemSessionProperties.getMaxRecursionDepth(io.trino.SystemSessionProperties.getMaxRecursionDepth) SortNode(io.trino.sql.planner.plan.SortNode) Function(java.util.function.Function) Cast(io.trino.sql.tree.Cast) HashSet(java.util.HashSet) ImmutableList(com.google.common.collect.ImmutableList) Objects.requireNonNull(java.util.Objects.requireNonNull) GREATER_THAN_OR_EQUAL(io.trino.sql.tree.ComparisonExpression.Operator.GREATER_THAN_OR_EQUAL) ProjectNode(io.trino.sql.planner.plan.ProjectNode) ResolvedWindow(io.trino.sql.analyzer.Analysis.ResolvedWindow) RowsPerMatch(io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch) Iterator(java.util.Iterator) TRUE_LITERAL(io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL) UpdateNode(io.trino.sql.planner.plan.UpdateNode) QualifiedName(io.trino.sql.tree.QualifiedName) SystemSessionProperties.isSkipRedundantSort(io.trino.SystemSessionProperties.isSkipRedundantSort) FrameBound(io.trino.sql.tree.FrameBound) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) AggregationNode(io.trino.sql.planner.plan.AggregationNode) PlanBuilder.newPlanBuilder(io.trino.sql.planner.PlanBuilder.newPlanBuilder) Aggregation(io.trino.sql.planner.plan.AggregationNode.Aggregation) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) FunctionCall(io.trino.sql.tree.FunctionCall) LambdaExpression(io.trino.sql.tree.LambdaExpression)

Aggregations

Aggregation (io.trino.sql.planner.plan.AggregationNode.Aggregation)20 AggregationNode (io.trino.sql.planner.plan.AggregationNode)17 Symbol (io.trino.sql.planner.Symbol)14 Map (java.util.Map)14 ImmutableMap (com.google.common.collect.ImmutableMap)11 PlanNode (io.trino.sql.planner.plan.PlanNode)9 Expression (io.trino.sql.tree.Expression)9 ProjectNode (io.trino.sql.planner.plan.ProjectNode)7 ImmutableList (com.google.common.collect.ImmutableList)5 ResolvedFunction (io.trino.metadata.ResolvedFunction)5 Assignments (io.trino.sql.planner.plan.Assignments)5 Type (io.trino.spi.type.Type)4 CorrelatedJoinNode (io.trino.sql.planner.plan.CorrelatedJoinNode)4 ComparisonExpression (io.trino.sql.tree.ComparisonExpression)4 Test (org.testng.annotations.Test)4 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)3 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)3 ImmutableSet (com.google.common.collect.ImmutableSet)3 Session (io.trino.Session)3 Cast (io.trino.sql.tree.Cast)3