Search in sources :

Example 1 with UnnestNode

use of com.facebook.presto.sql.planner.plan.UnnestNode in project presto by prestodb.

the class RelationPlanner method planCrossJoinUnnest.

private RelationPlan planCrossJoinUnnest(RelationPlan leftPlan, Join joinNode, Unnest node) {
    RelationType unnestOutputDescriptor = analysis.getOutputDescriptor(node);
    // Create variables for the result of unnesting
    ImmutableList.Builder<VariableReferenceExpression> unnestedVariablesBuilder = ImmutableList.builder();
    for (Field field : unnestOutputDescriptor.getVisibleFields()) {
        VariableReferenceExpression variable = variableAllocator.newVariable(field);
        unnestedVariablesBuilder.add(variable);
    }
    ImmutableList<VariableReferenceExpression> unnestedVariables = unnestedVariablesBuilder.build();
    // Add a projection for all the unnest arguments
    PlanBuilder planBuilder = initializePlanBuilder(leftPlan);
    planBuilder = planBuilder.appendProjections(node.getExpressions(), variableAllocator, idAllocator);
    TranslationMap translations = planBuilder.getTranslations();
    ProjectNode projectNode = (ProjectNode) planBuilder.getRoot();
    ImmutableMap.Builder<VariableReferenceExpression, List<VariableReferenceExpression>> unnestVariables = ImmutableMap.builder();
    UnmodifiableIterator<VariableReferenceExpression> unnestedVariablesIterator = unnestedVariables.iterator();
    for (Expression expression : node.getExpressions()) {
        Type type = analysis.getType(expression);
        VariableReferenceExpression inputVariable = new VariableReferenceExpression(getSourceLocation(expression), translations.get(expression).getName(), type);
        if (type instanceof ArrayType) {
            Type elementType = ((ArrayType) type).getElementType();
            if (!SystemSessionProperties.isLegacyUnnest(session) && elementType instanceof RowType) {
                ImmutableList.Builder<VariableReferenceExpression> unnestVariableBuilder = ImmutableList.builder();
                for (int i = 0; i < ((RowType) elementType).getFields().size(); i++) {
                    unnestVariableBuilder.add(unnestedVariablesIterator.next());
                }
                unnestVariables.put(inputVariable, unnestVariableBuilder.build());
            } else {
                unnestVariables.put(inputVariable, ImmutableList.of(unnestedVariablesIterator.next()));
            }
        } else if (type instanceof MapType) {
            unnestVariables.put(inputVariable, ImmutableList.of(unnestedVariablesIterator.next(), unnestedVariablesIterator.next()));
        } else {
            throw new IllegalArgumentException("Unsupported type for UNNEST: " + type);
        }
    }
    Optional<VariableReferenceExpression> ordinalityVariable = node.isWithOrdinality() ? Optional.of(unnestedVariablesIterator.next()) : Optional.empty();
    checkState(!unnestedVariablesIterator.hasNext(), "Not all output variables were matched with input variables");
    UnnestNode unnestNode = new UnnestNode(getSourceLocation(node), idAllocator.getNextId(), projectNode, leftPlan.getFieldMappings(), unnestVariables.build(), ordinalityVariable);
    return new RelationPlan(unnestNode, analysis.getScope(joinNode), unnestNode.getOutputVariables());
}
Also used : ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) RowType(com.facebook.presto.common.type.RowType) ImmutableMap(com.google.common.collect.ImmutableMap) MapType(com.facebook.presto.common.type.MapType) ArrayType(com.facebook.presto.common.type.ArrayType) Field(com.facebook.presto.sql.analyzer.Field) TypeUtils.isEnumType(com.facebook.presto.common.type.TypeUtils.isEnumType) ArrayType(com.facebook.presto.common.type.ArrayType) RowType(com.facebook.presto.common.type.RowType) MapType(com.facebook.presto.common.type.MapType) Type(com.facebook.presto.common.type.Type) RelationType(com.facebook.presto.sql.analyzer.RelationType) CoalesceExpression(com.facebook.presto.sql.tree.CoalesceExpression) OriginalExpressionUtils.castToRowExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) DereferenceExpression(com.facebook.presto.sql.tree.DereferenceExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) ExpressionTreeUtils.isEqualComparisonExpression(com.facebook.presto.sql.analyzer.ExpressionTreeUtils.isEqualComparisonExpression) Expression(com.facebook.presto.sql.tree.Expression) UnnestNode(com.facebook.presto.sql.planner.plan.UnnestNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RelationType(com.facebook.presto.sql.analyzer.RelationType) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Example 2 with UnnestNode

use of com.facebook.presto.sql.planner.plan.UnnestNode in project presto by prestodb.

the class ExtractSpatialJoins method addPartitioningNodes.

private static PlanNode addPartitioningNodes(Context context, FunctionAndTypeManager functionAndTypeManager, PlanNode node, VariableReferenceExpression partitionVariable, KdbTree kdbTree, RowExpression geometry, Optional<RowExpression> radius) {
    Assignments.Builder projections = Assignments.builder();
    for (VariableReferenceExpression outputVariable : node.getOutputVariables()) {
        projections.put(outputVariable, outputVariable);
    }
    FunctionHandle castFunctionHandle = functionAndTypeManager.lookupCast(CAST, VARCHAR.getTypeSignature(), KDB_TREE.getTypeSignature());
    ImmutableList.Builder partitioningArgumentsBuilder = ImmutableList.builder().add(new CallExpression(partitionVariable.getSourceLocation(), CAST.name(), castFunctionHandle, KDB_TREE, ImmutableList.of(Expressions.constant(utf8Slice(KdbTreeUtils.toJson(kdbTree)), VARCHAR)))).add(geometry);
    radius.map(partitioningArgumentsBuilder::add);
    List<RowExpression> partitioningArguments = partitioningArgumentsBuilder.build();
    String spatialPartitionsFunctionName = "spatial_partitions";
    FunctionHandle functionHandle = functionAndTypeManager.lookupFunction(spatialPartitionsFunctionName, fromTypes(partitioningArguments.stream().map(RowExpression::getType).collect(toImmutableList())));
    CallExpression partitioningFunction = new CallExpression(partitionVariable.getSourceLocation(), spatialPartitionsFunctionName, functionHandle, new ArrayType(INTEGER), partitioningArguments);
    VariableReferenceExpression partitionsVariable = context.getVariableAllocator().newVariable(partitioningFunction);
    projections.put(partitionsVariable, partitioningFunction);
    return new UnnestNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), new ProjectNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), node, projections.build(), LOCAL), node.getOutputVariables(), ImmutableMap.of(partitionsVariable, ImmutableList.of(partitionVariable)), Optional.empty());
}
Also used : ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) Assignments(com.facebook.presto.spi.plan.Assignments) RowExpression(com.facebook.presto.spi.relation.RowExpression) ArrayType(com.facebook.presto.common.type.ArrayType) UnnestNode(com.facebook.presto.sql.planner.plan.UnnestNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) SpatialJoinUtils.getFlippedFunctionHandle(com.facebook.presto.util.SpatialJoinUtils.getFlippedFunctionHandle) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) CallExpression(com.facebook.presto.spi.relation.CallExpression)

