diff --git a/presto-analyzer/pom.xml b/presto-analyzer/pom.xml index b78afbf40e555..c3f07d1c2bb1f 100644 --- a/presto-analyzer/pom.xml +++ b/presto-analyzer/pom.xml @@ -47,11 +47,6 @@ true - - com.google.inject - guice - - javax.inject javax.inject diff --git a/presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/BuiltInQueryAnalysis.java b/presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/BuiltInQueryAnalysis.java new file mode 100644 index 0000000000000..62984ecd0303e --- /dev/null +++ b/presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/BuiltInQueryAnalysis.java @@ -0,0 +1,55 @@ +/* + * 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.analyzer; + +import com.facebook.presto.spi.analyzer.QueryAnalysis; +import com.facebook.presto.spi.function.FunctionKind; + +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +public class BuiltInQueryAnalysis + implements QueryAnalysis +{ + private final Analysis analysis; + + public BuiltInQueryAnalysis(Analysis analysis) + { + this.analysis = analysis; + } + + public Analysis getAnalysis() + { + return analysis; + } + + @Override + public String getUpdateType() + { + return analysis.getUpdateType(); + } + + @Override + public Optional getExpandedQuery() + { + return analysis.getExpandedQuery(); + } + + @Override + public Map> getInvokedFunctions() + { + return analysis.getInvokedFunctions(); + } +} diff --git a/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchManager.java b/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchManager.java index 7c6115b137ca3..160247037382c 100644 --- a/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchManager.java +++ b/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchManager.java @@ -308,6 +308,7 @@ private void createQueryInternal(QueryId queryId, String slug, int retryCoun DispatchQuery dispatchQuery = dispatchQueryFactory.createDispatchQuery( session, + analyzerProvider, query, preparedQuery, slug, diff --git a/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchQueryFactory.java b/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchQueryFactory.java index b4f9c4dd17d31..0e19219b6728d 100644 --- a/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchQueryFactory.java +++ b/presto-main/src/main/java/com/facebook/presto/dispatcher/DispatchQueryFactory.java @@ -17,6 +17,7 @@ import com.facebook.presto.common.analyzer.PreparedQuery; import com.facebook.presto.common.resourceGroups.QueryType; import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.spi.analyzer.AnalyzerProvider; import com.facebook.presto.spi.resourceGroups.ResourceGroupId; import java.util.Optional; @@ -31,6 +32,7 @@ public interface DispatchQueryFactory * This interface API is defined to setting up all preparation works for query before it being executed. * * @param session the session + * @param analyzerProvider the analyzer provider * @param query the query * @param preparedQuery the prepared query * @param slug the unique query slug for each {@code Query} object @@ -43,6 +45,7 @@ public interface DispatchQueryFactory */ DispatchQuery createDispatchQuery( Session session, + AnalyzerProvider analyzerProvider, String query, PreparedQuery preparedQuery, String slug, diff --git a/presto-main/src/main/java/com/facebook/presto/dispatcher/LocalDispatchQueryFactory.java b/presto-main/src/main/java/com/facebook/presto/dispatcher/LocalDispatchQueryFactory.java index 853137d11de44..57f8aa4438c7d 100644 --- a/presto-main/src/main/java/com/facebook/presto/dispatcher/LocalDispatchQueryFactory.java +++ b/presto-main/src/main/java/com/facebook/presto/dispatcher/LocalDispatchQueryFactory.java @@ -27,9 +27,9 @@ import com.facebook.presto.metadata.Metadata; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.spi.analyzer.AnalyzerProvider; import com.facebook.presto.spi.resourceGroups.ResourceGroupId; import com.facebook.presto.spi.security.AccessControl; -import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer; import com.facebook.presto.tracing.NoopTracerProvider; import com.facebook.presto.tracing.QueryStateTracingListener; import com.facebook.presto.transaction.TransactionManager; @@ -43,7 +43,6 @@ import java.util.function.Consumer; import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED; -import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; /** @@ -118,6 +117,7 @@ public LocalDispatchQueryFactory( * to the {@link ResourceGroupManager}. This is no-op for no disaggregated coordinator setup * * @param session the session + * @param analyzerProvider the analyzer provider * @param query the query * @param preparedQuery the prepared query * @param slug the unique query slug for each {@code Query} object @@ -131,6 +131,7 @@ public LocalDispatchQueryFactory( @Override public DispatchQuery createDispatchQuery( Session session, + AnalyzerProvider analyzerProvider, String query, PreparedQuery preparedQuery, String slug, @@ -163,9 +164,7 @@ public DispatchQuery createDispatchQuery( throw new PrestoException(NOT_SUPPORTED, "Unsupported statement type: " + preparedQuery.getStatementClass().getSimpleName()); } - //TODO: PreparedQuery should be passed all the way to analyzer - checkState(preparedQuery instanceof BuiltInQueryPreparer.BuiltInPreparedQuery, "Unsupported prepared query type: %s", preparedQuery.getClass().getSimpleName()); - return queryExecutionFactory.createQueryExecution((BuiltInQueryPreparer.BuiltInPreparedQuery) preparedQuery, stateMachine, slug, retryCount, warningCollector, queryType); + return queryExecutionFactory.createQueryExecution(analyzerProvider, preparedQuery, stateMachine, slug, retryCount, warningCollector, queryType); }); return new LocalDispatchQuery( diff --git a/presto-main/src/main/java/com/facebook/presto/execution/DDLDefinitionExecution.java b/presto-main/src/main/java/com/facebook/presto/execution/DDLDefinitionExecution.java index 910de3cadd378..f621dfd8d4246 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/DDLDefinitionExecution.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/DDLDefinitionExecution.java @@ -13,10 +13,12 @@ */ package com.facebook.presto.execution; +import com.facebook.presto.common.analyzer.PreparedQuery; import com.facebook.presto.common.resourceGroups.QueryType; import com.facebook.presto.metadata.Metadata; import com.facebook.presto.metadata.MetadataManager; import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.spi.analyzer.AnalyzerProvider; import com.facebook.presto.spi.security.AccessControl; import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer; import com.facebook.presto.sql.tree.Expression; @@ -31,6 +33,7 @@ import java.util.Optional; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; public class DDLDefinitionExecution @@ -82,14 +85,19 @@ public DDLDefinitionExecutionFactory( @Override public DDLDefinitionExecution createQueryExecution( - BuiltInQueryPreparer.BuiltInPreparedQuery preparedQuery, + AnalyzerProvider analyzerProvider, + PreparedQuery preparedQuery, QueryStateMachine stateMachine, String slug, int retryCount, WarningCollector warningCollector, Optional queryType) { - return createDDLDefinitionExecution(preparedQuery.getStatement(), preparedQuery.getParameters(), stateMachine, slug, retryCount); + //TODO: PreparedQuery should be passed all the way to analyzer + checkState(preparedQuery instanceof BuiltInQueryPreparer.BuiltInPreparedQuery, "Unsupported prepared query type: %s", preparedQuery.getClass().getSimpleName()); + BuiltInQueryPreparer.BuiltInPreparedQuery builtInQueryPreparer = (BuiltInQueryPreparer.BuiltInPreparedQuery) preparedQuery; + + return createDDLDefinitionExecution(builtInQueryPreparer.getStatement(), builtInQueryPreparer.getParameters(), stateMachine, slug, retryCount); } private DDLDefinitionExecution createDDLDefinitionExecution( diff --git a/presto-main/src/main/java/com/facebook/presto/execution/QueryExecution.java b/presto-main/src/main/java/com/facebook/presto/execution/QueryExecution.java index 51e5b36c38168..52acd2ef275bd 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/QueryExecution.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/QueryExecution.java @@ -13,6 +13,7 @@ */ package com.facebook.presto.execution; +import com.facebook.presto.common.analyzer.PreparedQuery; import com.facebook.presto.common.resourceGroups.QueryType; import com.facebook.presto.common.type.Type; import com.facebook.presto.execution.QueryTracker.TrackedQuery; @@ -20,8 +21,8 @@ import com.facebook.presto.memory.VersionedMemoryPoolId; import com.facebook.presto.server.BasicQueryInfo; import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.spi.analyzer.AnalyzerProvider; import com.facebook.presto.spi.resourceGroups.ResourceGroupQueryLimits; -import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer.BuiltInPreparedQuery; import com.facebook.presto.sql.planner.Plan; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -103,7 +104,8 @@ public interface QueryExecution interface QueryExecutionFactory { T createQueryExecution( - BuiltInPreparedQuery preparedQuery, + AnalyzerProvider analyzerProvider, + PreparedQuery preparedQuery, QueryStateMachine stateMachine, String slug, int retryCount, diff --git a/presto-main/src/main/java/com/facebook/presto/execution/SessionDefinitionExecution.java b/presto-main/src/main/java/com/facebook/presto/execution/SessionDefinitionExecution.java index b27fc8364385a..d05d1f34bf6fd 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/SessionDefinitionExecution.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/SessionDefinitionExecution.java @@ -13,10 +13,12 @@ */ package com.facebook.presto.execution; +import com.facebook.presto.common.analyzer.PreparedQuery; import com.facebook.presto.common.resourceGroups.QueryType; import com.facebook.presto.metadata.Metadata; import com.facebook.presto.metadata.MetadataManager; import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.spi.analyzer.AnalyzerProvider; import com.facebook.presto.spi.security.AccessControl; import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer; import com.facebook.presto.sql.tree.Expression; @@ -31,6 +33,7 @@ import java.util.Optional; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; public class SessionDefinitionExecution @@ -82,14 +85,18 @@ public SessionDefinitionExecutionFactory( @Override public SessionDefinitionExecution createQueryExecution( - BuiltInQueryPreparer.BuiltInPreparedQuery preparedQuery, + AnalyzerProvider analyzerProvider, + PreparedQuery preparedQuery, QueryStateMachine stateMachine, String slug, int retryCount, WarningCollector warningCollector, Optional queryType) { - return createSessionDefinitionExecution(preparedQuery.getStatement(), preparedQuery.getParameters(), stateMachine, slug, retryCount); + //TODO: PreparedQuery should be passed all the way to analyzer + checkState(preparedQuery instanceof BuiltInQueryPreparer.BuiltInPreparedQuery, "Unsupported prepared query type: %s", preparedQuery.getClass().getSimpleName()); + BuiltInQueryPreparer.BuiltInPreparedQuery builtInQueryPreparer = (BuiltInQueryPreparer.BuiltInPreparedQuery) preparedQuery; + return createSessionDefinitionExecution(builtInQueryPreparer.getStatement(), builtInQueryPreparer.getParameters(), stateMachine, slug, retryCount); } private SessionDefinitionExecution createSessionDefinitionExecution( diff --git a/presto-main/src/main/java/com/facebook/presto/execution/SqlQueryExecution.java b/presto-main/src/main/java/com/facebook/presto/execution/SqlQueryExecution.java index 6c5abac27c48f..3dac2c91a16bf 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/SqlQueryExecution.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/SqlQueryExecution.java @@ -15,6 +15,7 @@ import com.facebook.airlift.concurrent.SetThreadName; import com.facebook.presto.Session; +import com.facebook.presto.common.analyzer.PreparedQuery; import com.facebook.presto.common.resourceGroups.QueryType; import com.facebook.presto.cost.CostCalculator; import com.facebook.presto.cost.HistoryBasedPlanStatisticsManager; @@ -35,8 +36,11 @@ import com.facebook.presto.spi.ConnectorId; import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.QueryId; -import com.facebook.presto.spi.TableHandle; import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.spi.analyzer.AnalyzerContext; +import com.facebook.presto.spi.analyzer.AnalyzerProvider; +import com.facebook.presto.spi.analyzer.QueryAnalysis; +import com.facebook.presto.spi.analyzer.QueryAnalyzer; import com.facebook.presto.spi.function.FunctionKind; import com.facebook.presto.spi.plan.PlanNode; import com.facebook.presto.spi.plan.PlanNodeIdAllocator; @@ -45,13 +49,9 @@ import com.facebook.presto.split.CloseableSplitSourceProvider; import com.facebook.presto.split.SplitManager; import com.facebook.presto.sql.Optimizer; -import com.facebook.presto.sql.analyzer.Analysis; -import com.facebook.presto.sql.analyzer.Analyzer; -import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer.BuiltInPreparedQuery; import com.facebook.presto.sql.analyzer.QueryExplainer; import com.facebook.presto.sql.parser.SqlParser; import com.facebook.presto.sql.planner.InputExtractor; -import com.facebook.presto.sql.planner.LogicalPlanner; import com.facebook.presto.sql.planner.OutputExtractor; import com.facebook.presto.sql.planner.PartitioningHandle; import com.facebook.presto.sql.planner.Plan; @@ -64,7 +64,6 @@ import com.facebook.presto.sql.planner.optimizations.PlanOptimizer; import com.facebook.presto.sql.planner.plan.OutputNode; import com.facebook.presto.sql.planner.sanity.PlanChecker; -import com.facebook.presto.sql.tree.Explain; import com.google.common.collect.ImmutableSet; import com.google.common.util.concurrent.ListenableFuture; import io.airlift.units.DataSize; @@ -96,8 +95,8 @@ import static com.facebook.presto.execution.buffer.OutputBuffers.createSpoolingOutputBuffers; import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED; import static com.facebook.presto.sql.Optimizer.PlanStage.OPTIMIZED_AND_VALIDATED; -import static com.facebook.presto.sql.analyzer.utils.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.planner.PlanNodeCanonicalInfo.getCanonicalInfo; +import static com.facebook.presto.util.AnalyzerUtil.getAnalyzerContext; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Throwables.throwIfInstanceOf; import static io.airlift.units.DataSize.Unit.BYTE; @@ -111,6 +110,7 @@ public class SqlQueryExecution { private static final OutputBufferId OUTPUT_BUFFER_ID = new OutputBufferId(0); + private final QueryAnalyzer queryAnalyzer; private final QueryStateMachine stateMachine; private final String slug; private final int retryCount; @@ -131,7 +131,6 @@ public class SqlQueryExecution private final AtomicReference queryPlan = new AtomicReference<>(); private final ExecutionPolicy executionPolicy; private final SplitSchedulerStats schedulerStats; - private final Analysis analysis; private final StatsCalculator statsCalculator; private final CostCalculator costCalculator; private final PlanChecker planChecker; @@ -140,9 +139,12 @@ public class SqlQueryExecution private final PartialResultQueryManager partialResultQueryManager; private final AtomicReference> resourceGroupQueryLimits = new AtomicReference<>(Optional.empty()); private final PlanCanonicalInfoProvider planCanonicalInfoProvider; + private final QueryAnalysis queryAnalysis; + private final AnalyzerContext analyzerContext; private SqlQueryExecution( - BuiltInPreparedQuery preparedQuery, + QueryAnalyzer queryAnalyzer, + PreparedQuery preparedQuery, QueryStateMachine stateMachine, String slug, int retryCount, @@ -170,6 +172,7 @@ private SqlQueryExecution( PlanCanonicalInfoProvider planCanonicalInfoProvider) { try (SetThreadName ignored = new SetThreadName("Query-%s", stateMachine.getQueryId())) { + this.queryAnalyzer = requireNonNull(queryAnalyzer, "queryAnalyzer is null"); this.slug = requireNonNull(slug, "slug is null"); this.retryCount = retryCount; this.metadata = requireNonNull(metadata, "metadata is null"); @@ -190,32 +193,25 @@ private SqlQueryExecution( this.stateMachine = requireNonNull(stateMachine, "stateMachine is null"); this.planChecker = requireNonNull(planChecker, "planChecker is null"); this.planCanonicalInfoProvider = requireNonNull(planCanonicalInfoProvider, "planCanonicalInfoProvider is null"); + this.analyzerContext = getAnalyzerContext(queryAnalyzer, idAllocator, new PlanVariableAllocator(), stateMachine.getSession()); // analyze query requireNonNull(preparedQuery, "preparedQuery is null"); stateMachine.beginSemanticAnalyzing(); - Analyzer analyzer = new Analyzer( - stateMachine.getSession(), - metadata, - sqlParser, - accessControl, - Optional.of(queryExplainer), - preparedQuery.getParameters(), - parameterExtractor(preparedQuery.getStatement(), preparedQuery.getParameters()), - warningCollector); try (TimeoutThread unused = new TimeoutThread( Thread.currentThread(), timeoutThreadExecutor, getQueryAnalyzerTimeout(getSession()))) { - this.analysis = analyzer.analyzeSemantic(preparedQuery.getStatement(), false); + this.queryAnalysis = queryAnalyzer.analyze(analyzerContext, preparedQuery); } - stateMachine.setUpdateType(analysis.getUpdateType()); - stateMachine.setExpandedQuery(analysis.getExpandedQuery()); + + stateMachine.setUpdateType(queryAnalysis.getUpdateType()); + stateMachine.setExpandedQuery(queryAnalysis.getExpandedQuery()); stateMachine.beginColumnAccessPermissionChecking(); - analyzer.checkColumnAccessPermissions(this.analysis); + queryAnalyzer.checkAccessPermissions(analyzerContext, queryAnalysis); stateMachine.endColumnAccessPermissionChecking(); // when the query finishes cache the final query info, and clear the reference to the output stage @@ -236,7 +232,7 @@ private SqlQueryExecution( this.partialResultQueryManager = requireNonNull(partialResultQueryManager, "partialResultQueryManager is null"); if (isLogInvokedFunctionNamesEnabled(getSession())) { - for (Map.Entry> entry : analysis.getInvokedFunctions().entrySet()) { + for (Map.Entry> entry : queryAnalysis.getInvokedFunctions().entrySet()) { switch (entry.getKey()) { case SCALAR: stateMachine.setScalarFunctions(entry.getValue()); @@ -454,7 +450,7 @@ public void start() timeoutThreadExecutor, getQueryAnalyzerTimeout(getSession()))) { // create logical plan for the query - plan = createLogicalPlan(); + plan = createLogicalPlanAndOptimize(); } metadata.beginQuery(getSession(), plan.getConnectors()); @@ -520,23 +516,15 @@ public void addFinalQueryInfoListener(StateChangeListener stateChange stateMachine.addQueryInfoStateChangeListener(stateChangeListener); } - private PlanRoot createLogicalPlan() + private PlanRoot createLogicalPlanAndOptimize() { try { // time analysis phase stateMachine.beginAnalysis(); - // plan query - final PlanVariableAllocator planVariableAllocator = new PlanVariableAllocator(); - LogicalPlanner logicalPlanner = new LogicalPlanner( - stateMachine.getSession(), - idAllocator, - metadata, - planVariableAllocator); - - PlanNode planNode = getSession().getRuntimeStats().profileNanos( + PlanNode planNode = stateMachine.getSession().getRuntimeStats().profileNanos( LOGICAL_PLANNER_TIME_NANOS, - () -> logicalPlanner.plan(analysis)); + () -> queryAnalyzer.plan(this.analyzerContext, queryAnalysis)); Optimizer optimizer = new Optimizer( stateMachine.getSession(), @@ -544,7 +532,7 @@ private PlanRoot createLogicalPlan() planOptimizers, planChecker, sqlParser, - planVariableAllocator, + analyzerContext.getVariableAllocator(), idAllocator, stateMachine.getWarningCollector(), statsCalculator, @@ -577,30 +565,14 @@ private PlanRoot createLogicalPlan() // record analysis time stateMachine.endAnalysis(); - boolean explainAnalyze = analysis.getStatement() instanceof Explain && ((Explain) analysis.getStatement()).isAnalyze(); - return new PlanRoot(fragmentedPlan, !explainAnalyze, extractConnectors(analysis)); + boolean explainAnalyze = queryAnalyzer.isExplainAnalyzeQuery(queryAnalysis); + return new PlanRoot(fragmentedPlan, !explainAnalyze, queryAnalyzer.extractConnectors(queryAnalysis)); } catch (StackOverflowError e) { throw new PrestoException(NOT_SUPPORTED, "statement is too large (stack overflow during analysis)", e); } } - private static Set extractConnectors(Analysis analysis) - { - ImmutableSet.Builder connectors = ImmutableSet.builder(); - - for (TableHandle tableHandle : analysis.getTables()) { - connectors.add(tableHandle.getConnectorId()); - } - - if (analysis.getInsert().isPresent()) { - TableHandle target = analysis.getInsert().get().getTarget(); - connectors.add(target.getConnectorId()); - } - - return connectors.build(); - } - private void planDistribution(PlanRoot plan) { CloseableSplitSourceProvider splitSourceProvider = new CloseableSplitSourceProvider(splitManager::getSplits); @@ -940,7 +912,8 @@ public static class SqlQueryExecutionFactory @Override public QueryExecution createQueryExecution( - BuiltInPreparedQuery preparedQuery, + AnalyzerProvider analyzerProvider, + PreparedQuery preparedQuery, QueryStateMachine stateMachine, String slug, int retryCount, @@ -952,6 +925,7 @@ public QueryExecution createQueryExecution( checkArgument(executionPolicy != null, "No execution policy %s", executionPolicy); return new SqlQueryExecution( + analyzerProvider.getQueryAnalyzer(), preparedQuery, stateMachine, slug, diff --git a/presto-main/src/main/java/com/facebook/presto/server/ServerMainModule.java b/presto-main/src/main/java/com/facebook/presto/server/ServerMainModule.java index b0b6431c5092e..dadb3597d284a 100644 --- a/presto-main/src/main/java/com/facebook/presto/server/ServerMainModule.java +++ b/presto-main/src/main/java/com/facebook/presto/server/ServerMainModule.java @@ -174,9 +174,11 @@ import com.facebook.presto.sql.SqlEnvironmentConfig; import com.facebook.presto.sql.analyzer.AnalyzerProviderManager; import com.facebook.presto.sql.analyzer.BuiltInAnalyzerProvider; +import com.facebook.presto.sql.analyzer.BuiltInQueryAnalyzer; import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer; import com.facebook.presto.sql.analyzer.FeaturesConfig; import com.facebook.presto.sql.analyzer.FeaturesConfig.SingleStreamSpillerChoice; +import com.facebook.presto.sql.analyzer.QueryExplainer; import com.facebook.presto.sql.analyzer.ViewDefinition; import com.facebook.presto.sql.gen.ExpressionCompiler; import com.facebook.presto.sql.gen.JoinCompiler; @@ -302,6 +304,8 @@ else if (serverConfig.isCoordinator()) { // analyzer binder.bind(BuiltInQueryPreparer.class).in(Scopes.SINGLETON); + newOptionalBinder(binder, QueryExplainer.class); + binder.bind(BuiltInQueryAnalyzer.class).in(Scopes.SINGLETON); binder.bind(BuiltInAnalyzerProvider.class).in(Scopes.SINGLETON); binder.bind(AnalyzerProviderManager.class).in(Scopes.SINGLETON); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/Optimizer.java b/presto-main/src/main/java/com/facebook/presto/sql/Optimizer.java index 525b6bced2542..db8b137051dde 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/Optimizer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/Optimizer.java @@ -23,6 +23,7 @@ import com.facebook.presto.cost.StatsCalculator; import com.facebook.presto.cost.StatsProvider; import com.facebook.presto.metadata.Metadata; +import com.facebook.presto.spi.VariableAllocator; import com.facebook.presto.spi.WarningCollector; import com.facebook.presto.spi.plan.PlanNode; import com.facebook.presto.spi.plan.PlanNodeIdAllocator; @@ -43,6 +44,7 @@ import static com.facebook.presto.common.RuntimeUnit.NANO; import static com.facebook.presto.sql.Optimizer.PlanStage.OPTIMIZED; import static com.facebook.presto.sql.Optimizer.PlanStage.OPTIMIZED_AND_VALIDATED; +import static com.google.common.base.Preconditions.checkState; import static java.lang.String.format; import static java.util.Objects.requireNonNull; @@ -71,7 +73,7 @@ public Optimizer( List planOptimizers, PlanChecker planChecker, SqlParser sqlParser, - PlanVariableAllocator variableAllocator, + VariableAllocator variableAllocator, PlanNodeIdAllocator idAllocator, WarningCollector warningCollector, StatsCalculator statsCalculator, @@ -83,7 +85,11 @@ public Optimizer( this.planChecker = requireNonNull(planChecker, "planChecker is null"); this.metadata = requireNonNull(metadata, "metadata is null"); this.sqlParser = requireNonNull(sqlParser, "sqlParser is null"); - this.variableAllocator = requireNonNull(variableAllocator, "variableAllocator is null"); + requireNonNull(variableAllocator, "variableAllocator is null"); + checkState(variableAllocator instanceof PlanVariableAllocator, "variableAllocator must be an instance of PlanVariableAllocator"); + + // TODO: We should cleanup redundancy between VariableAllocator and PlanVariableAllocator. + this.variableAllocator = (PlanVariableAllocator) variableAllocator; this.idAllocator = requireNonNull(idAllocator, "idAllocator is null"); this.warningCollector = requireNonNull(warningCollector, "warningCollector is null"); this.statsCalculator = requireNonNull(statsCalculator, "statsCalculator is null"); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/Analyzer.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/Analyzer.java index cd435c9bf5e9f..4c3d0d6298091 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/Analyzer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/Analyzer.java @@ -55,7 +55,8 @@ public class Analyzer private final Map, Expression> parameterLookup; private final WarningCollector warningCollector; - public Analyzer(Session session, + public Analyzer( + Session session, Metadata metadata, SqlParser sqlParser, AccessControl accessControl, @@ -69,8 +70,8 @@ public Analyzer(Session session, this.sqlParser = requireNonNull(sqlParser, "sqlParser is null"); this.accessControl = requireNonNull(accessControl, "accessControl is null"); this.queryExplainer = requireNonNull(queryExplainer, "query explainer is null"); - this.parameters = parameters; - this.parameterLookup = parameterLookup; + this.parameters = requireNonNull(parameters, "parameters is null"); + this.parameterLookup = requireNonNull(parameterLookup, "parameterLookup is null"); this.warningCollector = requireNonNull(warningCollector, "warningCollector is null"); } @@ -79,6 +80,7 @@ public Analysis analyze(Statement statement) return analyze(statement, false); } + // TODO: Remove this method once all calls are moved to analyzer interface, as this call is overloaded with analyze and columnCheckPermissions public Analysis analyze(Statement statement, boolean isDescribe) { Analysis analysis = analyzeSemantic(statement, isDescribe); diff --git a/presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/AnalyzerProviderManager.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/AnalyzerProviderManager.java similarity index 100% rename from presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/AnalyzerProviderManager.java rename to presto-main/src/main/java/com/facebook/presto/sql/analyzer/AnalyzerProviderManager.java diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerContext.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerContext.java new file mode 100644 index 0000000000000..465ca9523c69f --- /dev/null +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerContext.java @@ -0,0 +1,36 @@ +/* + * 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.analyzer; + +import com.facebook.presto.Session; +import com.facebook.presto.spi.VariableAllocator; +import com.facebook.presto.spi.analyzer.AnalyzerContext; +import com.facebook.presto.spi.plan.PlanNodeIdAllocator; + +public class BuiltInAnalyzerContext + extends AnalyzerContext +{ + private final Session session; + + public BuiltInAnalyzerContext(PlanNodeIdAllocator idAllocator, VariableAllocator variableAllocator, Session session) + { + super(idAllocator, variableAllocator); + this.session = session; + } + + public Session getSession() + { + return session; + } +} diff --git a/presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerProvider.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerProvider.java similarity index 79% rename from presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerProvider.java rename to presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerProvider.java index e0c7ca5dfba83..9f879593bd26a 100644 --- a/presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerProvider.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInAnalyzerProvider.java @@ -14,6 +14,7 @@ package com.facebook.presto.sql.analyzer; import com.facebook.presto.spi.analyzer.AnalyzerProvider; +import com.facebook.presto.spi.analyzer.QueryAnalyzer; import com.facebook.presto.spi.analyzer.QueryPreparer; import com.google.inject.Inject; @@ -24,11 +25,13 @@ public class BuiltInAnalyzerProvider { private static final String PROVIDER_NAME = "BUILTIN"; private final BuiltInQueryPreparer queryPreparer; + private final BuiltInQueryAnalyzer queryAnalyzer; @Inject - public BuiltInAnalyzerProvider(BuiltInQueryPreparer queryPreparer) + public BuiltInAnalyzerProvider(BuiltInQueryPreparer queryPreparer, BuiltInQueryAnalyzer queryAnalyzer) { this.queryPreparer = requireNonNull(queryPreparer, "queryPreparer is null"); + this.queryAnalyzer = requireNonNull(queryAnalyzer, "queryAnalyzer is null"); } @Override @@ -42,4 +45,10 @@ public QueryPreparer getQueryPreparer() { return queryPreparer; } + + @Override + public QueryAnalyzer getQueryAnalyzer() + { + return queryAnalyzer; + } } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInQueryAnalyzer.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInQueryAnalyzer.java new file mode 100644 index 0000000000000..fbc0184b2d5a4 --- /dev/null +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/BuiltInQueryAnalyzer.java @@ -0,0 +1,138 @@ +/* + * 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.analyzer; + +import com.facebook.presto.Session; +import com.facebook.presto.common.analyzer.PreparedQuery; +import com.facebook.presto.metadata.Metadata; +import com.facebook.presto.spi.ConnectorId; +import com.facebook.presto.spi.TableHandle; +import com.facebook.presto.spi.VariableAllocator; +import com.facebook.presto.spi.analyzer.AnalyzerContext; +import com.facebook.presto.spi.analyzer.QueryAnalysis; +import com.facebook.presto.spi.analyzer.QueryAnalyzer; +import com.facebook.presto.spi.plan.PlanNode; +import com.facebook.presto.spi.plan.PlanNodeIdAllocator; +import com.facebook.presto.spi.security.AccessControl; +import com.facebook.presto.sql.parser.SqlParser; +import com.facebook.presto.sql.planner.LogicalPlanner; +import com.facebook.presto.sql.tree.Explain; +import com.google.common.collect.ImmutableSet; +import com.google.inject.Inject; + +import java.util.Optional; +import java.util.Set; + +import static com.facebook.presto.SystemSessionProperties.isCheckAccessControlOnUtilizedColumnsOnly; +import static com.facebook.presto.SystemSessionProperties.isCheckAccessControlWithSubfields; +import static com.facebook.presto.sql.analyzer.utils.ParameterUtils.parameterExtractor; +import static com.google.common.base.Preconditions.checkState; +import static java.util.Objects.requireNonNull; + +public class BuiltInQueryAnalyzer + implements QueryAnalyzer +{ + private final Metadata metadata; + private final SqlParser sqlParser; + private final AccessControl accessControl; + private final Optional queryExplainer; + + @Inject + public BuiltInQueryAnalyzer(Metadata metadata, SqlParser sqlParser, AccessControl accessControl, Optional queryExplainer) + { + this.metadata = requireNonNull(metadata, "metadata is null"); + this.sqlParser = requireNonNull(sqlParser, "sqlParser is null"); + this.accessControl = requireNonNull(accessControl, "accessControl is null"); + this.queryExplainer = requireNonNull(queryExplainer, "query explainer is null"); + } + + public static BuiltInAnalyzerContext getBuiltInAnalyzerContext(PlanNodeIdAllocator idAllocator, VariableAllocator variableAllocator, Session session) + { + return new BuiltInAnalyzerContext(idAllocator, variableAllocator, session); + } + + @Override + public QueryAnalysis analyze(AnalyzerContext analyzerContext, PreparedQuery preparedQuery) + { + requireNonNull(preparedQuery, "preparedQuery is null"); + + checkState(analyzerContext instanceof BuiltInAnalyzerContext, "analyzerContext should be an instance of BuiltInAnalyzerContext"); + checkState(preparedQuery instanceof BuiltInQueryPreparer.BuiltInPreparedQuery, "Unsupported prepared query type: %s", preparedQuery.getClass().getSimpleName()); + + BuiltInQueryPreparer.BuiltInPreparedQuery builtInPreparedQuery = (BuiltInQueryPreparer.BuiltInPreparedQuery) preparedQuery; + Session session = ((BuiltInAnalyzerContext) analyzerContext).getSession(); + + Analyzer analyzer = new Analyzer( + session, + metadata, + sqlParser, + accessControl, + queryExplainer, + builtInPreparedQuery.getParameters(), + parameterExtractor(builtInPreparedQuery.getStatement(), builtInPreparedQuery.getParameters()), + session.getWarningCollector()); + + Analysis analysis = analyzer.analyzeSemantic(((BuiltInQueryPreparer.BuiltInPreparedQuery) preparedQuery).getStatement(), false); + return new BuiltInQueryAnalysis(analysis); + } + + @Override + public PlanNode plan(AnalyzerContext analyzerContext, QueryAnalysis queryAnalysis) + { + checkState(analyzerContext instanceof BuiltInAnalyzerContext, "analyzerContext should be an instance of BuiltInAnalyzerContext"); + return new LogicalPlanner(((BuiltInAnalyzerContext) analyzerContext).getSession(), analyzerContext.getIdAllocator(), metadata, analyzerContext.getVariableAllocator()).plan(((BuiltInQueryAnalysis) queryAnalysis).getAnalysis()); + } + + @Override + public void checkAccessPermissions(AnalyzerContext analyzerContext, QueryAnalysis queryAnalysis) + { + checkState(analyzerContext instanceof BuiltInAnalyzerContext, "analyzerContext should be an instance of BuiltInAnalyzerContext"); + Session session = ((BuiltInAnalyzerContext) analyzerContext).getSession(); + BuiltInQueryAnalysis builtInQueryAnalysis = (BuiltInQueryAnalysis) queryAnalysis; + builtInQueryAnalysis.getAnalysis().getTableColumnAndSubfieldReferencesForAccessControl(isCheckAccessControlOnUtilizedColumnsOnly(session), isCheckAccessControlWithSubfields(session)) + .forEach((accessControlInfo, tableColumnReferences) -> + tableColumnReferences.forEach((tableName, columns) -> + accessControlInfo.getAccessControl().checkCanSelectFromColumns( + session.getRequiredTransactionId(), + accessControlInfo.getIdentity(), + session.getAccessControlContext(), + tableName, + columns))); + } + + @Override + public boolean isExplainAnalyzeQuery(QueryAnalysis queryAnalysis) + { + Analysis analysis = ((BuiltInQueryAnalysis) queryAnalysis).getAnalysis(); + return analysis.getStatement() instanceof Explain && ((Explain) analysis.getStatement()).isAnalyze(); + } + + @Override + public Set extractConnectors(QueryAnalysis queryAnalysis) + { + Analysis analysis = ((BuiltInQueryAnalysis) queryAnalysis).getAnalysis(); + ImmutableSet.Builder connectors = ImmutableSet.builder(); + + for (TableHandle tableHandle : analysis.getTables()) { + connectors.add(tableHandle.getConnectorId()); + } + + if (analysis.getInsert().isPresent()) { + TableHandle target = analysis.getInsert().get().getTarget(); + connectors.add(target.getConnectorId()); + } + + return connectors.build(); + } +} diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/LogicalPlanner.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/LogicalPlanner.java index bf2de4623eeed..91fef1e31a14d 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/LogicalPlanner.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/LogicalPlanner.java @@ -26,6 +26,7 @@ import com.facebook.presto.spi.PrestoException; import com.facebook.presto.spi.TableHandle; import com.facebook.presto.spi.TableMetadata; +import com.facebook.presto.spi.VariableAllocator; import com.facebook.presto.spi.plan.AggregationNode; import com.facebook.presto.spi.plan.Assignments; import com.facebook.presto.spi.plan.LimitNode; @@ -113,13 +114,17 @@ public LogicalPlanner( Session session, PlanNodeIdAllocator idAllocator, Metadata metadata, - PlanVariableAllocator variableAllocator) + VariableAllocator variableAllocator) { this.session = requireNonNull(session, "session is null"); this.idAllocator = requireNonNull(idAllocator, "idAllocator is null"); this.metadata = requireNonNull(metadata, "metadata is null"); - this.variableAllocator = requireNonNull(variableAllocator, "variableAllocator is null"); - this.statisticsAggregationPlanner = new StatisticsAggregationPlanner(variableAllocator, metadata.getFunctionAndTypeManager().getFunctionAndTypeResolver()); + requireNonNull(variableAllocator, "variableAllocator is null"); + checkState(variableAllocator instanceof PlanVariableAllocator, "variableAllocator should be instance of PlanVariableAllocator"); + + // TODO: We should cleanup redundancy between VariableAllocator and PlanVariableAllocator. + this.variableAllocator = (PlanVariableAllocator) variableAllocator; + this.statisticsAggregationPlanner = new StatisticsAggregationPlanner(this.variableAllocator, metadata.getFunctionAndTypeManager().getFunctionAndTypeResolver()); } public PlanNode plan(Analysis analysis) diff --git a/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java b/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java index bc9328d75881c..464f19c02896f 100644 --- a/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java +++ b/presto-main/src/main/java/com/facebook/presto/testing/LocalQueryRunner.java @@ -127,7 +127,9 @@ import com.facebook.presto.spi.PageSorter; import com.facebook.presto.spi.Plugin; import com.facebook.presto.spi.WarningCollector; +import com.facebook.presto.spi.analyzer.AnalyzerContext; import com.facebook.presto.spi.analyzer.AnalyzerOptions; +import com.facebook.presto.spi.analyzer.QueryAnalysis; import com.facebook.presto.spi.connector.ConnectorFactory; import com.facebook.presto.spi.connector.ConnectorSplitManager.SplitSchedulingStrategy; import com.facebook.presto.spi.eventlistener.EventListener; @@ -149,10 +151,9 @@ import com.facebook.presto.split.SplitManager; import com.facebook.presto.split.SplitSource; import com.facebook.presto.sql.Optimizer; -import com.facebook.presto.sql.analyzer.Analysis; -import com.facebook.presto.sql.analyzer.Analyzer; import com.facebook.presto.sql.analyzer.AnalyzerProviderManager; import com.facebook.presto.sql.analyzer.BuiltInAnalyzerProvider; +import com.facebook.presto.sql.analyzer.BuiltInQueryAnalyzer; import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer; import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer.BuiltInPreparedQuery; import com.facebook.presto.sql.analyzer.FeaturesConfig; @@ -169,7 +170,6 @@ import com.facebook.presto.sql.planner.ConnectorPlanOptimizerManager; import com.facebook.presto.sql.planner.LocalExecutionPlanner; import com.facebook.presto.sql.planner.LocalExecutionPlanner.LocalExecutionPlan; -import com.facebook.presto.sql.planner.LogicalPlanner; import com.facebook.presto.sql.planner.NodePartitioningManager; import com.facebook.presto.sql.planner.PartitioningProviderManager; import com.facebook.presto.sql.planner.Plan; @@ -259,7 +259,6 @@ import static com.facebook.presto.spi.connector.ConnectorSplitManager.SplitSchedulingStrategy.UNGROUPED_SCHEDULING; import static com.facebook.presto.spi.connector.NotPartitionedPartitionHandle.NOT_PARTITIONED; import static com.facebook.presto.sql.Optimizer.PlanStage.OPTIMIZED_AND_VALIDATED; -import static com.facebook.presto.sql.analyzer.utils.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.planner.optimizations.PlanNodeSearcher.searchFrom; import static com.facebook.presto.sql.testing.TreeAssertions.assertFormattedSql; import static com.facebook.presto.testing.TestingSession.TESTING_CATALOG; @@ -267,6 +266,7 @@ import static com.facebook.presto.transaction.TransactionBuilder.transaction; import static com.facebook.presto.util.AnalyzerUtil.createAnalyzerOptions; import static com.facebook.presto.util.AnalyzerUtil.createParsingOptions; +import static com.facebook.presto.util.AnalyzerUtil.getAnalyzerContext; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; @@ -476,13 +476,16 @@ private LocalQueryRunner(Session defaultSession, FeaturesConfig featuresConfig, new TransactionsSystemTable(metadata.getFunctionAndTypeManager(), transactionManager)), ImmutableSet.of()); + BuiltInQueryAnalyzer queryAnalyzer = new BuiltInQueryAnalyzer(metadata, sqlParser, accessControl, Optional.empty()); + BuiltInAnalyzerProvider analyzerProvider = new BuiltInAnalyzerProvider(new BuiltInQueryPreparer(sqlParser), queryAnalyzer); + this.pluginManager = new PluginManager( nodeInfo, new PluginManagerConfig(), connectorManager, metadata, new NoOpResourceGroupManager(), - new AnalyzerProviderManager(new BuiltInAnalyzerProvider(new BuiltInQueryPreparer(sqlParser))), + new AnalyzerProviderManager(analyzerProvider), accessControl, new PasswordAuthenticatorManager(), new EventListenerManager(), @@ -1056,20 +1059,17 @@ public Plan createPlan(Session session, @Language("SQL") String sql, List logicalPlanner.plan(analysis)); + () -> queryAnalyzer.plan(analyzerContext, queryAnalysis)); Optimizer optimizer = new Optimizer( session, @@ -1077,7 +1077,7 @@ public Plan createPlan(Session session, @Language("SQL") String sql, List getExpandedQuery(); + + /** + * Returns function names based on the kinds (scalar, aggregate and window). + */ + Map> getInvokedFunctions(); +} diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/analyzer/QueryAnalyzer.java b/presto-spi/src/main/java/com/facebook/presto/spi/analyzer/QueryAnalyzer.java new file mode 100644 index 0000000000000..a7d0ac33ab0c8 --- /dev/null +++ b/presto-spi/src/main/java/com/facebook/presto/spi/analyzer/QueryAnalyzer.java @@ -0,0 +1,62 @@ +/* + * 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.spi.analyzer; + +import com.facebook.presto.common.analyzer.PreparedQuery; +import com.facebook.presto.spi.ConnectorId; +import com.facebook.presto.spi.plan.PlanNode; + +import java.util.Set; + +/** + * The QueryAnalyzer interface should be implemented by respective analyzer to provide various analyzer related functionalities. + */ +public interface QueryAnalyzer +{ + /** + * Analyzes a prepared query in the given analyzer context. + * + * @param analyzerContext analyzer context which stores various information used by analyzer + * @param preparedQuery prepared query which needs to be analyzed + * @return Query analysis object which stores various semantic analysis of the query + */ + QueryAnalysis analyze(AnalyzerContext analyzerContext, PreparedQuery preparedQuery); + + /** + * Check access permission for the various tables and columns used in the query. + * + * @param analyzerContext analyzerContext analyzer context which stores various information used by analyzer + * @param queryAnalysis query analysis on which the access permissions needs to be checked + */ + void checkAccessPermissions(AnalyzerContext analyzerContext, QueryAnalysis queryAnalysis); + + /** + * Create logical plan for a given query analysis. + * + * @param analyzerContext analyzerContext analyzer context which stores various information used by analyzer + * @param queryAnalysis query analysis for which logical plan needs to be created + * @return root logical plan node created from the given query analysis + */ + PlanNode plan(AnalyzerContext analyzerContext, QueryAnalysis queryAnalysis); + + /** + * Returns whether the given QueryAnalysis represents an "EXPLAIN ANALYZE" query. + */ + boolean isExplainAnalyzeQuery(QueryAnalysis queryAnalysis); + + /** + * Extracts the set of ConnectorIds used in the given QueryAnalysis. + */ + Set extractConnectors(QueryAnalysis queryAnalysis); +} diff --git a/presto-spi/src/main/java/com/facebook/presto/spi/analyzer/QueryPreparer.java b/presto-spi/src/main/java/com/facebook/presto/spi/analyzer/QueryPreparer.java index e15aa8137d32b..0e1167bc2da27 100644 --- a/presto-spi/src/main/java/com/facebook/presto/spi/analyzer/QueryPreparer.java +++ b/presto-spi/src/main/java/com/facebook/presto/spi/analyzer/QueryPreparer.java @@ -29,7 +29,7 @@ public interface QueryPreparer * @param query query string which needs to be prepared * @param preparedStatements existing prepared query statements * @param warningCollector Warning collector to collect various warnings - * @return preared query object + * @return prepared query object */ PreparedQuery prepareQuery(AnalyzerOptions analyzerOptions, String query, Map preparedStatements, WarningCollector warningCollector); }