Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,10 @@ public String getGraphvizPlan(Session session, Statement statement, Type planTyp
switch (planType) {
case LOGICAL:
Plan plan = getLogicalPlan(session, statement, parameters, warningCollector);
return graphvizLogicalPlan(plan.getRoot(), plan.getTypes(), session);
return graphvizLogicalPlan(plan.getRoot(), plan.getTypes(), session, metadata.getFunctionManager());
case DISTRIBUTED:
SubPlan subPlan = getDistributedPlan(session, statement, parameters, warningCollector);
return graphvizDistributedPlan(subPlan, session);
return graphvizDistributedPlan(subPlan, session, metadata.getFunctionManager());
}
throw new IllegalArgumentException("Unhandled plan type: " + planType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ private PlanPrinter(
.sum(), MILLISECONDS));

this.representation = new PlanRepresentation(planRoot, types, totalCpuTime, totalScheduledTime);
this.formatter = new RowExpressionFormatter(session.toConnectorSession());
this.formatter = new RowExpressionFormatter(session.toConnectorSession(), functionManager);

Visitor visitor = new Visitor(stageExecutionStrategy, types, estimatedStatsAndCosts, session, stats);
planRoot.accept(visitor, null);
Expand Down Expand Up @@ -312,7 +312,7 @@ private static String formatFragment(FunctionManager functionManager, Session se
return builder.toString();
}

public static String graphvizLogicalPlan(PlanNode plan, TypeProvider types, Session session)
public static String graphvizLogicalPlan(PlanNode plan, TypeProvider types, Session session, FunctionManager functionManager)
{
// TODO: This should move to something like GraphvizRenderer
PlanFragment fragment = new PlanFragment(
Expand All @@ -325,12 +325,12 @@ public static String graphvizLogicalPlan(PlanNode plan, TypeProvider types, Sess
StageExecutionDescriptor.ungroupedExecution(),
StatsAndCosts.empty(),
Optional.empty());
return GraphvizPrinter.printLogical(ImmutableList.of(fragment), session);
return GraphvizPrinter.printLogical(ImmutableList.of(fragment), session, functionManager);
}

public static String graphvizDistributedPlan(SubPlan plan, Session session)
public static String graphvizDistributedPlan(SubPlan plan, Session session, FunctionManager functionManager)
{
return GraphvizPrinter.printDistributed(plan, session);
return GraphvizPrinter.printDistributed(plan, session, functionManager);
}

private class Visitor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@
*/
package com.facebook.presto.sql.planner.planPrinter;

import com.facebook.presto.metadata.FunctionManager;
import com.facebook.presto.spi.ConnectorSession;
import com.facebook.presto.spi.block.Block;
import com.facebook.presto.spi.function.FunctionMetadataManager;
import com.facebook.presto.spi.function.StandardFunctionResolution;
import com.facebook.presto.spi.relation.CallExpression;
import com.facebook.presto.spi.relation.ConstantExpression;
import com.facebook.presto.spi.relation.InputReferenceExpression;
Expand All @@ -25,20 +28,26 @@
import com.facebook.presto.spi.relation.VariableReferenceExpression;
import com.facebook.presto.spi.type.Type;
import com.facebook.presto.sql.planner.LiteralInterpreter;
import com.facebook.presto.sql.relational.FunctionResolution;

import java.util.List;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;

public final class RowExpressionFormatter
{
private final ConnectorSession session;
private final FunctionMetadataManager functionMetadataManager;
private final StandardFunctionResolution standardFunctionResolution;

public RowExpressionFormatter(ConnectorSession session)
public RowExpressionFormatter(ConnectorSession session, FunctionManager functionManager)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use StandardFunctionResolution for the constructor; so it's more general

{
this.session = requireNonNull(session, "session is null");
this.functionMetadataManager = requireNonNull(functionManager, "function manager is null");
this.standardFunctionResolution = new FunctionResolution(functionManager);
}

public String formatRowExpression(RowExpression expression)
Expand All @@ -57,12 +66,32 @@ public class Formatter
@Override
public String visitCall(CallExpression node, Void context)
{
if (standardFunctionResolution.isArithmeticFunction(node.getFunctionHandle()) || standardFunctionResolution.isComparisonFunction(node.getFunctionHandle())) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also handle the CAST case?
For CAST(a) we can print out as CAST(a AS <return_type>). This helps us to understand the type info.

Also, can we handle NEGATION and SUBSCRIPT as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing, should I also include AND and OR.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good!

String operation = functionMetadataManager.getFunctionMetadata(node.getFunctionHandle()).getOperatorType().get().getOperator();
return String.join(" " + operation + " ", formatRowExpressions(node.getArguments()).stream().map(e -> "(" + e + ")").collect(toImmutableList()));
}
else if (standardFunctionResolution.isCastFunction(node.getFunctionHandle())) {
return String.format("CAST(%s AS %s)", formatRowExpression(node.getArguments().get(0)), node.getType().getDisplayName());
}
else if (standardFunctionResolution.isNegateFunction(node.getFunctionHandle())) {
return "-(" + formatRowExpression(node.getArguments().get(0)) + ")";
}
else if (standardFunctionResolution.isSubscriptFunction(node.getFunctionHandle())) {
return formatRowExpression(node.getArguments().get(0)) + "[" + formatRowExpression(node.getArguments().get(1)) + "]";
}
else if (standardFunctionResolution.isBetweenFunction(node.getFunctionHandle())) {
List<String> formattedExpresions = formatRowExpressions(node.getArguments());
return String.format("%s BETWEEN (%s) AND (%s)", formattedExpresions.get(0), formattedExpresions.get(1), formattedExpresions.get(2));
}
return node.getDisplayName() + "(" + String.join(", ", formatRowExpressions(node.getArguments())) + ")";
}

@Override
public String visitSpecialForm(SpecialFormExpression node, Void context)
{
if (node.getForm().equals(SpecialFormExpression.Form.AND) || node.getForm().equals(SpecialFormExpression.Form.OR)) {
return String.join(" " + node.getForm() + " ", formatRowExpressions(node.getArguments()).stream().map(e -> "(" + e + ")").collect(toImmutableList()));
}
return node.getForm().name() + "(" + String.join(", ", formatRowExpressions(node.getArguments())) + ")";
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package com.facebook.presto.util;

import com.facebook.presto.Session;
import com.facebook.presto.metadata.FunctionManager;
import com.facebook.presto.sql.planner.Partitioning.ArgumentBinding;
import com.facebook.presto.sql.planner.PlanFragment;
import com.facebook.presto.sql.planner.SubPlan;
Expand Down Expand Up @@ -133,7 +134,7 @@ private enum NodeType

private GraphvizPrinter() {}

public static String printLogical(List<PlanFragment> fragments, Session session)
public static String printLogical(List<PlanFragment> fragments, Session session, FunctionManager functionManager)
{
Map<PlanFragmentId, PlanFragment> fragmentsById = Maps.uniqueIndex(fragments, PlanFragment::getId);
PlanNodeIdGenerator idGenerator = new PlanNodeIdGenerator();
Expand All @@ -142,7 +143,7 @@ public static String printLogical(List<PlanFragment> fragments, Session session)
output.append("digraph logical_plan {\n");

for (PlanFragment fragment : fragments) {
printFragmentNodes(output, fragment, idGenerator, session);
printFragmentNodes(output, fragment, idGenerator, session, functionManager);
}

for (PlanFragment fragment : fragments) {
Expand All @@ -154,7 +155,7 @@ public static String printLogical(List<PlanFragment> fragments, Session session)
return output.toString();
}

public static String printDistributed(SubPlan plan, Session session)
public static String printDistributed(SubPlan plan, Session session, FunctionManager functionManager)
{
List<PlanFragment> fragments = plan.getAllFragments();
Map<PlanFragmentId, PlanFragment> fragmentsById = Maps.uniqueIndex(fragments, PlanFragment::getId);
Expand All @@ -163,25 +164,31 @@ public static String printDistributed(SubPlan plan, Session session)
StringBuilder output = new StringBuilder();
output.append("digraph distributed_plan {\n");

printSubPlan(plan, fragmentsById, idGenerator, output, session);
printSubPlan(plan, fragmentsById, idGenerator, output, session, functionManager);

output.append("}\n");

return output.toString();
}

private static void printSubPlan(SubPlan plan, Map<PlanFragmentId, PlanFragment> fragmentsById, PlanNodeIdGenerator idGenerator, StringBuilder output, Session session)
private static void printSubPlan(
SubPlan plan,
Map<PlanFragmentId, PlanFragment> fragmentsById,
PlanNodeIdGenerator idGenerator,
StringBuilder output,
Session session,
FunctionManager functionManager)
{
PlanFragment fragment = plan.getFragment();
printFragmentNodes(output, fragment, idGenerator, session);
printFragmentNodes(output, fragment, idGenerator, session, functionManager);
fragment.getRoot().accept(new EdgePrinter(output, fragmentsById, idGenerator), null);

for (SubPlan child : plan.getChildren()) {
printSubPlan(child, fragmentsById, idGenerator, output, session);
printSubPlan(child, fragmentsById, idGenerator, output, session, functionManager);
}
}

private static void printFragmentNodes(StringBuilder output, PlanFragment fragment, PlanNodeIdGenerator idGenerator, Session session)
private static void printFragmentNodes(StringBuilder output, PlanFragment fragment, PlanNodeIdGenerator idGenerator, Session session, FunctionManager functionManager)
{
String clusterId = "cluster_" + fragment.getId();
output.append("subgraph ")
Expand All @@ -193,7 +200,7 @@ private static void printFragmentNodes(StringBuilder output, PlanFragment fragme
.append('\n');

PlanNode plan = fragment.getRoot();
plan.accept(new NodePrinter(output, idGenerator, session), null);
plan.accept(new NodePrinter(output, idGenerator, session, functionManager), null);

output.append("}")
.append('\n');
Expand All @@ -207,11 +214,11 @@ private static class NodePrinter
private final PlanNodeIdGenerator idGenerator;
private final RowExpressionFormatter formatter;

public NodePrinter(StringBuilder output, PlanNodeIdGenerator idGenerator, Session session)
public NodePrinter(StringBuilder output, PlanNodeIdGenerator idGenerator, Session session, FunctionManager functionManager)
{
this.output = output;
this.idGenerator = idGenerator;
this.formatter = new RowExpressionFormatter(session.toConnectorSession());
this.formatter = new RowExpressionFormatter(session.toConnectorSession(), functionManager);
}

@Override
Expand Down
Loading