Search in sources :

Example 1 with TableWriterNode

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

the class TestVerifyNoOriginalExpression method testTableWriter.

@Test
public void testTableWriter() {
    ImmutableList<VariableReferenceExpression> variableReferenceExpressions = ImmutableList.of(VARIABLE_REFERENCE_EXPRESSION);
    TableWriterNode tableWriterNode = builder.tableWriter(variableReferenceExpressions, ImmutableList.of(""), valuesNode);
    testValidation(tableWriterNode);
}
Also used : VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) TableWriterNode(com.facebook.presto.sql.planner.plan.TableWriterNode) BasePlanTest(com.facebook.presto.sql.planner.assertions.BasePlanTest) Test(org.testng.annotations.Test)

Example 2 with TableWriterNode

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

the class LogicalPlanner method createTableWriterPlan.

private RelationPlan createTableWriterPlan(Analysis analysis, RelationPlan plan, WriterTarget target, List<String> columnNames, List<ColumnMetadata> columnMetadataList, Optional<NewTableLayout> writeTableLayout, Optional<NewTableLayout> preferredShuffleLayout, TableStatisticsMetadata statisticsMetadata) {
    verify(!(writeTableLayout.isPresent() && preferredShuffleLayout.isPresent()), "writeTableLayout and preferredShuffleLayout cannot both exist");
    PlanNode source = plan.getRoot();
    if (!analysis.isCreateTableAsSelectWithData()) {
        source = new LimitNode(source.getSourceLocation(), idAllocator.getNextId(), source, 0L, FINAL);
    }
    List<VariableReferenceExpression> variables = plan.getFieldMappings();
    Optional<PartitioningScheme> tablePartitioningScheme = getPartitioningSchemeForTableWrite(writeTableLayout, columnNames, variables);
    Optional<PartitioningScheme> preferredShufflePartitioningScheme = getPartitioningSchemeForTableWrite(preferredShuffleLayout, columnNames, variables);
    verify(columnNames.size() == variables.size(), "columnNames.size() != variables.size(): %s and %s", columnNames, variables);
    Map<String, VariableReferenceExpression> columnToVariableMap = zip(columnNames.stream(), plan.getFieldMappings().stream(), SimpleImmutableEntry::new).collect(toImmutableMap(Entry::getKey, Entry::getValue));
    Set<VariableReferenceExpression> notNullColumnVariables = columnMetadataList.stream().filter(column -> !column.isNullable()).map(ColumnMetadata::getName).map(columnToVariableMap::get).collect(toImmutableSet());
    if (!statisticsMetadata.isEmpty()) {
        TableStatisticAggregation result = statisticsAggregationPlanner.createStatisticsAggregation(statisticsMetadata, columnToVariableMap, true);
        StatisticAggregations.Parts aggregations = result.getAggregations().splitIntoPartialAndFinal(variableAllocator, metadata.getFunctionAndTypeManager());
        TableFinishNode commitNode = new TableFinishNode(source.getSourceLocation(), idAllocator.getNextId(), new TableWriterNode(source.getSourceLocation(), idAllocator.getNextId(), source, Optional.of(target), variableAllocator.newVariable("rows", BIGINT), variableAllocator.newVariable("fragments", VARBINARY), variableAllocator.newVariable("commitcontext", VARBINARY), plan.getFieldMappings(), columnNames, notNullColumnVariables, tablePartitioningScheme, preferredShufflePartitioningScheme, // the data consumed by the TableWriteOperator
        Optional.of(aggregations.getPartialAggregation())), Optional.of(target), variableAllocator.newVariable("rows", BIGINT), // by the partial aggregation from all of the writer nodes
        Optional.of(aggregations.getFinalAggregation()), Optional.of(result.getDescriptor()));
        return new RelationPlan(commitNode, analysis.getRootScope(), commitNode.getOutputVariables());
    }
    TableFinishNode commitNode = new TableFinishNode(source.getSourceLocation(), idAllocator.getNextId(), new TableWriterNode(source.getSourceLocation(), idAllocator.getNextId(), source, Optional.of(target), variableAllocator.newVariable("rows", BIGINT), variableAllocator.newVariable("fragments", VARBINARY), variableAllocator.newVariable("commitcontext", VARBINARY), plan.getFieldMappings(), columnNames, notNullColumnVariables, tablePartitioningScheme, preferredShufflePartitioningScheme, Optional.empty()), Optional.of(target), variableAllocator.newVariable("rows", BIGINT), Optional.empty(), Optional.empty());
    return new RelationPlan(commitNode, analysis.getRootScope(), commitNode.getOutputVariables());
}
Also used : WarningCollector(com.facebook.presto.spi.WarningCollector) FINAL(com.facebook.presto.spi.plan.LimitNode.Step.FINAL) NOT_FOUND(com.facebook.presto.spi.StandardErrorCode.NOT_FOUND) Analyze(com.facebook.presto.sql.tree.Analyze) Field(com.facebook.presto.sql.analyzer.Field) CachingStatsProvider(com.facebook.presto.cost.CachingStatsProvider) ValuesNode(com.facebook.presto.spi.plan.ValuesNode) TableStatisticAggregation(com.facebook.presto.sql.planner.StatisticsAggregationPlanner.TableStatisticAggregation) Delete(com.facebook.presto.sql.tree.Delete) Map(java.util.Map) QualifiedObjectName(com.facebook.presto.common.QualifiedObjectName) AggregationNode.singleGroupingSet(com.facebook.presto.spi.plan.AggregationNode.singleGroupingSet) Query(com.facebook.presto.sql.tree.Query) Explain(com.facebook.presto.sql.tree.Explain) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) LimitNode(com.facebook.presto.spi.plan.LimitNode) NullLiteral(com.facebook.presto.sql.tree.NullLiteral) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) DeleteHandle(com.facebook.presto.sql.planner.plan.TableWriterNode.DeleteHandle) ExpressionTreeUtils.getSourceLocation(com.facebook.presto.sql.analyzer.ExpressionTreeUtils.getSourceLocation) TableStatisticsMetadata(com.facebook.presto.spi.statistics.TableStatisticsMetadata) SystemSessionProperties(com.facebook.presto.SystemSessionProperties) PlanOptimizer(com.facebook.presto.sql.planner.optimizations.PlanOptimizer) LambdaArgumentDeclaration(com.facebook.presto.sql.tree.LambdaArgumentDeclaration) SystemSessionProperties.isPrintStatsForNonJoinQuery(com.facebook.presto.SystemSessionProperties.isPrintStatsForNonJoinQuery) NewTableLayout(com.facebook.presto.metadata.NewTableLayout) Assignments(com.facebook.presto.spi.plan.Assignments) ArrayList(java.util.ArrayList) Identifier(com.facebook.presto.sql.tree.Identifier) LinkedHashMap(java.util.LinkedHashMap) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) TableHandle(com.facebook.presto.spi.TableHandle) Cast(com.facebook.presto.sql.tree.Cast) ConnectorTableMetadata(com.facebook.presto.spi.ConnectorTableMetadata) BIGINT(com.facebook.presto.common.type.BigintType.BIGINT) MetadataUtil.toSchemaTableName(com.facebook.presto.metadata.MetadataUtil.toSchemaTableName) PlanNodeIdAllocator(com.facebook.presto.spi.plan.PlanNodeIdAllocator) Session(com.facebook.presto.Session) InsertReference(com.facebook.presto.sql.planner.plan.TableWriterNode.InsertReference) StatsProvider(com.facebook.presto.cost.StatsProvider) RefreshMaterializedViewReference(com.facebook.presto.sql.planner.plan.TableWriterNode.RefreshMaterializedViewReference) NodeRef(com.facebook.presto.sql.tree.NodeRef) Scope(com.facebook.presto.sql.analyzer.Scope) ColumnHandle(com.facebook.presto.spi.ColumnHandle) TableScanNode(com.facebook.presto.spi.plan.TableScanNode) SemiJoinNode(com.facebook.presto.sql.planner.plan.SemiJoinNode) Metadata(com.facebook.presto.metadata.Metadata) ExpressionTreeUtils.createSymbolReference(com.facebook.presto.sql.analyzer.ExpressionTreeUtils.createSymbolReference) OriginalExpressionUtils.castToRowExpression(com.facebook.presto.sql.relational.OriginalExpressionUtils.castToRowExpression) TableMetadata(com.facebook.presto.metadata.TableMetadata) AggregationNode(com.facebook.presto.spi.plan.AggregationNode) ExplainAnalyzeNode(com.facebook.presto.sql.planner.plan.ExplainAnalyzeNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) TableWriterNode(com.facebook.presto.sql.planner.plan.TableWriterNode) Expressions.constant(com.facebook.presto.sql.relational.Expressions.constant) StatsCalculator(com.facebook.presto.cost.StatsCalculator) StatisticAggregations(com.facebook.presto.sql.planner.plan.StatisticAggregations) RefreshMaterializedView(com.facebook.presto.sql.tree.RefreshMaterializedView) CostProvider(com.facebook.presto.cost.CostProvider) OutputNode(com.facebook.presto.sql.planner.plan.OutputNode) RelationId(com.facebook.presto.sql.analyzer.RelationId) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) CostCalculator(com.facebook.presto.cost.CostCalculator) String.format(java.lang.String.format) SqlParser(com.facebook.presto.sql.parser.SqlParser) Preconditions.checkState(com.google.common.base.Preconditions.checkState) List(java.util.List) ColumnMetadata(com.facebook.presto.spi.ColumnMetadata) NOT_SUPPORTED(com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED) Entry(java.util.Map.Entry) Analysis(com.facebook.presto.sql.analyzer.Analysis) Optional(java.util.Optional) ConnectorId(com.facebook.presto.spi.ConnectorId) CachingCostProvider(com.facebook.presto.cost.CachingCostProvider) WriterTarget(com.facebook.presto.sql.planner.plan.TableWriterNode.WriterTarget) PrestoException(com.facebook.presto.spi.PrestoException) SimpleImmutableEntry(java.util.AbstractMap.SimpleImmutableEntry) ImmutableList(com.google.common.collect.ImmutableList) PlanChecker(com.facebook.presto.sql.planner.sanity.PlanChecker) Verify.verify(com.google.common.base.Verify.verify) Objects.requireNonNull(java.util.Objects.requireNonNull) Type(com.facebook.presto.common.type.Type) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) CreateTableAsSelect(com.facebook.presto.sql.tree.CreateTableAsSelect) ROW_COUNT(com.facebook.presto.spi.statistics.TableStatisticType.ROW_COUNT) PlanNodeSearcher(com.facebook.presto.sql.planner.optimizations.PlanNodeSearcher) RelationType(com.facebook.presto.sql.analyzer.RelationType) VARBINARY(com.facebook.presto.common.type.VarbinaryType.VARBINARY) TupleDomain(com.facebook.presto.common.predicate.TupleDomain) DeleteNode(com.facebook.presto.sql.planner.plan.DeleteNode) Insert(com.facebook.presto.sql.tree.Insert) PlanNode(com.facebook.presto.spi.plan.PlanNode) Expression(com.facebook.presto.sql.tree.Expression) CreateName(com.facebook.presto.sql.planner.plan.TableWriterNode.CreateName) StatsAndCosts(com.facebook.presto.cost.StatsAndCosts) TableFinishNode(com.facebook.presto.sql.planner.plan.TableFinishNode) Streams.zip(com.google.common.collect.Streams.zip) StatisticsWriterNode(com.facebook.presto.sql.planner.plan.StatisticsWriterNode) Statement(com.facebook.presto.sql.tree.Statement) ColumnMetadata(com.facebook.presto.spi.ColumnMetadata) TableStatisticAggregation(com.facebook.presto.sql.planner.StatisticsAggregationPlanner.TableStatisticAggregation) TableFinishNode(com.facebook.presto.sql.planner.plan.TableFinishNode) StatisticAggregations(com.facebook.presto.sql.planner.plan.StatisticAggregations) PlanNode(com.facebook.presto.spi.plan.PlanNode) LimitNode(com.facebook.presto.spi.plan.LimitNode) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) TableWriterNode(com.facebook.presto.sql.planner.plan.TableWriterNode)

