Skip to content

Commit 2d2b03d

Browse files
committed
Support and handle call distributed procedure statement in preparer
1 parent 5b2c29d commit 2d2b03d

File tree

10 files changed

+204
-29
lines changed

10 files changed

+204
-29
lines changed

presto-analyzer/src/main/java/com/facebook/presto/sql/analyzer/BuiltInQueryPreparer.java

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,25 @@
1313
*/
1414
package com.facebook.presto.sql.analyzer;
1515

16+
import com.facebook.presto.common.QualifiedObjectName;
1617
import com.facebook.presto.common.analyzer.PreparedQuery;
1718
import com.facebook.presto.common.resourceGroups.QueryType;
19+
import com.facebook.presto.spi.ConnectorId;
1820
import com.facebook.presto.spi.PrestoException;
1921
import com.facebook.presto.spi.PrestoWarning;
22+
import com.facebook.presto.spi.SchemaTableName;
2023
import com.facebook.presto.spi.WarningCollector;
2124
import com.facebook.presto.spi.analyzer.AnalyzerOptions;
2225
import com.facebook.presto.spi.analyzer.QueryPreparer;
26+
import com.facebook.presto.spi.procedure.IProcedureRegistry;
2327
import com.facebook.presto.sql.analyzer.utils.StatementUtils;
2428
import com.facebook.presto.sql.parser.SqlParser;
29+
import com.facebook.presto.sql.tree.Call;
2530
import com.facebook.presto.sql.tree.Execute;
2631
import com.facebook.presto.sql.tree.Explain;
2732
import com.facebook.presto.sql.tree.ExplainType;
2833
import com.facebook.presto.sql.tree.Expression;
34+
import com.facebook.presto.sql.tree.QualifiedName;
2935
import com.facebook.presto.sql.tree.Statement;
3036
import com.google.common.collect.ImmutableList;
3137
import com.google.common.collect.ImmutableSet;
@@ -37,13 +43,15 @@
3743
import java.util.Optional;
3844

