Search in sources :

Example 21 with ProjectNode

use of com.facebook.presto.spi.plan.ProjectNode 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 22 with ProjectNode

use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.

the class ExtractSpatialJoins method addProjection.

private static PlanNode addProjection(Context context, PlanNode node, VariableReferenceExpression variable, RowExpression expression) {
    Assignments.Builder projections = Assignments.builder();
    for (VariableReferenceExpression outputVariable : node.getOutputVariables()) {
        projections.put(outputVariable, outputVariable);
    }
    projections.put(variable, expression);
    return new ProjectNode(node.getSourceLocation(), context.getIdAllocator().getNextId(), node, projections.build(), LOCAL);
}
Also used : VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Assignments(com.facebook.presto.spi.plan.Assignments) ProjectNode(com.facebook.presto.spi.plan.ProjectNode)

Example 23 with ProjectNode

use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.

the class EliminateEmptyJoins method apply.

@Override
public Result apply(JoinNode joinNode, Captures captures, Context context) {
    if (!isEmptyJoinOptimization(context.getSession())) {
        return Result.empty();
    }
    boolean leftChildEmpty;
    boolean rightChildEmpty;
    leftChildEmpty = isAtMost(context.getLookup().resolve(joinNode.getLeft()), context.getLookup(), 0);
    rightChildEmpty = isAtMost(context.getLookup().resolve(joinNode.getRight()), context.getLookup(), 0);
    /*
        Prune joins with one or more empty sources in the following cases. The pruning is done by replacing the whole join by empty values node.
        1. Both left and right children are empty. This works for all type of joins including outer joins.
        2. One of the left and right are empty and join is inner.
        3. Left child empty and left outer join.
        4. Right child empty and right outer join.
         */
    if ((leftChildEmpty && rightChildEmpty) || ((leftChildEmpty || rightChildEmpty) && joinNode.getType() == JoinNode.Type.INNER) || (leftChildEmpty && joinNode.getType() == JoinNode.Type.LEFT) || (rightChildEmpty && joinNode.getType() == JoinNode.Type.RIGHT)) {
        return Result.ofPlanNode(new ValuesNode(joinNode.getSourceLocation(), joinNode.getId(), joinNode.getOutputVariables(), Collections.emptyList()));
    }
    /*
        This covers the cases where the whole join can not be pruned for outer join cases.
        In this case, we optimize the join using a projection over the non-empty child.
        The follwoing are 4 scenarios:
        1. S1 left outer join S2 and S2 is empty. The join is rewritten as Projection over S1 with null values for fields of S2. For example,
           "select t1.X, dt.Y from t1 left outer (select * from t2 where 1=0) is rewritten as select t1.X, null as Y from t1
        2. S1 right outer join S2 and S1 is empty. Similiar to #1.
        3. S1 full outer join S2 and S1 is empty. This is can be reduce to S2 left outer join S1 and S1 is empty. Same logic of #1 is used.
        4. S1 full outer join S2 and S2 is empty. Similiar to #3 and full outer join is reduced to S1 left outer join S2. Same logic is #1.
         */
    if (leftChildEmpty || rightChildEmpty) {
        PlanNode nonEmptyChild;
        if (leftChildEmpty) {
            nonEmptyChild = joinNode.getRight();
        } else {
            nonEmptyChild = joinNode.getLeft();
        }
        Assignments.Builder newProjections = Assignments.builder().putAll(buildAssignments(joinNode.getOutputVariables(), nonEmptyChild));
        return Result.ofPlanNode(new ProjectNode(joinNode.getSourceLocation(), joinNode.getId(), nonEmptyChild, newProjections.build(), LOCAL));
    }
    return Result.empty();
}
Also used : ValuesNode(com.facebook.presto.spi.plan.ValuesNode) PlanNode(com.facebook.presto.spi.plan.PlanNode) Assignments(com.facebook.presto.spi.plan.Assignments) ProjectNode(com.facebook.presto.spi.plan.ProjectNode)

Example 24 with ProjectNode

use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.

the class RelationPlanner method addCoercions.