Example 3 with TableWriterNode

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

the class TableWriterMatcher method detailMatches.

@Override
public MatchResult detailMatches(PlanNode node, StatsProvider stats, Session session, Metadata metadata, SymbolAliases symbolAliases) {
    checkState(shapeMatches(node), "Plan testing framework error: shapeMatches returned false in detailMatches in %s", this.getClass().getName());
    TableWriterNode tableWriterNode = (TableWriterNode) node;
    if (!tableWriterNode.getColumnNames().equals(columnNames)) {
        return NO_MATCH;
    }
    if (!columns.stream().map(s -> Symbol.from(symbolAliases.get(s))).collect(toImmutableList()).equals(tableWriterNode.getColumns().stream().map(VariableReferenceExpression::getName).map(Symbol::new).collect(toImmutableList()))) {
        return NO_MATCH;
    }
    return match();
}
Also used : Session(com.facebook.presto.Session) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) StatsProvider(com.facebook.presto.cost.StatsProvider) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) TableWriterNode(com.facebook.presto.sql.planner.plan.TableWriterNode) Preconditions.checkState(com.google.common.base.Preconditions.checkState) PlanNode(com.facebook.presto.spi.plan.PlanNode) List(java.util.List) Symbol(com.facebook.presto.sql.planner.Symbol) MatchResult.match(com.facebook.presto.sql.planner.assertions.MatchResult.match) NO_MATCH(com.facebook.presto.sql.planner.assertions.MatchResult.NO_MATCH) Metadata(com.facebook.presto.metadata.Metadata) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) TableWriterNode(com.facebook.presto.sql.planner.plan.TableWriterNode)