Example 3 with UnnestNode

use of com.facebook.presto.sql.planner.plan.UnnestNode in project presto by prestodb.

the class CanonicalPlanGenerator method visitUnnest.

@Override
public Optional<PlanNode> visitUnnest(UnnestNode node, Map<VariableReferenceExpression, VariableReferenceExpression> context) {
    Optional<PlanNode> source = node.getSource().accept(this, context);
    if (!source.isPresent()) {
        return Optional.empty();
    }
    // Generate canonical unnestVariables.
    ImmutableMap.Builder<VariableReferenceExpression, List<VariableReferenceExpression>> newUnnestVariables = ImmutableMap.builder();
    for (Map.Entry<VariableReferenceExpression, List<VariableReferenceExpression>> unnestVariable : node.getUnnestVariables().entrySet()) {
        VariableReferenceExpression input = (VariableReferenceExpression) inlineVariables(context, unnestVariable.getKey());
        ImmutableList.Builder<VariableReferenceExpression> newVariables = ImmutableList.builder();
        for (VariableReferenceExpression variable : unnestVariable.getValue()) {
            VariableReferenceExpression newVariable = variableAllocator.newVariable(variable.getSourceLocation(), "unnest_field", variable.getType());
            context.put(variable, newVariable);
            newVariables.add(newVariable);
        }
        newUnnestVariables.put(input, newVariables.build());
    }
    // Generate canonical ordinality variable
    Optional<VariableReferenceExpression> ordinalityVariable = node.getOrdinalityVariable().map(variable -> {
        VariableReferenceExpression newVariable = variableAllocator.newVariable(variable.getSourceLocation(), "unnest_ordinality", variable.getType());
        context.put(variable, newVariable);
        return newVariable;
    });
    return Optional.of(new UnnestNode(node.getSourceLocation(), planNodeidAllocator.getNextId(), source.get(), node.getReplicateVariables().stream().map(variable -> (VariableReferenceExpression) inlineVariables(context, variable)).collect(toImmutableList()), newUnnestVariables.build(), ordinalityVariable));
}
Also used : AggregationNode(com.facebook.presto.spi.plan.AggregationNode) GroupIdNode(com.facebook.presto.sql.planner.plan.GroupIdNode) Assignments(com.facebook.presto.spi.plan.Assignments) CanonicalPartitioningScheme.getCanonicalPartitioningScheme(com.facebook.presto.sql.planner.CanonicalPartitioningScheme.getCanonicalPartitioningScheme) GroupingSetDescriptor(com.facebook.presto.spi.plan.AggregationNode.GroupingSetDescriptor) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) HashMap(java.util.HashMap) FilterNode(com.facebook.presto.spi.plan.FilterNode) ImmutableList(com.google.common.collect.ImmutableList) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) InternalPlanVisitor(com.facebook.presto.sql.planner.plan.InternalPlanVisitor) CanonicalTableHandle.getCanonicalTableHandle(com.facebook.presto.sql.planner.CanonicalTableScanNode.CanonicalTableHandle.getCanonicalTableHandle) CallExpression(com.facebook.presto.spi.relation.CallExpression) Comparator.comparing(java.util.Comparator.comparing) OrderingScheme(com.facebook.presto.spi.plan.OrderingScheme) UnnestNode(com.facebook.presto.sql.planner.plan.UnnestNode) RowExpression(com.facebook.presto.spi.relation.RowExpression) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) ImmutableMap(com.google.common.collect.ImmutableMap) Ordering(com.facebook.presto.spi.plan.Ordering) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) RowExpressionVariableInliner.inlineVariables(com.facebook.presto.sql.planner.RowExpressionVariableInliner.inlineVariables) PlanNode(com.facebook.presto.spi.plan.PlanNode) List(java.util.List) ColumnHandle(com.facebook.presto.spi.ColumnHandle) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) INTEGER(com.facebook.presto.common.type.IntegerType.INTEGER) Aggregation(com.facebook.presto.spi.plan.AggregationNode.Aggregation) Entry(java.util.Map.Entry) Optional(java.util.Optional) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableMap(com.google.common.collect.ImmutableMap) PlanNode(com.facebook.presto.spi.plan.PlanNode) UnnestNode(com.facebook.presto.sql.planner.plan.UnnestNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 4 with UnnestNode

use of com.facebook.presto.sql.planner.plan.UnnestNode in project presto by prestodb.

the class RelationPlanner method visitUnnest.

@Override
protected RelationPlan visitUnnest(Unnest node, Void context) {
    Scope scope = analysis.getScope(node);
    ImmutableList.Builder<VariableReferenceExpression> outputVariablesBuilder = ImmutableList.builder();
    for (Field field : scope.getRelationType().getVisibleFields()) {
        VariableReferenceExpression variable = variableAllocator.newVariable(field);
        outputVariablesBuilder.add(variable);
    }
    List<VariableReferenceExpression> unnestedVariables = outputVariablesBuilder.build();
    // If we got here, then we must be unnesting a constant, and not be in a join (where there could be column references)
    ImmutableList.Builder<VariableReferenceExpression> argumentVariables = ImmutableList.builder();
    ImmutableList.Builder<RowExpression> values = ImmutableList.builder();
    ImmutableMap.Builder<VariableReferenceExpression, List<VariableReferenceExpression>> unnestVariables = ImmutableMap.builder();
    Iterator<VariableReferenceExpression> unnestedVariablesIterator = unnestedVariables.iterator();
    for (Expression expression : node.getExpressions()) {
        Type type = analysis.getType(expression);
        Expression rewritten = Coercer.addCoercions(expression, analysis);
        rewritten = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(analysis.getParameters(), analysis), rewritten);
        values.add(castToRowExpression(rewritten));
        VariableReferenceExpression input = variableAllocator.newVariable(rewritten, type);
        argumentVariables.add(new VariableReferenceExpression(getSourceLocation(rewritten), input.getName(), type));
        if (type instanceof ArrayType) {
            Type elementType = ((ArrayType) type).getElementType();
            if (!SystemSessionProperties.isLegacyUnnest(session) && elementType instanceof RowType) {
                ImmutableList.Builder<VariableReferenceExpression> unnestVariableBuilder = ImmutableList.builder();
                for (int i = 0; i < ((RowType) elementType).getFields().size(); i++) {
                    unnestVariableBuilder.add(unnestedVariablesIterator.next());
                }
                unnestVariables.put(input, unnestVariableBuilder.build());
            } else {
                unnestVariables.put(input, ImmutableList.of(unnestedVariablesIterator.next()));
            }
        } else if (type instanceof MapType) {
            unnestVariables.put(input, ImmutableList.of(unnestedVariablesIterator.next(), unnestedVariablesIterator.next()));
        } else {
            throw new IllegalArgumentException("Unsupported type for UNNEST: " + type);
        }
    }
    Optional<VariableReferenceExpression> ordinalityVariable = node.isWithOrdinality() ? Optional.of(unnestedVariablesIterator.next()) : Optional.empty();
    checkState(!unnestedVariablesIterator.hasNext(), "Not all output variables were matched with input variables");
    ValuesNode valuesNode = new ValuesNode(getSourceLocation(node), idAllocator.getNextId(), argumentVariables.build(), ImmutableList.of(values.build()));
    UnnestNode unnestNode = new UnnestNode(getSourceLocation(node), idAllocator.getNextId(), valuesNode, ImmutableList.of(), unnestVariables.build(), ordinalityVariable);
    return new RelationPlan(unnestNode, scope, unnestedVariables);
}
Also used : ValuesNode(com.facebook.presto.spi.plan.ValuesNode) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) OriginalExpressionUtils.castToRowExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) RowType(com.facebook.presto.common.type.RowType) ImmutableMap(com.google.common.collect.ImmutableMap) MapType(com.facebook.presto.common.type.MapType) ArrayType(com.facebook.presto.common.type.ArrayType) Field(com.facebook.presto.sql.analyzer.Field) TypeUtils.isEnumType(com.facebook.presto.common.type.TypeUtils.isEnumType) ArrayType(com.facebook.presto.common.type.ArrayType) RowType(com.facebook.presto.common.type.RowType) MapType(com.facebook.presto.common.type.MapType) Type(com.facebook.presto.common.type.Type) RelationType(com.facebook.presto.sql.analyzer.RelationType) Scope(com.facebook.presto.sql.analyzer.Scope) CoalesceExpression(com.facebook.presto.sql.tree.CoalesceExpression) OriginalExpressionUtils.castToRowExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RowExpression(com.facebook.presto.spi.relation.RowExpression) DereferenceExpression(com.facebook.presto.sql.tree.DereferenceExpression) ComparisonExpression(com.facebook.presto.sql.tree.ComparisonExpression) ExpressionTreeUtils.isEqualComparisonExpression(com.facebook.presto.sql.analyzer.ExpressionTreeUtils.isEqualComparisonExpression) Expression(com.facebook.presto.sql.tree.Expression) UnnestNode(com.facebook.presto.sql.planner.plan.UnnestNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Aggregations

RowExpression (com.facebook.presto.spi.relation.RowExpression)4 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)4 UnnestNode (com.facebook.presto.sql.planner.plan.UnnestNode)4 ImmutableList (com.google.common.collect.ImmutableList)4 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)4 ArrayType (com.facebook.presto.common.type.ArrayType)3 ProjectNode (com.facebook.presto.spi.plan.ProjectNode)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 List (java.util.List)3 MapType (com.facebook.presto.common.type.MapType)2 RowType (com.facebook.presto.common.type.RowType)2 Type (com.facebook.presto.common.type.Type)2 TypeUtils.isEnumType (com.facebook.presto.common.type.TypeUtils.isEnumType)2 Assignments (com.facebook.presto.spi.plan.Assignments)2 CallExpression (com.facebook.presto.spi.relation.CallExpression)2 ExpressionTreeUtils.isEqualComparisonExpression (com.facebook.presto.sql.analyzer.ExpressionTreeUtils.isEqualComparisonExpression)2 Field (com.facebook.presto.sql.analyzer.Field)2 RelationType (com.facebook.presto.sql.analyzer.RelationType)2 OriginalExpressionUtils.castToRowExpression (com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression)2 CoalesceExpression (com.facebook.presto.sql.tree.CoalesceExpression)2