Skip to content

Commit

Permalink
Add QueryPreparer interface
Browse files Browse the repository at this point in the history
Adding a QueryPreparer interface, all analyzers should implement this
interface to support query prepare functionality.
  • Loading branch information
jainxrohit authored and rschlussel committed Oct 28, 2022
1 parent bc873b8 commit e97afc8
Show file tree
Hide file tree
Showing 24 changed files with 374 additions and 91 deletions.
13 changes: 9 additions & 4 deletions presto-analyzer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,25 @@
<artifactId>presto-parser</artifactId>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>

<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>

<!-- for testing -->
Expand Down
Original file line number Diff line number Diff line change
@@ -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.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.multibindings.MapBinder;

import static com.facebook.presto.sql.analyzer.AnalyzerType.BUILTIN;
import static com.facebook.presto.sql.analyzer.AnalyzerType.NATIVE;
import static com.google.inject.Scopes.SINGLETON;

public class AnalyzerModule
implements Module
{
@Override
public void configure(Binder binder)
{
MapBinder<AnalyzerType, QueryPreparer> queryPreparersByType = MapBinder.newMapBinder(binder, AnalyzerType.class, QueryPreparer.class);
queryPreparersByType.addBinding(BUILTIN).to(BuiltInQueryPreparer.class).in(SINGLETON);
queryPreparersByType.addBinding(NATIVE).to(NativeQueryPreparer.class).in(SINGLETON);

binder.bind(AnalyzerProvider.class).in(SINGLETON);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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.PrestoException;

import javax.inject.Inject;

import java.util.Map;

import static com.facebook.presto.spi.StandardErrorCode.UNSUPPORTED_ANALYZER_TYPE;
import static java.util.Objects.requireNonNull;

/**
* This class provides various interfaces for various functionalities in the analyzer.
* This class can be used to get a specific analyzer implementation for a given analyzer type.
*/
public class AnalyzerProvider
{
private final Map<AnalyzerType, QueryPreparer> queryPreparersByType;

@Inject
public AnalyzerProvider(Map<AnalyzerType, QueryPreparer> queryPreparersByType)
{
this.queryPreparersByType = requireNonNull(queryPreparersByType, "queryPreparersByType is null");
}

public QueryPreparer getQueryPreparer(AnalyzerType analyzerType)
{
requireNonNull(analyzerType, "AnalyzerType is null");
if (queryPreparersByType.containsKey(analyzerType)) {
return queryPreparersByType.get(analyzerType);
}

throw new PrestoException(UNSUPPORTED_ANALYZER_TYPE, "Unsupported analyzer type: " + analyzerType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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;

/**
* Presto supports various analyzers to support various analyzer functionality.
*/
public enum AnalyzerType
{
/**
* This is for builtin analyzer. This provides default antlr based parser and inbuilt analyzer to produce Analysis object.
*/
BUILTIN,
/**
* This is for C++ based parser and analyzer. This analyzer is currently under development.
* Please avoid using it, as it may corrupt the session.
*/
NATIVE
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;

/**
* This query preparer provides builtin functionality. It leverages builtin parser and analyzer.
*/
public class BuiltInQueryPreparer
implements QueryPreparer
{
private final SqlParser sqlParser;

Expand All @@ -55,6 +59,7 @@ public BuiltInQueryPreparer(SqlParser sqlParser)
this.sqlParser = requireNonNull(sqlParser, "sqlParser is null");
}

@Override
public BuiltInPreparedQuery prepareQuery(AnalyzerOptions analyzerOptions, String query, Map<String, String> preparedStatements, WarningCollector warningCollector)
throws ParsingException, PrestoException, SemanticException
{
Expand Down Expand Up @@ -119,20 +124,18 @@ private static void validateParameters(Statement node, List<Expression> paramete
}

public static class BuiltInPreparedQuery
extends PreparedQuery
{
private final Statement statement;
private final Statement wrappedStatement;
private final List<Expression> parameters;
private final Optional<String> formattedQuery;
private final Optional<String> prepareSql;

public BuiltInPreparedQuery(Statement wrappedStatement, Statement statement, List<Expression> parameters, Optional<String> formattedQuery, Optional<String> prepareSql)
{
super(formattedQuery, prepareSql);
this.wrappedStatement = requireNonNull(wrappedStatement, "wrappedStatement is null");
this.statement = requireNonNull(statement, "statement is null");
this.parameters = ImmutableList.copyOf(requireNonNull(parameters, "parameters is null"));
this.formattedQuery = requireNonNull(formattedQuery, "formattedQuery is null");
this.prepareSql = requireNonNull(prepareSql, "prepareSql is null");
}

public Statement getStatement()
Expand All @@ -150,14 +153,14 @@ public List<Expression> getParameters()
return parameters;
}

public Optional<String> getFormattedQuery()
public Optional<QueryType> getQueryType()
{
return formattedQuery;
return StatementUtils.getQueryType(statement.getClass());
}

public Optional<String> getPrepareSql()
public boolean isTransactionControlStatement()
{
return prepareSql;
return StatementUtils.isTransactionControlStatement(getStatement());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 java.util.Optional;

public class NativePreparedQuery
extends PreparedQuery
{
// TODO: Dummy implementation. This should be replaced with native implementation.
public NativePreparedQuery(Optional<String> formattedQuery, Optional<String> prepareSql)
{
super(formattedQuery, prepareSql);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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.PrestoException;
import com.facebook.presto.spi.WarningCollector;
import com.facebook.presto.sql.parser.ParsingException;

import java.util.Map;
import java.util.Optional;

public class NativeQueryPreparer
implements QueryPreparer
{
@Override
public PreparedQuery prepareQuery(AnalyzerOptions analyzerOptions, String query, Map<String, String> preparedStatements, WarningCollector warningCollector)
throws ParsingException, PrestoException, SemanticException
{
return new NativePreparedQuery(Optional.of(query), Optional.of(query));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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.common.resourceGroups.QueryType;

import java.util.Optional;

import static java.util.Objects.requireNonNull;

public abstract class PreparedQuery
{
private final Optional<String> formattedQuery;
private final Optional<String> prepareSql;

public PreparedQuery(Optional<String> formattedQuery, Optional<String> prepareSql)
{
this.formattedQuery = requireNonNull(formattedQuery, "formattedQuery is null");
this.prepareSql = requireNonNull(prepareSql, "prepareSql is null");
}

public Optional<String> getFormattedQuery()
{
return formattedQuery;
}

public Optional<String> getPrepareSql()
{
return prepareSql;
}

public Optional<QueryType> getQueryType()
{
throw new UnsupportedOperationException("getQueryType method is not supported!");
}

public boolean isTransactionControlStatement()
{
throw new UnsupportedOperationException("isTransactionControlStatement method is not supported!");
}

public Class<?> getStatementClass()
{
throw new UnsupportedOperationException("getStatementClass method is not supported!");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.PrestoException;
import com.facebook.presto.spi.WarningCollector;
import com.facebook.presto.sql.parser.ParsingException;

import java.util.Map;

/**
* QueryPreparer interface should be implemented by the analyzer to provide prepare query related functionality.
*/
public interface QueryPreparer
{
/**
* This method should do the necessary work required to prepare the query and return the preparedQuery object.
* @param analyzerOptions various analyzer options required to parse and analyze the query
* @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
* @throws ParsingException
* @throws PrestoException
* @throws SemanticException
*/
PreparedQuery prepareQuery(AnalyzerOptions analyzerOptions, String query, Map<String, String> preparedStatements, WarningCollector warningCollector)
throws ParsingException, PrestoException, SemanticException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import com.facebook.presto.spi.PrestoException;
import com.facebook.presto.spi.session.PropertyMetadata;
import com.facebook.presto.spiller.NodeSpillConfig;
import com.facebook.presto.sql.analyzer.AnalyzerType;
import com.facebook.presto.sql.analyzer.FeaturesConfig;
import com.facebook.presto.sql.analyzer.FeaturesConfig.AggregationIfToFilterRewriteStrategy;
import com.facebook.presto.sql.analyzer.FeaturesConfig.AggregationPartitioningMergingStrategy;
import com.facebook.presto.sql.analyzer.FeaturesConfig.AnalyzerType;
import com.facebook.presto.sql.analyzer.FeaturesConfig.JoinDistributionType;
import com.facebook.presto.sql.analyzer.FeaturesConfig.JoinReorderingStrategy;
import com.facebook.presto.sql.analyzer.FeaturesConfig.PartialAggregationStrategy;
Expand Down
Loading

0 comments on commit e97afc8

Please sign in to comment.