3945
import static com.facebook.presto.common.WarningHandlingLevel.AS_ERROR;
46+
import static com.facebook.presto.common.resourceGroups.QueryType.CALL_DISTRIBUTED_PROCEDURE;
4047
import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND;
4148
import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED;
4249
import static com.facebook.presto.spi.StandardErrorCode.WARNING_AS_ERROR;
4350
import static com.facebook.presto.sql.SqlFormatter.formatSql;
4451
import static com.facebook.presto.sql.analyzer.ConstantExpressionVerifier.verifyExpressionIsConstant;
4552
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.INVALID_PARAMETER_USAGE;
4653
import static com.facebook.presto.sql.analyzer.utils.AnalyzerUtil.createParsingOptions;
54+
import static com.facebook.presto.sql.analyzer.utils.MetadataUtils.createQualifiedObjectName;
4755
import static com.facebook.presto.sql.analyzer.utils.ParameterExtractor.getParameterCount;
4856
import static com.facebook.presto.sql.tree.ExplainType.Type.VALIDATE;
4957
import static java.lang.String.format;
@@ -57,11 +65,15 @@ public class BuiltInQueryPreparer
5765
implements QueryPreparer
5866
{
5967
private final SqlParser sqlParser;
68+
private final IProcedureRegistry procedureRegistry;
6069

6170
@Inject
62-
public BuiltInQueryPreparer(SqlParser sqlParser)
71+
public BuiltInQueryPreparer(
72+
SqlParser sqlParser,
73+
IProcedureRegistry procedureRegistry)
6374
{
6475
this.sqlParser = requireNonNull(sqlParser, "sqlParser is null");
76+
this.procedureRegistry = requireNonNull(procedureRegistry, "procedureRegistry is null");
6577
}
6678

6779
@Override
@@ -88,6 +100,17 @@ public BuiltInPreparedQuery prepareQuery(AnalyzerOptions analyzerOptions, Statem
88100
statement = sqlParser.createStatement(query, createParsingOptions(analyzerOptions));
89101
}
90102

103+
Optional<QualifiedObjectName> distributedProcedureName = Optional.empty();
104+
if (statement instanceof Call) {
105+
QualifiedName qualifiedName = ((Call) statement).getName();
106+
QualifiedObjectName qualifiedObjectName = createQualifiedObjectName(analyzerOptions.getSessionCatalogName(), analyzerOptions.getSessionSchemaName(), statement, qualifiedName);
107+
if (procedureRegistry.isDistributedProcedure(
108+
new ConnectorId(qualifiedObjectName.getCatalogName()),
109+
new SchemaTableName(qualifiedObjectName.getSchemaName(), qualifiedObjectName.getObjectName()))) {
110+
distributedProcedureName = Optional.of(qualifiedObjectName);
111+
}
112+
}
113+
91114
if (statement instanceof Explain && ((Explain) statement).isAnalyze()) {
92115
Statement innerStatement = ((Explain) statement).getStatement();
93116
Optional<QueryType> innerQueryType = StatementUtils.getQueryType(innerStatement.getClass());
@@ -104,7 +127,7 @@ public BuiltInPreparedQuery prepareQuery(AnalyzerOptions analyzerOptions, Statem
104127
if (analyzerOptions.isLogFormattedQueryEnabled()) {
105128
formattedQuery = Optional.of(getFormattedQuery(statement, parameters));
106129
}
107-
return new BuiltInPreparedQuery(wrappedStatement, statement, parameters, formattedQuery, prepareSql);
130+
return new BuiltInPreparedQuery(wrappedStatement, statement, parameters, formattedQuery, prepareSql, distributedProcedureName);
108131
}
109132

110133
private static String getFormattedQuery(Statement statement, List<Expression> parameters)
@@ -132,13 +155,19 @@ public static class BuiltInPreparedQuery
132155
private final Statement statement;
133156
private final Statement wrappedStatement;
134157
private final List<Expression> parameters;
158+
private final Optional<QualifiedObjectName> distributedProcedureName;
135159

136-
public BuiltInPreparedQuery(Statement wrappedStatement, Statement statement, List<Expression> parameters, Optional<String> formattedQuery, Optional<String> prepareSql)
160+
public BuiltInPreparedQuery(
161+
Statement wrappedStatement,
162+
Statement statement, List<Expression> parameters,
163+
Optional<String> formattedQuery, Optional<String> prepareSql,
164+
Optional<QualifiedObjectName> distributedProcedureName)
137165
{
138166
super(formattedQuery, prepareSql);
139167
this.wrappedStatement = requireNonNull(wrappedStatement, "wrappedStatement is null");
140168
this.statement = requireNonNull(statement, "statement is null");
141169
this.parameters = ImmutableList.copyOf(requireNonNull(parameters, "parameters is null"));
170+
this.distributedProcedureName = requireNonNull(distributedProcedureName, "distributedProcedureName is null");
142171
}
143172

144173
public Statement getStatement()
@@ -158,9 +187,17 @@ public List<Expression> getParameters()
158187

159188
public Optional<QueryType> getQueryType()
160189
{
190+
if (getDistributedProcedureName().isPresent()) {
191+
return Optional.of(CALL_DISTRIBUTED_PROCEDURE);
192+
}
161193
return StatementUtils.getQueryType(statement.getClass());
162194
}
163195

196+
public Optional<QualifiedObjectName> getDistributedProcedureName()
197+
{
198+
return this.distributedProcedureName;
199+
}
200+
164201
public boolean isTransactionControlStatement()
165202
{
166203
return StatementUtils.isTransactionControlStatement(getStatement());
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package com.facebook.presto.sql.analyzer.utils;
15+
16+
import com.facebook.presto.common.QualifiedObjectName;
17+
import com.facebook.presto.spi.PrestoException;
18+
import com.facebook.presto.sql.analyzer.SemanticException;
19+
import com.facebook.presto.sql.tree.Node;
20+
import com.facebook.presto.sql.tree.QualifiedName;
21+
import com.google.common.collect.Lists;
22+
23+
import java.util.List;
24+
import java.util.Optional;
25+
26+
import static com.facebook.presto.spi.StandardErrorCode.SYNTAX_ERROR;
27+
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.CATALOG_NOT_SPECIFIED;
28+
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.SCHEMA_NOT_SPECIFIED;
29+
import static java.lang.String.format;
30+
import static java.util.Objects.requireNonNull;
31+
32+
public class MetadataUtils
33+
{
34+
private MetadataUtils()
35+
{}
36+
37+
public static QualifiedObjectName createQualifiedObjectName(Optional<String> sessionCatalogName, Optional<String> sessionSchemaName, Node node, QualifiedName name)
38+
{
39+
requireNonNull(sessionCatalogName, "sessionCatalogName is null");
40+
requireNonNull(sessionSchemaName, "sessionSchemaName is null");
41+
requireNonNull(name, "name is null");
42+
if (name.getParts().size() > 3) {
43+
throw new PrestoException(SYNTAX_ERROR, format("Too many dots in table name: %s", name));
44+
}
45+
46+
List<String> parts = Lists.reverse(name.getParts());
47+
String objectName = parts.get(0);
48+
String schemaName = (parts.size() > 1) ? parts.get(1) : sessionSchemaName.orElseThrow(() ->
49+
new SemanticException(SCHEMA_NOT_SPECIFIED, node, "Schema must be specified when session schema is not set"));
50+
String catalogName = (parts.size() > 2) ? parts.get(2) : sessionCatalogName.orElseThrow(() ->
51+
new SemanticException(CATALOG_NOT_SPECIFIED, node, "Catalog must be specified when session catalog is not set"));
52+
53+
return new QualifiedObjectName(catalogName, schemaName, objectName);
54+
}
55+
}

presto-analyzer/src/test/java/com/facebook/presto/sql/analyzer/TestBuiltInQueryPreparer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import com.facebook.presto.spi.PrestoException;
1717
import com.facebook.presto.spi.WarningCollector;
1818
import com.facebook.presto.spi.analyzer.AnalyzerOptions;
19+
import com.facebook.presto.spi.procedure.IProcedureRegistry;
20+
import com.facebook.presto.spi.procedure.NoopProcedureRegistry;
1921
import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer.BuiltInPreparedQuery;
2022
import com.facebook.presto.sql.parser.SqlParser;
2123
import com.facebook.presto.sql.tree.AllColumns;
@@ -37,7 +39,8 @@
3739
public class TestBuiltInQueryPreparer
3840
{
3941
private static final SqlParser SQL_PARSER = new SqlParser();
40-
private static final BuiltInQueryPreparer QUERY_PREPARER = new BuiltInQueryPreparer(SQL_PARSER);
42+
private static final IProcedureRegistry RROCEDURE_REGISTRY = new NoopProcedureRegistry();
43+
private static final BuiltInQueryPreparer QUERY_PREPARER = new BuiltInQueryPreparer(SQL_PARSER, RROCEDURE_REGISTRY);
4144
private static final Map<String, String> emptyPreparedStatements = ImmutableMap.of();
4245
private static final AnalyzerOptions testAnalyzerOptions = AnalyzerOptions.builder().build();
4346

presto-common/src/main/java/com/facebook/presto/common/resourceGroups/QueryType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ public enum QueryType
2727
INSERT(6),
2828
SELECT(7),
2929
CONTROL(8),
30-
UPDATE(9)
30+
UPDATE(9),
31+
CALL_DISTRIBUTED_PROCEDURE(10),
3132
/**/;
3233

3334
private final int value;

presto-main/src/main/java/com/facebook/presto/metadata/MetadataUtil.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,24 @@
2121
import com.facebook.presto.spi.ConnectorId;
2222
import com.facebook.presto.spi.ConnectorTableHandle;
2323
import com.facebook.presto.spi.ConnectorTableMetadata;
24-
import com.facebook.presto.spi.PrestoException;
2524
import com.facebook.presto.spi.SchemaTableName;
2625
import com.facebook.presto.spi.TableHandle;
2726
import com.facebook.presto.spi.connector.ConnectorMetadata;
2827
import com.facebook.presto.spi.connector.ConnectorTableVersion;
2928
import com.facebook.presto.spi.security.PrestoPrincipal;
3029
import com.facebook.presto.sql.analyzer.SemanticException;
30+
import com.facebook.presto.sql.analyzer.utils.MetadataUtils;
3131
import com.facebook.presto.sql.tree.GrantorSpecification;
3232
import com.facebook.presto.sql.tree.Node;
3333
import com.facebook.presto.sql.tree.PrincipalSpecification;
3434
import com.facebook.presto.sql.tree.QualifiedName;
3535
import com.facebook.presto.transaction.TransactionManager;
3636
import com.google.common.collect.ImmutableList;
3737
import com.google.common.collect.ImmutableMap;
38-
import com.google.common.collect.Lists;
3938

4039
import java.util.List;
4140
import java.util.Optional;
4241

43-
import static com.facebook.presto.spi.StandardErrorCode.SYNTAX_ERROR;
4442
import static com.facebook.presto.spi.security.PrincipalType.ROLE;
4543
import static com.facebook.presto.spi.security.PrincipalType.USER;
4644
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.CATALOG_NOT_SPECIFIED;
@@ -143,19 +141,7 @@ public static CatalogSchemaName createCatalogSchemaName(Session session, Node no
143141
public static QualifiedObjectName createQualifiedObjectName(Session session, Node node, QualifiedName name)
144142
{
145143
requireNonNull(session, "session is null");
146-
requireNonNull(name, "name is null");
147-
if (name.getParts().size() > 3) {
148-
throw new PrestoException(SYNTAX_ERROR, format("Too many dots in table name: %s", name));
149-
}
150-
151-
List<String> parts = Lists.reverse(name.getParts());
152-
String objectName = parts.get(0);
153-
String schemaName = (parts.size() > 1) ? parts.get(1) : session.getSchema().orElseThrow(() ->
154-
new SemanticException(SCHEMA_NOT_SPECIFIED, node, "Schema must be specified when session schema is not set"));
155-
String catalogName = (parts.size() > 2) ? parts.get(2) : session.getCatalog().orElseThrow(() ->
156-
new SemanticException(CATALOG_NOT_SPECIFIED, node, "Catalog must be specified when session catalog is not set"));
157-
158-
return new QualifiedObjectName(catalogName, schemaName, objectName);
144+
return MetadataUtils.createQualifiedObjectName(session.getCatalog(), session.getSchema(), node, name);
159145
}
160146

161147
public static QualifiedName createQualifiedName(QualifiedObjectName name)

presto-main/src/main/java/com/facebook/presto/sql/rewrite/ExplainRewrite.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.facebook.presto.metadata.Metadata;
1818
import com.facebook.presto.spi.WarningCollector;
1919
import com.facebook.presto.spi.analyzer.AnalyzerOptions;
20+
import com.facebook.presto.spi.procedure.NoopProcedureRegistry;
2021
import com.facebook.presto.spi.security.AccessControl;
2122
import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer;
2223
import com.facebook.presto.sql.analyzer.BuiltInQueryPreparer.BuiltInPreparedQuery;
@@ -80,7 +81,7 @@ public Visitor(
8081
WarningCollector warningCollector)
8182
{
8283
this.session = requireNonNull(session, "session is null");
83-
this.queryPreparer = new BuiltInQueryPreparer(requireNonNull(parser, "queryPreparer is null"));
84+
this.queryPreparer = new BuiltInQueryPreparer(requireNonNull(parser, "queryPreparer is null"), new NoopProcedureRegistry());
8485
this.queryExplainer = requireNonNull(queryExplainer, "queryExplainer is null");
8586
this.warningCollector = requireNonNull(warningCollector, "warningCollector is null");
8687
}

0 commit comments

Comments
 (0)