Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print Trino version to EXPLAIN ANALYZE VERBOSE #15243

Merged
merged 1 commit into from
Nov 30, 2022
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 @@ -108,7 +108,7 @@ public class QueryMonitor
private final JsonCodec<ExecutionFailureInfo> executionFailureInfoCodec;
private final JsonCodec<StatsAndCosts> statsAndCostsCodec;
private final EventListenerManager eventListenerManager;
private final String serverVersion;
private final NodeVersion serverVersion;
private final String serverAddress;
private final String environment;
private final SessionPropertyManager sessionPropertyManager;
Expand All @@ -135,7 +135,7 @@ public QueryMonitor(
this.operatorStatsCodec = requireNonNull(operatorStatsCodec, "operatorStatsCodec is null");
this.statsAndCostsCodec = requireNonNull(statsAndCostsCodec, "statsAndCostsCodec is null");
this.executionFailureInfoCodec = requireNonNull(executionFailureInfoCodec, "executionFailureInfoCodec is null");
this.serverVersion = nodeVersion.toString();
this.serverVersion = nodeVersion;
this.serverAddress = nodeInfo.getExternalAddress();
this.environment = nodeInfo.getEnvironment();
this.sessionPropertyManager = requireNonNull(sessionPropertyManager, "sessionPropertyManager is null");
Expand Down Expand Up @@ -351,7 +351,7 @@ private QueryContext createQueryContext(SessionRepresentation session, Optional<
mergeSessionAndCatalogProperties(session),
session.getResourceEstimates(),
serverAddress,
serverVersion,
serverVersion.toString(),
environment,
queryType,
retryPolicy.toString());
Expand All @@ -366,7 +366,8 @@ private Optional<String> createTextQueryPlan(QueryInfo queryInfo, Anonymizer ano
queryInfo.getQueryStats(),
new ValuePrinter(metadata, functionManager, queryInfo.getSession().toSession(sessionPropertyManager)),
false,
anonymizer));
anonymizer,
serverVersion));
}
}
catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package io.trino.operator;

import com.google.common.collect.ImmutableList;
import io.trino.client.NodeVersion;
import io.trino.execution.QueryInfo;
import io.trino.execution.QueryPerformanceFetcher;
import io.trino.execution.StageId;
Expand Down Expand Up @@ -44,6 +45,7 @@ public static class ExplainAnalyzeOperatorFactory
private final Metadata metadata;
private final FunctionManager functionManager;
private final boolean verbose;
private final NodeVersion version;
private boolean closed;

public ExplainAnalyzeOperatorFactory(
Expand All @@ -52,22 +54,24 @@ public ExplainAnalyzeOperatorFactory(
QueryPerformanceFetcher queryPerformanceFetcher,
Metadata metadata,
FunctionManager functionManager,
boolean verbose)
boolean verbose,
NodeVersion version)
{
this.operatorId = operatorId;
this.planNodeId = requireNonNull(planNodeId, "planNodeId is null");
this.queryPerformanceFetcher = requireNonNull(queryPerformanceFetcher, "queryPerformanceFetcher is null");
this.metadata = requireNonNull(metadata, "metadata is null");
this.functionManager = requireNonNull(functionManager, "functionManager is null");
this.verbose = verbose;
this.version = requireNonNull(version, "version is null");
}

@Override
public Operator createOperator(DriverContext driverContext)
{
checkState(!closed, "Factory is already closed");
OperatorContext operatorContext = driverContext.addOperatorContext(operatorId, planNodeId, ExplainAnalyzeOperator.class.getSimpleName());
return new ExplainAnalyzeOperator(operatorContext, queryPerformanceFetcher, metadata, functionManager, verbose);
return new ExplainAnalyzeOperator(operatorContext, queryPerformanceFetcher, metadata, functionManager, verbose, version);
}

@Override
Expand All @@ -79,7 +83,7 @@ public void noMoreOperators()
@Override
public OperatorFactory duplicate()
{
return new ExplainAnalyzeOperatorFactory(operatorId, planNodeId, queryPerformanceFetcher, metadata, functionManager, verbose);
return new ExplainAnalyzeOperatorFactory(operatorId, planNodeId, queryPerformanceFetcher, metadata, functionManager, verbose, version);
}
}

Expand All @@ -88,6 +92,7 @@ public OperatorFactory duplicate()
private final Metadata metadata;
private final FunctionManager functionManager;
private final boolean verbose;
private final NodeVersion version;
private boolean finishing;
private boolean outputConsumed;