Example 4 with TableWriterNode

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

the class LogicalPlanner method createTableWriterPlan.

private RelationPlan createTableWriterPlan(Analysis analysis, RelationPlan plan, WriterTarget target, List<String> columnNames, Optional<NewTableLayout> writeTableLayout) {
    List<Symbol> writerOutputs = ImmutableList.of(symbolAllocator.newSymbol("partialrows", BIGINT), symbolAllocator.newSymbol("fragment", VARBINARY));
    PlanNode source = plan.getRoot();
    if (!analysis.isCreateTableAsSelectWithData()) {
        source = new LimitNode(idAllocator.getNextId(), source, 0L, false);
    }
    // todo this should be checked in analysis
    writeTableLayout.ifPresent(layout -> {
        if (!ImmutableSet.copyOf(columnNames).containsAll(layout.getPartitionColumns())) {
            throw new PrestoException(NOT_SUPPORTED, "INSERT must write all distribution columns: " + layout.getPartitionColumns());
        }
    });
    List<Symbol> symbols = plan.getFieldMappings();
    Optional<PartitioningScheme> partitioningScheme = Optional.empty();
    if (writeTableLayout.isPresent()) {
        List<Symbol> partitionFunctionArguments = new ArrayList<>();
        writeTableLayout.get().getPartitionColumns().stream().mapToInt(columnNames::indexOf).mapToObj(symbols::get).forEach(partitionFunctionArguments::add);
        List<Symbol> outputLayout = new ArrayList<>(symbols);
        partitioningScheme = Optional.of(new PartitioningScheme(Partitioning.create(writeTableLayout.get().getPartitioning(), partitionFunctionArguments), outputLayout));
    }
    PlanNode writerNode = new TableWriterNode(idAllocator.getNextId(), source, target, symbols, columnNames, writerOutputs, partitioningScheme);
    List<Symbol> outputs = ImmutableList.of(symbolAllocator.newSymbol("rows", BIGINT));
    TableFinishNode commitNode = new TableFinishNode(idAllocator.getNextId(), writerNode, target, outputs);
    return new RelationPlan(commitNode, analysis.getRootScope(), outputs);
}
Also used : ArrayList(java.util.ArrayList) PrestoException(com.facebook.presto.spi.PrestoException) TableFinishNode(com.facebook.presto.sql.planner.plan.TableFinishNode) PlanNode(com.facebook.presto.sql.planner.plan.PlanNode) LimitNode(com.facebook.presto.sql.planner.plan.LimitNode) TableWriterNode(com.facebook.presto.sql.planner.plan.TableWriterNode)

