diff --git a/presto-main-base/src/main/java/com/facebook/presto/cost/PlanNodeStatsEstimate.java b/presto-main-base/src/main/java/com/facebook/presto/cost/PlanNodeStatsEstimate.java index ab6bf3c397bf7..6d675e7a9a6be 100644 --- a/presto-main-base/src/main/java/com/facebook/presto/cost/PlanNodeStatsEstimate.java +++ b/presto-main-base/src/main/java/com/facebook/presto/cost/PlanNodeStatsEstimate.java @@ -28,6 +28,7 @@ import com.facebook.presto.spi.statistics.SourceInfo; import com.facebook.presto.spi.statistics.TableWriterNodeStatistics; import com.facebook.presto.sql.Serialization; +import com.facebook.presto.sql.planner.planPrinter.NodeRepresentation; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -180,6 +181,17 @@ public double getOutputSizeInBytes(PlanNode planNode) return getOutputSizeForVariables(planNode.getOutputVariables()); } + public double getOutputSizeInBytes(NodeRepresentation nodeRepresentation) + { + requireNonNull(nodeRepresentation, "nodeRepresentation is null"); + + if (!sourceInfo.estimateSizeUsingVariables() && !isNaN(totalSize)) { + return totalSize; + } + + return getOutputSizeForVariables(nodeRepresentation.getOutputs()); + } + /** * Returns estimated data size for given variables. * Unknown value is represented by {@link Double#NaN} diff --git a/presto-main-base/src/main/java/com/facebook/presto/sql/planner/planPrinter/TextRenderer.java b/presto-main-base/src/main/java/com/facebook/presto/sql/planner/planPrinter/TextRenderer.java index 2809b8145831a..8ca19bc5292d8 100644 --- a/presto-main-base/src/main/java/com/facebook/presto/sql/planner/planPrinter/TextRenderer.java +++ b/presto-main-base/src/main/java/com/facebook/presto/sql/planner/planPrinter/TextRenderer.java @@ -247,7 +247,7 @@ private String printEstimates(PlanRepresentation plan, NodeRepresentation node) output.append(format(formatStr, stats.getSourceInfo().getClass().getSimpleName(), formatAsLong(stats.getOutputRowCount()), - formatEstimateAsDataSize(stats.getOutputSizeInBytes(plan.getPlanNodeRoot())), + formatEstimateAsDataSize(stats.getOutputSizeInBytes(node)), formatDouble(cost.getCpuCost()), formatDouble(cost.getMaxMemory()), formatDouble(cost.getNetworkCost()), diff --git a/presto-main-base/src/test/java/com/facebook/presto/sql/planner/sanity/TestPlanPrinterSmoke.java b/presto-main-base/src/test/java/com/facebook/presto/sql/planner/sanity/TestPlanPrinterSmoke.java new file mode 100644 index 0000000000000..05b19c949ea41 --- /dev/null +++ b/presto-main-base/src/test/java/com/facebook/presto/sql/planner/sanity/TestPlanPrinterSmoke.java @@ -0,0 +1,84 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.facebook.presto.sql.planner.sanity; + +import com.facebook.presto.cost.CachingCostProvider; +import com.facebook.presto.cost.CachingStatsProvider; +import com.facebook.presto.cost.CostProvider; +import com.facebook.presto.cost.StatsAndCosts; +import com.facebook.presto.cost.StatsProvider; +import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.sql.planner.Plan; +import com.facebook.presto.sql.planner.assertions.BasePlanTest; +import com.facebook.presto.sql.planner.planPrinter.PlanPrinter; +import com.facebook.presto.testing.LocalQueryRunner; +import com.google.common.collect.ImmutableMap; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestPlanPrinterSmoke + extends BasePlanTest +{ + @Test + public void testLogicalPlanTextSizeEstimates() + { + String testSql = "SELECT \n" + + " *\n" + + "FROM \n" + + " supplier s,\n" + + " lineitem l1,\n" + + " orders o,\n" + + " nation n\n" + + "WHERE \n" + + " s.suppkey = l1.suppkey \n" + + " AND o.orderkey = l1.orderkey\n" + + " AND s.nationkey = n.nationkey \n" + + "\n"; + try (LocalQueryRunner localQueryRunner = createQueryRunner(ImmutableMap.of())) { + localQueryRunner.inTransaction(localQueryRunner.getDefaultSession(), transactionSession -> { + Plan actualPlan = localQueryRunner.createPlan( + transactionSession, + testSql, + WarningCollector.NOOP); + + StatsProvider statsProvider = new CachingStatsProvider(localQueryRunner.getStatsCalculator(), transactionSession, actualPlan.getTypes()); + CostProvider costProvider = new CachingCostProvider(localQueryRunner.getEstimatedExchangesCostCalculator(), statsProvider, transactionSession); + + String textLogicalPlan = PlanPrinter.textLogicalPlan(actualPlan.getRoot(), + actualPlan.getTypes(), + StatsAndCosts.create(actualPlan.getRoot(), statsProvider, costProvider, transactionSession), + localQueryRunner.getFunctionAndTypeManager(), + transactionSession, + 1); + + // `nation` scan + assertThat(textLogicalPlan).contains("Estimates: {source: CostBasedSourceInfo, rows: 25 (2.89kB), cpu: 2,734.00, memory: 0.00, network: 0.00}"); + // `supplier` scan + assertThat(textLogicalPlan).contains("Estimates: {source: CostBasedSourceInfo, rows: 100 (17.14kB), cpu: 16,652.00, memory: 0.00, network: 0.00}"); + // `orders` scan + assertThat(textLogicalPlan).contains("Estimates: {source: CostBasedSourceInfo, rows: 15,000 (1.99MB), cpu: 1,948,552.00, memory: 0.00, network: 0.00}"); + // `lineitem` scan + assertThat(textLogicalPlan).contains("Estimates: {source: CostBasedSourceInfo, rows: 60,175 (9.29MB), cpu: 9,197,910.00, memory: 0.00, network: 0.00}"); + + // JOINs + assertThat(textLogicalPlan).contains("Estimates: {source: CostBasedSourceInfo, rows: 60,175 (15.71MB), cpu: 53,349,364.11, memory: 2,083,552.00, network: 2,083,552.00}"); + assertThat(textLogicalPlan).contains("Estimates: {source: CostBasedSourceInfo, rows: 60,175 (30.51MB), cpu: 119,543,090.43, memory: 2,114,099.00, network: 2,114,099.00}"); + assertThat(textLogicalPlan).contains("Estimates: {source: CostBasedSourceInfo, rows: 100 (26.06kB), cpu: 90,055.00, memory: 2,959.00, network: 2,959.00}"); + + return null; + }); + } + } +}