Expand All @@ -96,13 +101,15 @@ public ExplainAnalyzeOperator(
QueryPerformanceFetcher queryPerformanceFetcher,
Metadata metadata,
FunctionManager functionManager,
boolean verbose)
boolean verbose,
NodeVersion version)
{
this.operatorContext = requireNonNull(operatorContext, "operatorContext is null");
this.queryPerformanceFetcher = requireNonNull(queryPerformanceFetcher, "queryPerformanceFetcher is null");
this.metadata = requireNonNull(metadata, "metadata is null");
this.functionManager = requireNonNull(functionManager, "functionManager is null");
this.verbose = verbose;
this.version = requireNonNull(version, "version is null");
}

@Override
Expand Down Expand Up @@ -158,7 +165,8 @@ public Page getOutput()
metadata,
functionManager,
operatorContext.getSession(),
verbose);
verbose,
version);
BlockBuilder builder = VARCHAR.createBlockBuilder(null, 1);
VARCHAR.writeString(builder, plan);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import io.airlift.units.DataSize;
import io.trino.Session;
import io.trino.SystemSessionProperties;
import io.trino.client.NodeVersion;
import io.trino.collect.cache.NonEvictableCache;
import io.trino.exchange.ExchangeManagerRegistry;
import io.trino.execution.DynamicFilterConfig;
Expand Down Expand Up @@ -423,6 +424,7 @@ public class LocalExecutionPlanner
private final TableExecuteContextManager tableExecuteContextManager;
private final ExchangeManagerRegistry exchangeManagerRegistry;
private final PositionsAppenderFactory positionsAppenderFactory;
private final NodeVersion version;

private final NonEvictableCache<FunctionKey, AccumulatorFactory> accumulatorFactoryCache = buildNonEvictableCache(CacheBuilder.newBuilder()
.maximumSize(1000)
Expand Down Expand Up @@ -456,7 +458,8 @@ public LocalExecutionPlanner(
DynamicFilterConfig dynamicFilterConfig,
BlockTypeOperators blockTypeOperators,
TableExecuteContextManager tableExecuteContextManager,
ExchangeManagerRegistry exchangeManagerRegistry)
ExchangeManagerRegistry exchangeManagerRegistry,
NodeVersion version)
{
this.plannerContext = requireNonNull(plannerContext, "plannerContext is null");
this.metadata = plannerContext.getMetadata();
Expand Down Expand Up @@ -502,6 +505,7 @@ public LocalExecutionPlanner(
this.tableExecuteContextManager = requireNonNull(tableExecuteContextManager, "tableExecuteContextManager is null");
this.exchangeManagerRegistry = requireNonNull(exchangeManagerRegistry, "exchangeManagerRegistry is null");
this.positionsAppenderFactory = new PositionsAppenderFactory(blockTypeOperators);
this.version = requireNonNull(version, "version is null");
}

public LocalExecutionPlan plan(
Expand Down Expand Up @@ -955,7 +959,8 @@ public PhysicalOperation visitExplainAnalyze(ExplainAnalyzeNode node, LocalExecu
analyzeContext.getQueryPerformanceFetcher(),
metadata,
plannerContext.getFunctionManager(),
node.isVerbose());
node.isVerbose(),
version);
return new PhysicalOperation(operatorFactory, makeLayout(node), context, source);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.airlift.json.JsonCodec;
import io.airlift.units.Duration;
import io.trino.Session;
import io.trino.client.NodeVersion;
import io.trino.cost.PlanCostEstimate;
import io.trino.cost.PlanNodeStatsAndCostSummary;
import io.trino.cost.PlanNodeStatsEstimate;
Expand Down Expand Up @@ -383,22 +384,25 @@ public static String textDistributedPlan(
Metadata metadata,
FunctionManager functionManager,
Session session,
boolean verbose)
boolean verbose,
NodeVersion version)
{
return textDistributedPlan(
outputStageInfo,
queryStats,
new ValuePrinter(metadata, functionManager, session),
verbose,
new NoOpAnonymizer());
new NoOpAnonymizer(),
version);
}