Example 5 with TableWriterNode

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

the class PlanFragmenter method analyzeGroupedExecution.

/*
     * In theory, recoverable grouped execution should be decided at query section level (i.e. a connected component of stages connected by remote exchanges).
     * This is because supporting mixed recoverable execution and non-recoverable execution within a query section adds unnecessary complications but provides little benefit,
     * because a single task failure is still likely to fail the non-recoverable stage.
     * However, since the concept of "query section" is not introduced until execution time as of now, it needs significant hacks to decide at fragmenting time.

     * TODO: We should introduce "query section" and make recoverability analysis done at query section level.
     */
private SubPlan analyzeGroupedExecution(Session session, SubPlan subPlan, boolean parentContainsTableFinish) {
    PlanFragment fragment = subPlan.getFragment();
    GroupedExecutionProperties properties = fragment.getRoot().accept(new GroupedExecutionTagger(session, metadata, nodePartitioningManager), null);
    if (properties.isSubTreeUseful()) {
        boolean preferDynamic = fragment.getRemoteSourceNodes().stream().allMatch(node -> node.getExchangeType() == REPLICATE);
        BucketNodeMap bucketNodeMap = nodePartitioningManager.getBucketNodeMap(session, fragment.getPartitioning(), preferDynamic);
        if (bucketNodeMap.isDynamic()) {
            /*
                 * We currently only support recoverable grouped execution if the following statements hold true:
                 *   - Current session enables recoverable grouped execution and table writer merge operator
                 *   - Parent sub plan contains TableFinishNode
                 *   - Current sub plan's root is TableWriterMergeNode or TableWriterNode
                 *   - Input connectors supports split source rewind
                 *   - Output connectors supports partition commit
                 *   - Bucket node map uses dynamic scheduling
                 *   - One table writer per task
                 */
            boolean recoverable = isRecoverableGroupedExecutionEnabled(session) && isTableWriterMergeOperatorEnabled(session) && parentContainsTableFinish && (fragment.getRoot() instanceof TableWriterMergeNode || fragment.getRoot() instanceof TableWriterNode) && properties.isRecoveryEligible();
            if (recoverable) {
                fragment = fragment.withRecoverableGroupedExecution(properties.getCapableTableScanNodes(), properties.getTotalLifespans());
            } else {
                fragment = fragment.withDynamicLifespanScheduleGroupedExecution(properties.getCapableTableScanNodes(), properties.getTotalLifespans());
            }
        } else {
            fragment = fragment.withFixedLifespanScheduleGroupedExecution(properties.getCapableTableScanNodes(), properties.getTotalLifespans());
        }
    }
    ImmutableList.Builder<SubPlan> result = ImmutableList.builder();
    boolean containsTableFinishNode = containsTableFinishNode(fragment);
    for (SubPlan child : subPlan.getChildren()) {
        result.add(analyzeGroupedExecution(session, child, containsTableFinishNode));
    }
    return new SubPlan(fragment, result.build());
}
Also used : BucketNodeMap(com.facebook.presto.execution.scheduler.BucketNodeMap) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) TableWriterMergeNode(com.facebook.presto.sql.planner.plan.TableWriterMergeNode) TableWriterNode(com.facebook.presto.sql.planner.plan.TableWriterNode)