private RelationPlan addCoercions(RelationPlan plan, Type[] targetColumnTypes) {
    RelationType oldRelation = plan.getDescriptor();
    List<VariableReferenceExpression> oldVisibleVariables = oldRelation.getVisibleFields().stream().map(oldRelation::indexOf).map(plan.getFieldMappings()::get).collect(toImmutableList());
    RelationType oldRelationWithVisibleFields = plan.getDescriptor().withOnlyVisibleFields();
    verify(targetColumnTypes.length == oldVisibleVariables.size());
    ImmutableList.Builder<VariableReferenceExpression> newVariables = new ImmutableList.Builder<>();
    Field[] newFields = new Field[targetColumnTypes.length];
    Assignments.Builder assignments = Assignments.builder();
    for (int i = 0; i < targetColumnTypes.length; i++) {
        VariableReferenceExpression inputVariable = oldVisibleVariables.get(i);
        Field oldField = oldRelationWithVisibleFields.getFieldByIndex(i);
        Type outputType = targetColumnTypes[i];
        if (!outputType.equals(inputVariable.getType())) {
            Expression cast = new Cast(createSymbolReference(inputVariable), outputType.getTypeSignature().toString());
            VariableReferenceExpression outputVariable = variableAllocator.newVariable(cast, outputType);
            assignments.put(outputVariable, castToRowExpression(cast));
            newVariables.add(outputVariable);
        } else {
            SymbolReference symbolReference = new SymbolReference(oldField.getNodeLocation(), inputVariable.getName());
            VariableReferenceExpression outputVariable = variableAllocator.newVariable(symbolReference, outputType);
            assignments.put(outputVariable, castToRowExpression(symbolReference));
            newVariables.add(outputVariable);
        }
        newFields[i] = new Field(oldField.getNodeLocation(), oldField.getRelationAlias(), oldField.getName(), targetColumnTypes[i], oldField.isHidden(), oldField.getOriginTable(), oldField.getOriginColumnName(), oldField.isAliased());
    }
    ProjectNode projectNode = new ProjectNode(idAllocator.getNextId(), plan.getRoot(), assignments.build());
    return new RelationPlan(projectNode, Scope.builder().withRelationType(RelationId.anonymous(), new RelationType(newFields)).build(), newVariables.build());
}
Also used : Cast(com.facebook.presto.sql.tree.Cast) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) OriginalExpressionUtils.asSymbolReference(com.facebook.presto.sql.relational.OriginalExpressionUtils.asSymbolReference) ExpressionTreeUtils.createSymbolReference(com.facebook.presto.sql.analyzer.ExpressionTreeUtils.createSymbolReference) SymbolReference(com.facebook.presto.sql.tree.SymbolReference) Assignments(com.facebook.presto.spi.plan.Assignments) 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) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) RelationType(com.facebook.presto.sql.analyzer.RelationType) ProjectNode(com.facebook.presto.spi.plan.ProjectNode)

Example 25 with ProjectNode

use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.

the class SubqueryPlanner method appendExistSubqueryApplyNode.

/**
 * Exists is modeled as:
 * <pre>
 *     - Project($0 > 0)
 *       - Aggregation(COUNT(*))
 *         - Limit(1)
 *           -- subquery
 * </pre>
 */
private PlanBuilder appendExistSubqueryApplyNode(PlanBuilder subPlan, ExistsPredicate existsPredicate, boolean correlationAllowed) {
    if (subPlan.canTranslate(existsPredicate)) {
        // given subquery is already appended
        return subPlan;
    }
    PlanBuilder subqueryPlan = createPlanBuilder(existsPredicate.getSubquery());
    PlanNode subqueryPlanRoot = subqueryPlan.getRoot();
    if (isAggregationWithEmptyGroupBy(subqueryPlanRoot)) {
        subPlan.getTranslations().put(existsPredicate, BooleanLiteral.TRUE_LITERAL);
        return subPlan;
    }
    // add an explicit projection that removes all columns
    PlanNode subqueryNode = new ProjectNode(idAllocator.getNextId(), subqueryPlan.getRoot(), Assignments.of());
    VariableReferenceExpression exists = variableAllocator.newVariable(getSourceLocation(existsPredicate), "exists", BOOLEAN);
    subPlan.getTranslations().put(existsPredicate, exists);
    ExistsPredicate rewrittenExistsPredicate = new ExistsPredicate(BooleanLiteral.TRUE_LITERAL);
    return appendApplyNode(subPlan, existsPredicate.getSubquery(), subqueryNode, Assignments.of(exists, castToRowExpression(rewrittenExistsPredicate)), correlationAllowed);
}
Also used : PlanNode(com.facebook.presto.spi.plan.PlanNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ExistsPredicate(com.facebook.presto.sql.tree.ExistsPredicate) ProjectNode(com.facebook.presto.spi.plan.ProjectNode)

Aggregations

ProjectNode (com.facebook.presto.spi.plan.ProjectNode)53 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)41 Assignments (com.facebook.presto.spi.plan.Assignments)33 PlanNode (com.facebook.presto.spi.plan.PlanNode)23 RowExpression (com.facebook.presto.spi.relation.RowExpression)20 OriginalExpressionUtils.castToRowExpression (com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression)19 CallExpression (com.facebook.presto.spi.relation.CallExpression)16 Expression (com.facebook.presto.sql.tree.Expression)16 ImmutableList (com.google.common.collect.ImmutableList)15 AggregationNode (com.facebook.presto.spi.plan.AggregationNode)14 Map (java.util.Map)12 Test (org.testng.annotations.Test)12 FilterNode (com.facebook.presto.spi.plan.FilterNode)11 ImmutableMap (com.google.common.collect.ImmutableMap)11 Cast (com.facebook.presto.sql.tree.Cast)10 SymbolReference (com.facebook.presto.sql.tree.SymbolReference)10 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)8 List (java.util.List)8 Type (com.facebook.presto.common.type.Type)7 Set (java.util.Set)7