public static String textDistributedPlan(
StageInfo outputStageInfo,
QueryStats queryStats,
ValuePrinter valuePrinter,
boolean verbose,
Anonymizer anonymizer)
Anonymizer anonymizer,
NodeVersion version)
{
List<StageInfo> allStages = getAllStages(Optional.of(outputStageInfo));
Map<PlanNodeId, TableInfo> tableInfos = allStages.stream()
Expand All @@ -418,6 +422,10 @@ public static String textDistributedPlan(
.collect(toImmutableMap(DynamicFilterDomainStats::getDynamicFilterId, identity()));
TypeProvider typeProvider = getTypeProvider(allFragments);

if (verbose) {
Copy link
Member

Choose a reason for hiding this comment

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

Why not print this always ?

Copy link
Member Author

Choose a reason for hiding this comment

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

I would say EXPLAIN ANALYZE is more for end-users while EXPLAIN ANALYZE VERBOSE it's kind of diagnostic output for devs and power users. Therefore, I thought it's not that useful to keep it in plain EXPLAIN ANALYZE

Copy link
Member

Choose a reason for hiding this comment

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

Why not always?

every EXPLAIN is quite verbose, and version string is quite short, so having it in every EXPLAIN & EXPLAIN ANALYZE wouldn't hurt

Copy link
Member Author

Choose a reason for hiding this comment

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

Done in #15317

builder.append(format("Trino version: %s\n", version));
}

for (StageInfo stageInfo : allStages) {
builder.append(formatFragment(
tableScanNode -> tableInfos.get(tableScanNode.getId()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -962,7 +962,8 @@ private List<Driver> createDrivers(Session session, Plan plan, OutputFactory out
new DynamicFilterConfig(),
blockTypeOperators,
tableExecuteContextManager,
exchangeManagerRegistry);
exchangeManagerRegistry,
nodeManager.getCurrentNode().getNodeVersion());

// plan query
LocalExecutionPlan localExecutionPlan = executionPlanner.plan(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import io.airlift.json.ObjectMapperProvider;
import io.trino.client.NodeVersion;
import io.trino.connector.CatalogHandle;
import io.trino.connector.CatalogServiceProvider;
import io.trino.cost.StatsAndCosts;
Expand Down Expand Up @@ -173,7 +174,8 @@ public static LocalExecutionPlanner createTestingPlanner()
new DynamicFilterConfig(),
blockTypeOperators,
new TableExecuteContextManager(),
new ExchangeManagerRegistry());
new ExchangeManagerRegistry(),
new NodeVersion("test"));
}

public static TaskInfo updateTask(SqlTask sqlTask, List<SplitAssignment> splitAssignments, OutputBuffers outputBuffers)
Expand Down
5 changes: 3 additions & 2 deletions docs/src/main/sphinx/sql/explain-analyze.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ relevant plan nodes). Such statistics are useful when one wants to detect data a
orderdate := orderdate:date:REGULAR
Input: 1500000 rows (18.17MB), Filtered: 45.46%, Physical Input: 4.51MB

When the ``VERBOSE`` option is used, some operators may report additional information.
For example, the window function operator will output the following::
When the ``VERBOSE`` option is used, Trino version is reported as well as
some operators may report additional information. For example, the window
function operator will output the following::

EXPLAIN ANALYZE VERBOSE SELECT count(clerk) OVER() FROM orders
WHERE orderdate > date '1995-01-01';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ public void testExplainAnalyzeVerbose()
"'CPU time distribution \\(s\\)' = \\{count=.*, p01=.*, p05=.*, p10=.*, p25=.*, p50=.*, p75=.*, p90=.*, p95=.*, p99=.*, min=.*, max=.*}",
"'Scheduled time distribution \\(s\\)' = \\{count=.*, p01=.*, p05=.*, p10=.*, p25=.*, p50=.*, p75=.*, p90=.*, p95=.*, p99=.*, min=.*, max=.*}",
"'Blocked time distribution \\(s\\)' = \\{count=.*, p01=.*, p05=.*, p10=.*, p25=.*, p50=.*, p75=.*, p90=.*, p95=.*, p99=.*, min=.*, max=.*}",
"Output buffer active time: .*, buffer utilization distribution \\(%\\): \\{p01=.*, p05=.*, p10=.*, p25=.*, p50=.*, p75=.*, p90=.*, p95=.*, p99=.*, max=.*}");
"Output buffer active time: .*, buffer utilization distribution \\(%\\): \\{p01=.*, p05=.*, p10=.*, p25=.*, p50=.*, p75=.*, p90=.*, p95=.*, p99=.*, max=.*}",
"Trino version: .*");
}

@Test
Expand Down