Aggregations

TableWriterNode (com.facebook.presto.sql.planner.plan.TableWriterNode)5 VariableReferenceExpression (com.facebook.presto.spi.relation.VariableReferenceExpression)3 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)3 Session (com.facebook.presto.Session)2 StatsProvider (com.facebook.presto.cost.StatsProvider)2 Metadata (com.facebook.presto.metadata.Metadata)2 PrestoException (com.facebook.presto.spi.PrestoException)2 PlanNode (com.facebook.presto.spi.plan.PlanNode)2 Preconditions.checkState (com.google.common.base.Preconditions.checkState)2 List (java.util.List)2 SystemSessionProperties (com.facebook.presto.SystemSessionProperties)1 SystemSessionProperties.isPrintStatsForNonJoinQuery (com.facebook.presto.SystemSessionProperties.isPrintStatsForNonJoinQuery)1 QualifiedObjectName (com.facebook.presto.common.QualifiedObjectName)1 TupleDomain (com.facebook.presto.common.predicate.TupleDomain)1 BIGINT (com.facebook.presto.common.type.BigintType.BIGINT)1 Type (com.facebook.presto.common.type.Type)1 VARBINARY (com.facebook.presto.common.type.VarbinaryType.VARBINARY)1 CachingCostProvider (com.facebook.presto.cost.CachingCostProvider)1 CachingStatsProvider (com.facebook.presto.cost.CachingStatsProvider)1 CostCalculator (com.facebook.presto.cost.CostCalculator)1