From 25b2f255a3c3b80447d3a92c7575514cd9a64fd3 Mon Sep 17 00:00:00 2001 From: v-jizhang Date: Wed, 8 Dec 2021 21:44:36 -0800 Subject: [PATCH] Ensure Parameters are in proper order for queries having WITH clause Cherry-pick of https://github.com/trinodb/trino/pull/1529 Fixes #17012 Co-authored-by: praveenkrishna --- .../presto/druid/TestDruidQueryBase.java | 2 +- .../presto/cost/FilterStatsCalculator.java | 7 +-- .../presto/cost/ScalarStatsCalculator.java | 8 +-- .../facebook/presto/cost/ValuesStatsRule.java | 4 +- .../presto/execution/AddColumnTask.java | 3 +- .../presto/execution/AlterFunctionTask.java | 7 ++- .../facebook/presto/execution/CallTask.java | 8 ++- .../presto/execution/CreateFunctionTask.java | 5 +- .../execution/CreateMaterializedViewTask.java | 8 ++- .../presto/execution/CreateSchemaTask.java | 3 +- .../presto/execution/CreateTableTask.java | 8 ++- .../presto/execution/CreateViewTask.java | 3 +- .../presto/execution/DropFunctionTask.java | 7 ++- .../presto/execution/SetSessionTask.java | 3 +- .../presto/execution/SqlQueryExecution.java | 2 + .../metadata/AbstractPropertyManager.java | 6 ++- .../metadata/SessionPropertyManager.java | 4 +- .../facebook/presto/sql/ParameterUtils.java | 51 +++++++++++++++++++ .../sql/analyzer/AggregationAnalyzer.java | 5 +- .../presto/sql/analyzer/Analysis.java | 11 ++-- .../presto/sql/analyzer/Analyzer.java | 8 ++- .../sql/analyzer/ExpressionAnalyzer.java | 30 +++++------ .../MaterializedViewQueryOptimizer.java | 2 +- .../presto/sql/analyzer/QueryExplainer.java | 3 +- .../planner/AnalyzedExpressionRewriter.java | 4 +- .../planner/ExpressionDomainTranslator.java | 6 +-- .../sql/planner/ExpressionInterpreter.java | 8 +-- .../presto/sql/planner/LogicalPlanner.java | 3 +- .../presto/sql/planner/ParameterRewriter.java | 20 ++++---- .../presto/sql/planner/RelationPlanner.java | 4 +- .../presto/sql/planner/TranslationMap.java | 2 +- .../iterative/rule/InlineSqlFunctions.java | 4 +- .../iterative/rule/SimplifyExpressions.java | 4 +- .../iterative/rule/TranslateExpressions.java | 6 +-- .../optimizations/ExpressionEquivalence.java | 4 +- .../sql/planner/sanity/TypeValidator.java | 4 +- .../sql/rewrite/DescribeInputRewrite.java | 10 +++- .../sql/rewrite/DescribeOutputRewrite.java | 11 +++- .../presto/sql/rewrite/ExplainRewrite.java | 6 ++- .../MaterializedViewOptimizationRewrite.java | 4 ++ .../sql/rewrite/ShowQueriesRewrite.java | 3 ++ .../presto/sql/rewrite/ShowStatsRewrite.java | 12 ++++- .../presto/sql/rewrite/StatementRewrite.java | 7 ++- .../presto/testing/LocalQueryRunner.java | 3 +- .../operator/scalar/FunctionAssertions.java | 8 +-- .../presto/sql/TestExpressionInterpreter.java | 6 +-- .../presto/sql/TestRowExpressionSerde.java | 4 +- .../sql/TestingRowExpressionTranslator.java | 4 +- .../sql/analyzer/AbstractAnalyzerTest.java | 2 + .../sql/gen/CommonSubExpressionBenchmark.java | 4 +- .../sql/gen/PageProcessorBenchmark.java | 4 +- .../gen/TestCommonSubExpressionRewritter.java | 2 +- .../rule/TestInlineSqlFunctions.java | 2 +- .../iterative/rule/test/PlanBuilder.java | 2 +- .../type/BenchmarkDecimalOperators.java | 4 +- .../presto/pinot/TestPinotQueryBase.java | 2 +- .../planner/PrestoSparkQueryPlanner.java | 2 + .../presto/tests/AbstractTestQueries.java | 14 +++++ 58 files changed, 268 insertions(+), 115 deletions(-) create mode 100644 presto-main/src/main/java/com/facebook/presto/sql/ParameterUtils.java diff --git a/presto-druid/src/test/java/com/facebook/presto/druid/TestDruidQueryBase.java b/presto-druid/src/test/java/com/facebook/presto/druid/TestDruidQueryBase.java index 8a40992b510a..8048288b6851 100644 --- a/presto-druid/src/test/java/com/facebook/presto/druid/TestDruidQueryBase.java +++ b/presto-druid/src/test/java/com/facebook/presto/druid/TestDruidQueryBase.java @@ -197,7 +197,7 @@ protected RowExpression toRowExpression(Expression expression, Session session) new SqlParser(), typeProvider, expression, - ImmutableList.of(), + ImmutableMap.of(), WarningCollector.NOOP); return SqlToRowExpressionTranslator.translate(expression, expressionTypes, ImmutableMap.of(), functionAndTypeManager, session); } diff --git a/presto-main/src/main/java/com/facebook/presto/cost/FilterStatsCalculator.java b/presto-main/src/main/java/com/facebook/presto/cost/FilterStatsCalculator.java index 467b528ba0b4..18ec1cec7f3a 100644 --- a/presto-main/src/main/java/com/facebook/presto/cost/FilterStatsCalculator.java +++ b/presto-main/src/main/java/com/facebook/presto/cost/FilterStatsCalculator.java @@ -55,6 +55,7 @@ import com.facebook.presto.sql.tree.SymbolReference; import com.google.common.base.VerifyException; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import javax.annotation.Nullable; import javax.inject.Inject; @@ -96,7 +97,7 @@ import static java.lang.Double.isNaN; import static java.lang.Double.min; import static java.lang.String.format; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Objects.requireNonNull; public class FilterStatsCalculator @@ -181,7 +182,7 @@ private Map, Type> getExpressionTypes(Session session, Expre metadata.getFunctionAndTypeManager(), session, types, - emptyList(), + emptyMap(), node -> new IllegalStateException("Unexpected node: %s" + node), WarningCollector.NOOP, false); @@ -463,7 +464,7 @@ private Type getType(Expression expression) metadata.getFunctionAndTypeManager(), session, types, - ImmutableList.of(), + ImmutableMap.of(), // At this stage, there should be no subqueries in the plan. node -> new VerifyException("Unexpected subquery"), WarningCollector.NOOP, diff --git a/presto-main/src/main/java/com/facebook/presto/cost/ScalarStatsCalculator.java b/presto-main/src/main/java/com/facebook/presto/cost/ScalarStatsCalculator.java index b1df48dc0150..243c24fc7405 100644 --- a/presto-main/src/main/java/com/facebook/presto/cost/ScalarStatsCalculator.java +++ b/presto-main/src/main/java/com/facebook/presto/cost/ScalarStatsCalculator.java @@ -49,7 +49,7 @@ import com.facebook.presto.sql.tree.NullLiteral; import com.facebook.presto.sql.tree.SymbolReference; import com.facebook.presto.type.TypeUtils; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import javax.inject.Inject; @@ -72,7 +72,7 @@ import static java.lang.Double.isNaN; import static java.lang.Math.abs; import static java.lang.String.format; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Objects.requireNonNull; public class ScalarStatsCalculator @@ -356,7 +356,7 @@ protected VariableStatsEstimate visitNullLiteral(NullLiteral node, Void context) protected VariableStatsEstimate visitLiteral(Literal node, Void context) { Object value = evaluate(metadata, session.toConnectorSession(), node); - Type type = ExpressionAnalyzer.createConstantAnalyzer(metadata, session, ImmutableList.of(), WarningCollector.NOOP).analyze(node, Scope.create()); + Type type = ExpressionAnalyzer.createConstantAnalyzer(metadata, session, ImmutableMap.of(), WarningCollector.NOOP).analyze(node, Scope.create()); OptionalDouble doubleValue = toStatsRepresentation(metadata, session, type, value); VariableStatsEstimate.Builder estimate = VariableStatsEstimate.builder() .setNullsFraction(0) @@ -398,7 +398,7 @@ private Map, Type> getExpressionTypes(Session session, Expre metadata.getFunctionAndTypeManager(), session, types, - emptyList(), + emptyMap(), node -> new IllegalStateException("Unexpected node: %s" + node), WarningCollector.NOOP, false); diff --git a/presto-main/src/main/java/com/facebook/presto/cost/ValuesStatsRule.java b/presto-main/src/main/java/com/facebook/presto/cost/ValuesStatsRule.java index a0514949371e..bb392a5793cb 100644 --- a/presto-main/src/main/java/com/facebook/presto/cost/ValuesStatsRule.java +++ b/presto-main/src/main/java/com/facebook/presto/cost/ValuesStatsRule.java @@ -22,7 +22,7 @@ import com.facebook.presto.spi.relation.VariableReferenceExpression; import com.facebook.presto.sql.planner.TypeProvider; import com.facebook.presto.sql.planner.iterative.Lookup; -import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import java.util.List; import java.util.Objects; @@ -87,7 +87,7 @@ private List getVariableValues(ValuesNode valuesNode, int symbolId, Sess .map(row -> row.get(symbolId)) .map(rowExpression -> { if (isExpression(rowExpression)) { - return evaluateConstantExpression(castToExpression(rowExpression), type, metadata, session, ImmutableList.of()); + return evaluateConstantExpression(castToExpression(rowExpression), type, metadata, session, ImmutableMap.of()); } return evaluateConstantRowExpression(rowExpression, metadata, session.toConnectorSession()); }) diff --git a/presto-main/src/main/java/com/facebook/presto/execution/AddColumnTask.java b/presto-main/src/main/java/com/facebook/presto/execution/AddColumnTask.java index a485550f63ed..aa0e9f40e2d9 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/AddColumnTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/AddColumnTask.java @@ -42,6 +42,7 @@ import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND; import static com.facebook.presto.spi.connector.ConnectorCapabilities.NOT_NULL_COLUMN_CONSTRAINT; import static com.facebook.presto.sql.NodeUtils.mapFromProperties; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.COLUMN_ALREADY_EXISTS; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.MISSING_TABLE; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.NOT_SUPPORTED; @@ -113,7 +114,7 @@ public ListenableFuture execute(AddColumn statement, TransactionManager trans sqlProperties, session, metadata, - parameters); + parameterExtractor(statement, parameters)); ColumnMetadata column = new ColumnMetadata( element.getName().getValue(), diff --git a/presto-main/src/main/java/com/facebook/presto/execution/AlterFunctionTask.java b/presto-main/src/main/java/com/facebook/presto/execution/AlterFunctionTask.java index 605b584daac9..d2062c6c2bd2 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/AlterFunctionTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/AlterFunctionTask.java @@ -25,15 +25,19 @@ import com.facebook.presto.sql.parser.SqlParser; import com.facebook.presto.sql.tree.AlterFunction; import com.facebook.presto.sql.tree.Expression; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.transaction.TransactionManager; import com.google.common.util.concurrent.ListenableFuture; import javax.inject.Inject; import java.util.List; +import java.util.Map; import java.util.Optional; import static com.facebook.presto.metadata.FunctionAndTypeManager.qualifyObjectName; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.util.concurrent.Futures.immediateFuture; import static java.util.Objects.requireNonNull; @@ -64,7 +68,8 @@ public String explain(AlterFunction statement, List parameters) @Override public ListenableFuture execute(AlterFunction statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List parameters, WarningCollector warningCollector) { - Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, warningCollector); + Map, Expression> parameterLookup = parameterExtractor(statement, parameters); + Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, parameterLookup, warningCollector); analyzer.analyze(statement); QualifiedObjectName functionName = qualifyObjectName(statement.getFunctionName()); diff --git a/presto-main/src/main/java/com/facebook/presto/execution/CallTask.java b/presto-main/src/main/java/com/facebook/presto/execution/CallTask.java index f02bfb4bc1dc..6371e6a45b39 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/CallTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/CallTask.java @@ -31,6 +31,8 @@ import com.facebook.presto.sql.tree.CallArgument; import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.ExpressionTreeRewriter; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.transaction.TransactionManager; import com.google.common.util.concurrent.ListenableFuture; @@ -51,6 +53,7 @@ import static com.facebook.presto.spi.StandardErrorCode.INVALID_PROCEDURE_DEFINITION; import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED; import static com.facebook.presto.spi.StandardErrorCode.PROCEDURE_CALL_FAILED; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.INVALID_PROCEDURE_ARGUMENTS; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.MISSING_CATALOG; import static com.facebook.presto.sql.planner.ExpressionInterpreter.evaluateConstantExpression; @@ -128,16 +131,17 @@ else if (i < procedure.getArguments().size()) { // get argument values Object[] values = new Object[procedure.getArguments().size()]; + Map, Expression> parameterLookup = parameterExtractor(call, parameters); for (Entry entry : names.entrySet()) { CallArgument callArgument = entry.getValue(); int index = positions.get(entry.getKey()); Argument argument = procedure.getArguments().get(index); - Expression expression = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(parameters), callArgument.getValue()); + Expression expression = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(parameterLookup), callArgument.getValue()); Type type = metadata.getType(argument.getType()); checkCondition(type != null, INVALID_PROCEDURE_DEFINITION, "Unknown procedure argument type: %s", argument.getType()); - Object value = evaluateConstantExpression(expression, type, metadata, session, parameters); + Object value = evaluateConstantExpression(expression, type, metadata, session, parameterLookup); values[index] = toTypeObjectValue(session, type, value); } diff --git a/presto-main/src/main/java/com/facebook/presto/execution/CreateFunctionTask.java b/presto-main/src/main/java/com/facebook/presto/execution/CreateFunctionTask.java index 55d4f8ba10ad..af5dc1301f65 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/CreateFunctionTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/CreateFunctionTask.java @@ -34,6 +34,7 @@ import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.ExpressionRewriter; import com.facebook.presto.sql.tree.ExpressionTreeRewriter; +import com.facebook.presto.sql.tree.NodeRef; import com.facebook.presto.sql.tree.Return; import com.facebook.presto.sql.tree.RoutineBody; import com.facebook.presto.transaction.TransactionManager; @@ -53,6 +54,7 @@ import static com.facebook.presto.spi.StandardErrorCode.ALREADY_EXISTS; import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED; import static com.facebook.presto.spi.function.FunctionVersion.notVersioned; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.SqlFormatter.formatSql; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.util.concurrent.Futures.immediateFuture; @@ -86,7 +88,8 @@ public String explain(CreateFunction statement, List parameters) @Override public ListenableFuture execute(CreateFunction statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List parameters, WarningCollector warningCollector) { - Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, warningCollector); + Map, Expression> parameterLookup = parameterExtractor(statement, parameters); + Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, parameterLookup, warningCollector); Analysis analysis = analyzer.analyze(statement); if (analysis.getFunctionHandles().values().stream() .anyMatch(SqlFunctionHandle.class::isInstance)) { diff --git a/presto-main/src/main/java/com/facebook/presto/execution/CreateMaterializedViewTask.java b/presto-main/src/main/java/com/facebook/presto/execution/CreateMaterializedViewTask.java index e563f7667e02..8900b3f21f12 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/CreateMaterializedViewTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/CreateMaterializedViewTask.java @@ -32,6 +32,8 @@ import com.facebook.presto.sql.parser.SqlParser; import com.facebook.presto.sql.tree.CreateMaterializedView; import com.facebook.presto.sql.tree.Expression; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.transaction.TransactionManager; import com.google.common.util.concurrent.ListenableFuture; @@ -46,6 +48,7 @@ import static com.facebook.presto.spi.StandardErrorCode.ALREADY_EXISTS; import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND; import static com.facebook.presto.sql.NodeUtils.mapFromProperties; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.SqlFormatterUtil.getFormattedSql; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.MATERIALIZED_VIEW_ALREADY_EXISTS; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.NOT_SUPPORTED; @@ -86,7 +89,8 @@ public ListenableFuture execute(CreateMaterializedView statement, Transaction accessControl.checkCanCreateTable(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), viewName); accessControl.checkCanCreateView(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), viewName); - Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, warningCollector); + Map, Expression> parameterLookup = parameterExtractor(statement, parameters); + Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, parameterLookup, warningCollector); Analysis analysis = analyzer.analyze(statement); ConnectorId connectorId = metadata.getCatalogHandle(session, viewName.getCatalogName()) @@ -103,7 +107,7 @@ public ListenableFuture execute(CreateMaterializedView statement, Transaction sqlProperties, session, metadata, - parameters); + parameterLookup); ConnectorTableMetadata viewMetadata = new ConnectorTableMetadata( toSchemaTableName(viewName), diff --git a/presto-main/src/main/java/com/facebook/presto/execution/CreateSchemaTask.java b/presto-main/src/main/java/com/facebook/presto/execution/CreateSchemaTask.java index 09242a4a80e7..67ff7d0ffca2 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/CreateSchemaTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/CreateSchemaTask.java @@ -33,6 +33,7 @@ import static com.facebook.presto.metadata.MetadataUtil.createCatalogSchemaName; import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND; import static com.facebook.presto.sql.NodeUtils.mapFromProperties; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.SCHEMA_ALREADY_EXISTS; import static com.google.common.util.concurrent.Futures.immediateFuture; @@ -76,7 +77,7 @@ public ListenableFuture execute(CreateSchema statement, TransactionManager tr mapFromProperties(statement.getProperties()), session, metadata, - parameters); + parameterExtractor(statement, parameters)); metadata.createSchema(session, schema, properties); diff --git a/presto-main/src/main/java/com/facebook/presto/execution/CreateTableTask.java b/presto-main/src/main/java/com/facebook/presto/execution/CreateTableTask.java index 2e2aa50386a4..7a300c6e90d7 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/CreateTableTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/CreateTableTask.java @@ -30,6 +30,8 @@ import com.facebook.presto.sql.tree.CreateTable; import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.LikeClause; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.TableElement; import com.facebook.presto.transaction.TransactionManager; import com.google.common.annotations.VisibleForTesting; @@ -54,6 +56,7 @@ import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND; import static com.facebook.presto.spi.connector.ConnectorCapabilities.NOT_NULL_COLUMN_CONSTRAINT; import static com.facebook.presto.sql.NodeUtils.mapFromProperties; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.DUPLICATE_COLUMN_NAME; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.MISSING_CATALOG; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.MISSING_TABLE; @@ -89,6 +92,7 @@ public ListenableFuture internalExecute(CreateTable statement, Metadata metad { checkArgument(!statement.getElements().isEmpty(), "no columns for table"); + Map, Expression> parameterLookup = parameterExtractor(statement, parameters); QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getName()); Optional tableHandle = metadata.getTableHandle(session, tableName); if (tableHandle.isPresent()) { @@ -132,7 +136,7 @@ public ListenableFuture internalExecute(CreateTable statement, Metadata metad sqlProperties, session, metadata, - parameters); + parameterLookup); columns.put(name, new ColumnMetadata( name, @@ -188,7 +192,7 @@ else if (element instanceof LikeClause) { sqlProperties, session, metadata, - parameters); + parameterLookup); Map finalProperties = combineProperties(sqlProperties.keySet(), properties, inheritedProperties); diff --git a/presto-main/src/main/java/com/facebook/presto/execution/CreateViewTask.java b/presto-main/src/main/java/com/facebook/presto/execution/CreateViewTask.java index 6719930f05b5..e9cd785b8f80 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/CreateViewTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/CreateViewTask.java @@ -40,6 +40,7 @@ import static com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName; import static com.facebook.presto.metadata.MetadataUtil.toSchemaTableName; import static com.facebook.presto.metadata.ViewDefinition.ViewColumn; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.SqlFormatterUtil.getFormattedSql; import static com.facebook.presto.sql.tree.CreateView.Security.INVOKER; import static com.google.common.collect.ImmutableList.toImmutableList; @@ -111,7 +112,7 @@ public ListenableFuture execute(CreateView statement, TransactionManager tran private Analysis analyzeStatement(Statement statement, Session session, Metadata metadata, AccessControl accessControl, List parameters, WarningCollector warningCollector) { - Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, warningCollector); + Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, parameterExtractor(statement, parameters), warningCollector); return analyzer.analyze(statement); } } diff --git a/presto-main/src/main/java/com/facebook/presto/execution/DropFunctionTask.java b/presto-main/src/main/java/com/facebook/presto/execution/DropFunctionTask.java index 4f6cb1515ee5..2938ba5e25a6 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/DropFunctionTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/DropFunctionTask.java @@ -25,6 +25,8 @@ import com.facebook.presto.sql.parser.SqlParser; import com.facebook.presto.sql.tree.DropFunction; import com.facebook.presto.sql.tree.Expression; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.transaction.TransactionManager; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Sets; @@ -33,12 +35,14 @@ import javax.inject.Inject; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import static com.facebook.presto.metadata.FunctionAndTypeManager.qualifyObjectName; import static com.facebook.presto.metadata.SessionFunctionHandle.SESSION_NAMESPACE; import static com.facebook.presto.spi.StandardErrorCode.NOT_FOUND; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.util.concurrent.Futures.immediateFuture; import static java.lang.String.format; @@ -72,7 +76,8 @@ public String explain(DropFunction statement, List parameters) @Override public ListenableFuture execute(DropFunction statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, Session session, List parameters, WarningCollector warningCollector) { - Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, warningCollector); + Map, Expression> parameterLookup = parameterExtractor(statement, parameters); + Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.empty(), parameters, parameterLookup, warningCollector); analyzer.analyze(statement); Optional> parameterTypes = statement.getParameterTypes().map(types -> types.stream().map(TypeSignature::parseTypeSignature).collect(toImmutableList())); diff --git a/presto-main/src/main/java/com/facebook/presto/execution/SetSessionTask.java b/presto-main/src/main/java/com/facebook/presto/execution/SetSessionTask.java index 2dc52bae8686..baf6c68607b3 100644 --- a/presto-main/src/main/java/com/facebook/presto/execution/SetSessionTask.java +++ b/presto-main/src/main/java/com/facebook/presto/execution/SetSessionTask.java @@ -32,6 +32,7 @@ import static com.facebook.presto.metadata.SessionPropertyManager.evaluatePropertyValue; import static com.facebook.presto.metadata.SessionPropertyManager.serializeSessionProperty; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.INVALID_SESSION_PROPERTY; import static com.facebook.presto.sql.analyzer.SemanticErrorCode.MISSING_CATALOG; import static com.google.common.util.concurrent.Futures.immediateFuture; @@ -75,7 +76,7 @@ public ListenableFuture execute(SetSession statement, TransactionManager tran Object objectValue; try { - objectValue = evaluatePropertyValue(statement.getValue(), type, session, metadata, parameters); + objectValue = evaluatePropertyValue(statement.getValue(), type, session, metadata, parameterExtractor(statement, parameters)); } catch (SemanticException e) { throw new PrestoException(StandardErrorCode.INVALID_SESSION_PROPERTY, 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 e3cbd5d06940..6ade37123f2d 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 @@ -86,6 +86,7 @@ import static com.facebook.presto.execution.buffer.OutputBuffers.createInitialEmptyOutputBuffers; import static com.facebook.presto.execution.buffer.OutputBuffers.createSpoolingOutputBuffers; import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Throwables.throwIfInstanceOf; import static io.airlift.units.DataSize.Unit.BYTE; @@ -184,6 +185,7 @@ private SqlQueryExecution( accessControl, Optional.of(queryExplainer), preparedQuery.getParameters(), + parameterExtractor(preparedQuery.getStatement(), preparedQuery.getParameters()), warningCollector); this.analysis = analyzer.analyzeSemantic(preparedQuery.getStatement(), false); diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/AbstractPropertyManager.java b/presto-main/src/main/java/com/facebook/presto/metadata/AbstractPropertyManager.java index a369d953f739..630713273423 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/AbstractPropertyManager.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/AbstractPropertyManager.java @@ -24,6 +24,8 @@ import com.facebook.presto.sql.planner.ParameterRewriter; import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.ExpressionTreeRewriter; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; @@ -74,7 +76,7 @@ public final Map getProperties( Map sqlPropertyValues, Session session, Metadata metadata, - List parameters) + Map, Expression> parameters) { Map> supportedProperties = connectorProperties.get(connectorId); if (supportedProperties == null) { @@ -142,7 +144,7 @@ public Map>> getAllProperties() return ImmutableMap.copyOf(connectorProperties); } - private Object evaluatePropertyValue(Expression expression, Type expectedType, Session session, Metadata metadata, List parameters) + private Object evaluatePropertyValue(Expression expression, Type expectedType, Session session, Metadata metadata, Map, Expression> parameters) { Expression rewritten = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(parameters), expression); Object value = evaluateConstantExpression(rewritten, expectedType, metadata, session, parameters); diff --git a/presto-main/src/main/java/com/facebook/presto/metadata/SessionPropertyManager.java b/presto-main/src/main/java/com/facebook/presto/metadata/SessionPropertyManager.java index b24b2163a416..6b7d77ed7936 100644 --- a/presto-main/src/main/java/com/facebook/presto/metadata/SessionPropertyManager.java +++ b/presto-main/src/main/java/com/facebook/presto/metadata/SessionPropertyManager.java @@ -32,6 +32,8 @@ import com.facebook.presto.sql.planner.ParameterRewriter; import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.ExpressionTreeRewriter; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; @@ -223,7 +225,7 @@ private static T decodePropertyValue(String fullPropertyName, @Nullable Stri } } - public static Object evaluatePropertyValue(Expression expression, Type expectedType, Session session, Metadata metadata, List parameters) + public static Object evaluatePropertyValue(Expression expression, Type expectedType, Session session, Metadata metadata, Map, Expression> parameters) { Expression rewritten = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(parameters), expression); Object value = evaluateConstantExpression(rewritten, expectedType, metadata, session, parameters); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/ParameterUtils.java b/presto-main/src/main/java/com/facebook/presto/sql/ParameterUtils.java new file mode 100644 index 000000000000..a7d010ecfb2c --- /dev/null +++ b/presto-main/src/main/java/com/facebook/presto/sql/ParameterUtils.java @@ -0,0 +1,51 @@ +/* + * 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; + +import com.facebook.presto.sql.tree.Expression; +import com.facebook.presto.sql.tree.NodeLocation; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; +import com.facebook.presto.sql.tree.Statement; +import com.google.common.collect.ImmutableMap; + +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import static com.facebook.presto.execution.ParameterExtractor.getParameters; +import static com.google.common.collect.ImmutableList.toImmutableList; + +public class ParameterUtils +{ + private ParameterUtils() {} + + public static Map, Expression> parameterExtractor(Statement statement, List parameters) + { + List parametersList = getParameters(statement).stream() + .sorted(Comparator.comparing( + parameter -> parameter.getLocation().get(), + Comparator.comparing(NodeLocation::getLineNumber) + .thenComparing(NodeLocation::getColumnNumber))) + .collect(toImmutableList()); + + ImmutableMap.Builder, Expression> builder = ImmutableMap.builder(); + Iterator iterator = parameters.iterator(); + for (Parameter parameter : parametersList) { + builder.put(NodeRef.of(parameter), iterator.next()); + } + return builder.build(); + } +} diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/AggregationAnalyzer.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/AggregationAnalyzer.java index 9fd0c98cfc61..80141c3f11ef 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/AggregationAnalyzer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/AggregationAnalyzer.java @@ -69,6 +69,7 @@ import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -624,9 +625,9 @@ public Boolean visitParameter(Parameter node, Void context) if (analysis.isDescribe()) { return true; } - List parameters = analysis.getParameters(); + Map, Expression> parameters = analysis.getParameters(); checkArgument(node.getPosition() < parameters.size(), "Invalid parameter number %s, max values is %s", node.getPosition(), parameters.size() - 1); - return process(parameters.get(node.getPosition()), context); + return process(parameters.get(NodeRef.of(node)), context); } public Boolean visitGroupingOperation(GroupingOperation node, Void context) diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/Analysis.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/Analysis.java index 4da8b7dbf2cd..db19dcefbbd2 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/Analysis.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/Analysis.java @@ -34,6 +34,7 @@ import com.facebook.presto.sql.tree.NodeRef; import com.facebook.presto.sql.tree.Offset; import com.facebook.presto.sql.tree.OrderBy; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.QuantifiedComparisonExpression; import com.facebook.presto.sql.tree.Query; import com.facebook.presto.sql.tree.QuerySpecification; @@ -85,7 +86,7 @@ public class Analysis { @Nullable private final Statement root; - private final List parameters; + private final Map, Expression> parameters; private String updateType; private final Map, Query> namedQueries = new LinkedHashMap<>(); @@ -162,12 +163,10 @@ public class Analysis private Optional expandedQuery = Optional.empty(); - public Analysis(@Nullable Statement root, List parameters, boolean isDescribe) + public Analysis(@Nullable Statement root, Map, Expression> parameters, boolean isDescribe) { - requireNonNull(parameters); - this.root = root; - this.parameters = ImmutableList.copyOf(requireNonNull(parameters, "parameters is null")); + this.parameters = ImmutableMap.copyOf(requireNonNull(parameters, "parameterMap is null")); this.isDescribe = isDescribe; } @@ -741,7 +740,7 @@ public List getGroupingOperations(QuerySpecification querySpe .orElse(emptyList()); } - public List getParameters() + public Map, Expression> getParameters() { return parameters; } 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 3df3da90bf1d..09281a123f97 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 @@ -25,6 +25,7 @@ import com.facebook.presto.sql.tree.FunctionCall; import com.facebook.presto.sql.tree.GroupingOperation; import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.Statement; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -50,6 +51,7 @@ public class Analyzer private final Session session; private final Optional queryExplainer; private final List parameters; + private final Map, Expression> parameterLookup; private final WarningCollector warningCollector; public Analyzer(Session session, @@ -58,6 +60,7 @@ public Analyzer(Session session, AccessControl accessControl, Optional queryExplainer, List parameters, + Map, Expression> parameterLookup, WarningCollector warningCollector) { this.session = requireNonNull(session, "session is null"); @@ -66,6 +69,7 @@ public Analyzer(Session session, this.accessControl = requireNonNull(accessControl, "accessControl is null"); this.queryExplainer = requireNonNull(queryExplainer, "query explainer is null"); this.parameters = parameters; + this.parameterLookup = parameterLookup; this.warningCollector = requireNonNull(warningCollector, "warningCollector is null"); } @@ -83,8 +87,8 @@ public Analysis analyze(Statement statement, boolean isDescribe) public Analysis analyzeSemantic(Statement statement, boolean isDescribe) { - Statement rewrittenStatement = StatementRewrite.rewrite(session, metadata, sqlParser, queryExplainer, statement, parameters, accessControl, warningCollector); - Analysis analysis = new Analysis(rewrittenStatement, parameters, isDescribe); + Statement rewrittenStatement = StatementRewrite.rewrite(session, metadata, sqlParser, queryExplainer, statement, parameters, parameterLookup, accessControl, warningCollector); + Analysis analysis = new Analysis(rewrittenStatement, parameterLookup, isDescribe); StatementAnalyzer analyzer = new StatementAnalyzer(analysis, metadata, sqlParser, accessControl, session, warningCollector); analyzer.analyze(rewrittenStatement, Optional.empty()); analyzeForUtilizedColumns(analysis, analysis.getStatement()); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/ExpressionAnalyzer.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/ExpressionAnalyzer.java index ebd9aedbe7d1..790814020c81 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/ExpressionAnalyzer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/ExpressionAnalyzer.java @@ -174,7 +174,7 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static java.lang.Math.toIntExact; import static java.lang.String.format; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Collections.unmodifiableMap; import static java.util.Collections.unmodifiableSet; import static java.util.Objects.requireNonNull; @@ -206,7 +206,7 @@ public class ExpressionAnalyzer private final Optional transactionId; private final Optional> sessionFunctions; private final SqlFunctionProperties sqlFunctionProperties; - private final List parameters; + private final Map, Expression> parameters; private final WarningCollector warningCollector; private ExpressionAnalyzer( @@ -216,7 +216,7 @@ private ExpressionAnalyzer( Optional transactionId, SqlFunctionProperties sqlFunctionProperties, TypeProvider symbolTypes, - List parameters, + Map, Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { @@ -226,7 +226,7 @@ private ExpressionAnalyzer( this.sessionFunctions = requireNonNull(sessionFunctions, "sessionFunctions is null"); this.sqlFunctionProperties = requireNonNull(sqlFunctionProperties, "sqlFunctionProperties is null"); this.symbolTypes = requireNonNull(symbolTypes, "symbolTypes is null"); - this.parameters = requireNonNull(parameters, "parameters is null"); + this.parameters = requireNonNull(parameters, "parameterMap is null"); this.isDescribe = isDescribe; this.warningCollector = requireNonNull(warningCollector, "warningCollector is null"); } @@ -1043,7 +1043,7 @@ protected Type visitParameter(Parameter node, StackableAstVisitorContext, Type> getExpressionTypes( SqlParser sqlParser, TypeProvider types, Expression expression, - List parameters, + Map, Expression> parameters, WarningCollector warningCollector) { return getExpressionTypes(session, metadata, sqlParser, types, expression, parameters, warningCollector, false); @@ -1562,7 +1562,7 @@ public static Map, Type> getExpressionTypes( SqlParser sqlParser, TypeProvider types, Expression expression, - List parameters, + Map, Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { @@ -1575,7 +1575,7 @@ public static Map, Type> getExpressionTypes( SqlParser sqlParser, TypeProvider types, Iterable expressions, - List parameters, + Map, Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { @@ -1588,7 +1588,7 @@ public static ExpressionAnalysis analyzeExpressions( SqlParser sqlParser, TypeProvider types, Iterable expressions, - List parameters, + Map, Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { @@ -1663,7 +1663,7 @@ public static ExpressionAnalysis analyzeSqlFunctionExpression( Optional.empty(), sqlFunctionProperties, TypeProvider.copyOf(argumentTypes), - emptyList(), + emptyMap(), node -> new SemanticException(NOT_SUPPORTED, node, "SQL function does not support subquery"), WarningCollector.NOOP, false); @@ -1710,7 +1710,7 @@ private static ExpressionAnalyzer create( analysis.isDescribe()); } - public static ExpressionAnalyzer createConstantAnalyzer(Metadata metadata, Session session, List parameters, WarningCollector warningCollector) + public static ExpressionAnalyzer createConstantAnalyzer(Metadata metadata, Session session, Map, Expression> parameters, WarningCollector warningCollector) { return createWithoutSubqueries( metadata.getFunctionAndTypeManager(), @@ -1722,7 +1722,7 @@ public static ExpressionAnalyzer createConstantAnalyzer(Metadata metadata, Sessi false); } - public static ExpressionAnalyzer createConstantAnalyzer(Metadata metadata, Session session, List parameters, WarningCollector warningCollector, boolean isDescribe) + public static ExpressionAnalyzer createConstantAnalyzer(Metadata metadata, Session session, Map, Expression> parameters, WarningCollector warningCollector, boolean isDescribe) { return createWithoutSubqueries( metadata.getFunctionAndTypeManager(), @@ -1737,7 +1737,7 @@ public static ExpressionAnalyzer createConstantAnalyzer(Metadata metadata, Sessi public static ExpressionAnalyzer createWithoutSubqueries( FunctionAndTypeManager functionAndTypeManager, Session session, - List parameters, + Map, Expression> parameters, SemanticErrorCode errorCode, String message, WarningCollector warningCollector, @@ -1757,7 +1757,7 @@ public static ExpressionAnalyzer createWithoutSubqueries( FunctionAndTypeManager functionAndTypeManager, Session session, TypeProvider symbolTypes, - List parameters, + Map, Expression> parameters, Function statementAnalyzerRejection, WarningCollector warningCollector, boolean isDescribe) @@ -1780,7 +1780,7 @@ public static ExpressionAnalyzer createWithoutSubqueries( Optional transactionId, SqlFunctionProperties sqlFunctionProperties, TypeProvider symbolTypes, - List parameters, + Map, Expression> parameters, Function statementAnalyzerRejection, WarningCollector warningCollector, boolean isDescribe) diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/MaterializedViewQueryOptimizer.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/MaterializedViewQueryOptimizer.java index 56975ae8f79d..3e4b4e54150c 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/MaterializedViewQueryOptimizer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/MaterializedViewQueryOptimizer.java @@ -437,7 +437,7 @@ private RowExpression convertToRowExpression(Expression expression, Scope scope) accessControl, sqlParser, scope, - new Analysis(null, ImmutableList.of(), false), + new Analysis(null, ImmutableMap.of(), false), expression, WarningCollector.NOOP); return SqlToRowExpressionTranslator.translate( diff --git a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/QueryExplainer.java b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/QueryExplainer.java index 57e1fa4edd61..e49014b3ca46 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/analyzer/QueryExplainer.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/analyzer/QueryExplainer.java @@ -44,6 +44,7 @@ import java.util.Optional; import static com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.planner.planPrinter.IOPlanPrinter.textIOPlan; import static com.facebook.presto.sql.planner.planPrinter.PlanPrinter.graphvizDistributedPlan; import static com.facebook.presto.sql.planner.planPrinter.PlanPrinter.graphvizLogicalPlan; @@ -112,7 +113,7 @@ public QueryExplainer( public Analysis analyze(Session session, Statement statement, List parameters, WarningCollector warningCollector) { - Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.of(this), parameters, warningCollector); + Analyzer analyzer = new Analyzer(session, metadata, sqlParser, accessControl, Optional.of(this), parameters, parameterExtractor(statement, parameters), warningCollector); return analyzer.analyze(statement); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/AnalyzedExpressionRewriter.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/AnalyzedExpressionRewriter.java index cf4324d4e432..a0cfdfdba653 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/AnalyzedExpressionRewriter.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/AnalyzedExpressionRewriter.java @@ -27,7 +27,7 @@ import java.util.Map; import static com.facebook.presto.sql.analyzer.ExpressionAnalyzer.getExpressionTypes; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; @Deprecated public class AnalyzedExpressionRewriter @@ -63,7 +63,7 @@ public Expression rewriteWith(RewriterProvider rewriterProvider, Expressi sqlParser, typeProvider, expression, - emptyList(), + emptyMap(), WarningCollector.NOOP); return ExpressionTreeRewriter.rewriteWith(rewriterProvider.get(expressionTypes), expression, context); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/ExpressionDomainTranslator.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/ExpressionDomainTranslator.java index 6756a1c13820..74b479987771 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/ExpressionDomainTranslator.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/ExpressionDomainTranslator.java @@ -79,7 +79,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.collect.Iterators.peekingIterator; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Comparator.comparing; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.collectingAndThen; @@ -469,7 +469,7 @@ private boolean isImplicitCoercion(Cast cast) private Map, Type> analyzeExpression(Expression expression) { - return ExpressionAnalyzer.getExpressionTypes(session, metadata, new SqlParser(), types, expression, emptyList(), WarningCollector.NOOP); + return ExpressionAnalyzer.getExpressionTypes(session, metadata, new SqlParser(), types, expression, emptyMap(), WarningCollector.NOOP); } private static ExtractionResult createComparisonExtractionResult(ComparisonExpression.Operator comparisonOperator, String column, Type type, @Nullable Object value, boolean complement) @@ -735,7 +735,7 @@ protected ExtractionResult visitNullLiteral(NullLiteral node, Boolean complement private static Type typeOf(Expression expression, Session session, Metadata metadata, TypeProvider types) { - Map, Type> expressionTypes = ExpressionAnalyzer.getExpressionTypes(session, metadata, new SqlParser(), types, expression, emptyList(), WarningCollector.NOOP); + Map, Type> expressionTypes = ExpressionAnalyzer.getExpressionTypes(session, metadata, new SqlParser(), types, expression, emptyMap(), WarningCollector.NOOP); return expressionTypes.get(NodeRef.of(expression)); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/ExpressionInterpreter.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/ExpressionInterpreter.java index 2957f34ecc30..60ad2b189e82 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/ExpressionInterpreter.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/ExpressionInterpreter.java @@ -154,7 +154,7 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static java.lang.Math.toIntExact; import static java.lang.String.format; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; @@ -193,7 +193,7 @@ public static ExpressionInterpreter expressionOptimizer(Expression expression, M return new ExpressionInterpreter(expression, metadata, session, expressionTypes, true); } - public static Object evaluateConstantExpression(Expression expression, Type expectedType, Metadata metadata, Session session, List parameters) + public static Object evaluateConstantExpression(Expression expression, Type expectedType, Metadata metadata, Session session, Map, Expression> parameters) { ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters, WarningCollector.NOOP); analyzer.analyze(expression, Scope.create()); @@ -219,7 +219,7 @@ private static Object evaluateConstantExpression( Metadata metadata, Session session, Set> columnReferences, - List parameters) + Map, Expression> parameters) { requireNonNull(columnReferences, "columnReferences is null"); @@ -957,7 +957,7 @@ else if (implementationType.equals(JAVA)) { function, metadata, session, - getExpressionTypes(session, metadata, new SqlParser(), TypeProvider.empty(), function, emptyList(), WarningCollector.NOOP), + getExpressionTypes(session, metadata, new SqlParser(), TypeProvider.empty(), function, emptyMap(), WarningCollector.NOOP), optimize); result = functionInterpreter.visitor.process(function, context); if (result instanceof FunctionCall) { 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 f5127f2c4b17..fb6e987a814c 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 @@ -76,6 +76,7 @@ import com.facebook.presto.sql.tree.LambdaArgumentDeclaration; import com.facebook.presto.sql.tree.NodeRef; import com.facebook.presto.sql.tree.NullLiteral; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.Query; import com.facebook.presto.sql.tree.RefreshMaterializedView; import com.facebook.presto.sql.tree.Statement; @@ -586,7 +587,7 @@ private RelationPlan createRelationPlan(Analysis analysis, Query query) .process(query, null); } - private ConnectorTableMetadata createTableMetadata(QualifiedObjectName table, List columns, Map propertyExpressions, List parameters, Optional comment) + private ConnectorTableMetadata createTableMetadata(QualifiedObjectName table, List columns, Map propertyExpressions, Map, Expression> parameters, Optional comment) { ConnectorId connectorId = metadata.getCatalogHandle(session, table.getCatalogName()) .orElseThrow(() -> new PrestoException(NOT_FOUND, "Catalog does not exist: " + table.getCatalogName())); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/ParameterRewriter.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/ParameterRewriter.java index 01aff60e5f31..b9ca7696f086 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/ParameterRewriter.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/ParameterRewriter.java @@ -19,9 +19,10 @@ import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.ExpressionRewriter; import com.facebook.presto.sql.tree.ExpressionTreeRewriter; +import com.facebook.presto.sql.tree.NodeRef; import com.facebook.presto.sql.tree.Parameter; -import java.util.List; +import java.util.Map; import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; @@ -29,19 +30,20 @@ public class ParameterRewriter extends ExpressionRewriter { - private final List parameterValues; + private final Map, Expression> parameters; private final Analysis analysis; - public ParameterRewriter(List parameterValues) + public ParameterRewriter(Map, Expression> parameters) { - this(parameterValues, null); + requireNonNull(parameters, "parameterMap is null"); + this.parameters = parameters; + this.analysis = null; } - public ParameterRewriter(List parameterValues, Analysis analysis) + public ParameterRewriter(Analysis analysis) { - requireNonNull(parameterValues, "parameterValues is null"); - this.parameterValues = parameterValues; this.analysis = analysis; + this.parameters = analysis.getParameters(); } @Override @@ -53,8 +55,8 @@ public Expression rewriteExpression(Expression node, Void context, ExpressionTre @Override public Expression rewriteParameter(Parameter node, Void context, ExpressionTreeRewriter treeRewriter) { - checkState(parameterValues.size() > node.getPosition(), "Too few parameter values"); - return coerceIfNecessary(node, parameterValues.get(node.getPosition())); + checkState(parameters.size() > node.getPosition(), "Too few parameter values"); + return coerceIfNecessary(node, parameters.get(NodeRef.of(node))); } private Expression coerceIfNecessary(Expression original, Expression rewritten) diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/RelationPlanner.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/RelationPlanner.java index d0726bb10650..2a391d62c055 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/RelationPlanner.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/RelationPlanner.java @@ -717,7 +717,7 @@ public Expression rewriteDereferenceExpression(DereferenceExpression node, Void } }, row); expression = Coercer.addCoercions(expression, analysis); - expression = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(analysis.getParameters(), analysis), expression); + expression = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(analysis), expression); return castToRowExpression(expression); } @@ -740,7 +740,7 @@ protected RelationPlan visitUnnest(Unnest node, Void context) for (Expression expression : node.getExpressions()) { Type type = analysis.getType(expression); Expression rewritten = Coercer.addCoercions(expression, analysis); - rewritten = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(analysis.getParameters(), analysis), rewritten); + rewritten = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(analysis), rewritten); values.add(castToRowExpression(rewritten)); VariableReferenceExpression input = variableAllocator.newVariable(rewritten, type); argumentVariables.add(new VariableReferenceExpression(getSourceLocation(rewritten), input.getName(), type)); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/TranslationMap.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/TranslationMap.java index 44e241d3c0b9..0c9bb875f66a 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/TranslationMap.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/TranslationMap.java @@ -266,7 +266,7 @@ public Expression rewriteLambdaExpression(LambdaExpression node, Void context, E public Expression rewriteParameter(Parameter node, Void context, ExpressionTreeRewriter treeRewriter) { checkState(analysis.getParameters().size() > node.getPosition(), "Too few parameter values"); - return coerceIfNecessary(node, analysis.getParameters().get(node.getPosition())); + return coerceIfNecessary(node, analysis.getParameters().get(NodeRef.of(node))); } private Expression coerceIfNecessary(Expression original, Expression rewritten) diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/InlineSqlFunctions.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/InlineSqlFunctions.java index f971e62643fc..8296ad02ccde 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/InlineSqlFunctions.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/InlineSqlFunctions.java @@ -40,7 +40,7 @@ import static com.facebook.presto.sql.analyzer.ExpressionAnalyzer.getExpressionTypes; import static com.facebook.presto.sql.analyzer.TypeSignatureProvider.fromTypes; import static com.facebook.presto.sql.relational.SqlFunctionUtils.getSqlFunctionExpression; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Objects.requireNonNull; public class InlineSqlFunctions @@ -67,7 +67,7 @@ private static ExpressionRewriter createRewrite(Metadata metadata, SqlParser sql sqlParser, context.getVariableAllocator().getTypes(), expression, - emptyList(), + emptyMap(), context.getWarningCollector())); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/SimplifyExpressions.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/SimplifyExpressions.java index 1906c59adfdd..75edd927378f 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/SimplifyExpressions.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/SimplifyExpressions.java @@ -35,7 +35,7 @@ import static com.facebook.presto.sql.analyzer.ExpressionAnalyzer.getExpressionTypes; import static com.facebook.presto.sql.planner.iterative.rule.ExtractCommonPredicatesExpressionRewriter.extractCommonPredicates; import static com.facebook.presto.sql.planner.iterative.rule.PushDownNegationsExpressionRewriter.pushDownNegations; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Objects.requireNonNull; public class SimplifyExpressions @@ -51,7 +51,7 @@ static Expression rewrite(Expression expression, Session session, PlanVariableAl } expression = pushDownNegations(expression); expression = extractCommonPredicates(expression); - Map, Type> expressionTypes = getExpressionTypes(session, metadata, sqlParser, variableAllocator.getTypes(), expression, emptyList(), WarningCollector.NOOP); + Map, Type> expressionTypes = getExpressionTypes(session, metadata, sqlParser, variableAllocator.getTypes(), expression, emptyMap(), WarningCollector.NOOP); ExpressionInterpreter interpreter = ExpressionInterpreter.expressionOptimizer(expression, metadata, session, expressionTypes); return literalEncoder.toExpression(interpreter.optimize(NoOpVariableResolver.INSTANCE), expressionTypes.get(NodeRef.of(expression))); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/TranslateExpressions.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/TranslateExpressions.java index cdb95294b67f..a4220acefaeb 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/TranslateExpressions.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/iterative/rule/TranslateExpressions.java @@ -42,7 +42,7 @@ import static com.facebook.presto.sql.relational.OriginalExpressionUtils.isExpression; import static com.google.common.base.Verify.verify; import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; public class TranslateExpressions extends RowExpressionRewriteRuleSet @@ -134,7 +134,7 @@ private Map, Type> analyzeCallExpressionTypes(CallExpression sqlParser, TypeProvider.copyOf(lambdaArgumentSymbolTypes), lambdaExpression.getBody(), - emptyList(), + emptyMap(), NOOP)); } } @@ -155,7 +155,7 @@ private Map, Type> analyze(Expression expression, Session se sqlParser, typeProvider, expression, - emptyList(), + emptyMap(), NOOP); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/ExpressionEquivalence.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/ExpressionEquivalence.java index 214c02b8aab2..ec6306b23f5f 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/ExpressionEquivalence.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/optimizations/ExpressionEquivalence.java @@ -62,7 +62,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.ImmutableList.toImmutableList; import static java.lang.Integer.min; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Objects.requireNonNull; public class ExpressionEquivalence @@ -115,7 +115,7 @@ private RowExpression toRowExpression(Session session, Expression expression, Ma sqlParser, types, expression, - emptyList(), /* parameters have already been replaced */ + emptyMap(), /* parameters have already been replaced */ WarningCollector.NOOP); // convert to row expression diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/sanity/TypeValidator.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/sanity/TypeValidator.java index 28613104150e..e6d59f944c3f 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/planner/sanity/TypeValidator.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/sanity/TypeValidator.java @@ -46,7 +46,7 @@ import static com.facebook.presto.sql.relational.OriginalExpressionUtils.isExpression; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Objects.requireNonNull; /** @@ -124,7 +124,7 @@ public Void visitProject(ProjectNode node, Void context) verifyTypeSignature(entry.getKey(), types.get(symbolReference).getTypeSignature()); continue; } - Map, Type> expressionTypes = getExpressionTypes(session, metadata, sqlParser, types, castToExpression(expression), emptyList(), warningCollector); + Map, Type> expressionTypes = getExpressionTypes(session, metadata, sqlParser, types, castToExpression(expression), emptyMap(), warningCollector); Type actualType = expressionTypes.get(NodeRef.of(castToExpression(expression))); verifyTypeSignature(entry.getKey(), actualType.getTypeSignature()); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/DescribeInputRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/DescribeInputRewrite.java index b2515c9d001d..08b00d7a3500 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/DescribeInputRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/DescribeInputRewrite.java @@ -28,6 +28,7 @@ import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.LongLiteral; import com.facebook.presto.sql.tree.Node; +import com.facebook.presto.sql.tree.NodeRef; import com.facebook.presto.sql.tree.NullLiteral; import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.Row; @@ -36,6 +37,7 @@ import com.google.common.collect.ImmutableList; import java.util.List; +import java.util.Map; import java.util.Optional; import static com.facebook.presto.common.type.UnknownType.UNKNOWN; @@ -62,10 +64,11 @@ public Statement rewrite( Optional queryExplainer, Statement node, List parameters, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector) { - return (Statement) new Visitor(session, parser, metadata, queryExplainer, parameters, accessControl, warningCollector).process(node, null); + return (Statement) new Visitor(session, parser, metadata, queryExplainer, parameters, parameterLookup, accessControl, warningCollector).process(node, null); } private static final class Visitor @@ -76,6 +79,7 @@ private static final class Visitor private final Metadata metadata; private final Optional queryExplainer; private final List parameters; + private final Map, Expression> parameterLookup; private final AccessControl accessControl; private final WarningCollector warningCollector; @@ -85,6 +89,7 @@ public Visitor( Metadata metadata, Optional queryExplainer, List parameters, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector) { @@ -94,6 +99,7 @@ public Visitor( this.queryExplainer = queryExplainer; this.accessControl = accessControl; this.parameters = parameters; + this.parameterLookup = parameterLookup; this.warningCollector = requireNonNull(warningCollector, "warningCollector is null"); } @@ -105,7 +111,7 @@ protected Node visitDescribeInput(DescribeInput node, Void context) Statement statement = parser.createStatement(sqlString, createParsingOptions(session, warningCollector)); // create analysis for the query we are describing. - Analyzer analyzer = new Analyzer(session, metadata, parser, accessControl, queryExplainer, parameters, warningCollector); + Analyzer analyzer = new Analyzer(session, metadata, parser, accessControl, queryExplainer, parameters, parameterLookup, warningCollector); Analysis analysis = analyzer.analyze(statement, true); // get all parameters in query diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/DescribeOutputRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/DescribeOutputRewrite.java index 97a45171aacb..05388885f4a6 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/DescribeOutputRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/DescribeOutputRewrite.java @@ -30,13 +30,16 @@ import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.LongLiteral; import com.facebook.presto.sql.tree.Node; +import com.facebook.presto.sql.tree.NodeRef; import com.facebook.presto.sql.tree.NullLiteral; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.Row; import com.facebook.presto.sql.tree.Statement; import com.facebook.presto.sql.tree.StringLiteral; import com.google.common.collect.ImmutableList; import java.util.List; +import java.util.Map; import java.util.Optional; import static com.facebook.presto.sql.ParsingUtil.createParsingOptions; @@ -59,10 +62,11 @@ public Statement rewrite( Optional queryExplainer, Statement node, List parameters, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector) { - return (Statement) new Visitor(session, parser, metadata, queryExplainer, parameters, accessControl, warningCollector).process(node, null); + return (Statement) new Visitor(session, parser, metadata, queryExplainer, parameters, parameterLookup, accessControl, warningCollector).process(node, null); } private static final class Visitor @@ -73,6 +77,7 @@ private static final class Visitor private final Metadata metadata; private final Optional queryExplainer; private final List parameters; + private final Map, Expression> parameterLookup; private final AccessControl accessControl; private final WarningCollector warningCollector; @@ -82,6 +87,7 @@ public Visitor( Metadata metadata, Optional queryExplainer, List parameters, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector) { @@ -90,6 +96,7 @@ public Visitor( this.metadata = metadata; this.queryExplainer = queryExplainer; this.parameters = parameters; + this.parameterLookup = parameterLookup; this.accessControl = accessControl; this.warningCollector = requireNonNull(warningCollector, "warningCollector is null"); } @@ -100,7 +107,7 @@ protected Node visitDescribeOutput(DescribeOutput node, Void context) String sqlString = session.getPreparedStatement(node.getName().getValue()); Statement statement = parser.createStatement(sqlString, createParsingOptions(session, warningCollector)); - Analyzer analyzer = new Analyzer(session, metadata, parser, accessControl, queryExplainer, parameters, warningCollector); + Analyzer analyzer = new Analyzer(session, metadata, parser, accessControl, queryExplainer, parameters, parameterLookup, warningCollector); Analysis analysis = analyzer.analyze(statement, true); Optional limit = Optional.empty(); diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ExplainRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ExplainRewrite.java index 304b8bff447a..e81f9090cf79 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ExplainRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ExplainRewrite.java @@ -29,9 +29,12 @@ import com.facebook.presto.sql.tree.ExplainType; import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.Node; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.Statement; import java.util.List; +import java.util.Map; import java.util.Optional; import static com.facebook.presto.sql.QueryUtil.singleValueQuery; @@ -52,7 +55,8 @@ public Statement rewrite( SqlParser parser, Optional queryExplainer, Statement node, - List parameters, + List parameter, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector) { diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/MaterializedViewOptimizationRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/MaterializedViewOptimizationRewrite.java index 8d08dfc98c31..8bb31cb01bfd 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/MaterializedViewOptimizationRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/MaterializedViewOptimizationRewrite.java @@ -23,10 +23,13 @@ import com.facebook.presto.sql.tree.AstVisitor; import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.Node; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.Query; import com.facebook.presto.sql.tree.Statement; import java.util.List; +import java.util.Map; import java.util.Optional; import static com.facebook.presto.sql.rewrite.MaterializedViewOptimizationRewriteUtils.optimizeQueryUsingMaterializedView; @@ -43,6 +46,7 @@ public Statement rewrite( Optional queryExplainer, Statement node, List parameters, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector) { diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowQueriesRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowQueriesRewrite.java index ad95d287070e..59413f091113 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowQueriesRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowQueriesRewrite.java @@ -57,7 +57,9 @@ import com.facebook.presto.sql.tree.LikePredicate; import com.facebook.presto.sql.tree.LongLiteral; import com.facebook.presto.sql.tree.Node; +import com.facebook.presto.sql.tree.NodeRef; import com.facebook.presto.sql.tree.OrderBy; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.Property; import com.facebook.presto.sql.tree.QualifiedName; import com.facebook.presto.sql.tree.Query; @@ -163,6 +165,7 @@ public Statement rewrite( Optional queryExplainer, Statement node, List parameters, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector) { diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowStatsRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowStatsRewrite.java index 59e44ae20e2c..a8abf74575a7 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowStatsRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/ShowStatsRewrite.java @@ -49,7 +49,9 @@ import com.facebook.presto.sql.tree.Expression; import com.facebook.presto.sql.tree.Identifier; import com.facebook.presto.sql.tree.Node; +import com.facebook.presto.sql.tree.NodeRef; import com.facebook.presto.sql.tree.NullLiteral; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.QualifiedName; import com.facebook.presto.sql.tree.Query; import com.facebook.presto.sql.tree.QuerySpecification; @@ -94,7 +96,15 @@ public class ShowStatsRewrite private static final Expression NULL_VARCHAR = new Cast(new NullLiteral(), VARCHAR); @Override - public Statement rewrite(Session session, Metadata metadata, SqlParser parser, Optional queryExplainer, Statement node, List parameters, AccessControl accessControl, WarningCollector warningCollector) + public Statement rewrite(Session session, + Metadata metadata, + SqlParser parser, + Optional queryExplainer, + Statement node, + List parameters, + Map, Expression> parameterLookup, + AccessControl accessControl, + WarningCollector warningCollector) { return (Statement) new Visitor(metadata, session, parameters, queryExplainer, warningCollector).process(node, null); } diff --git a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/StatementRewrite.java b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/StatementRewrite.java index 603d0067bc81..e6feb4159f87 100644 --- a/presto-main/src/main/java/com/facebook/presto/sql/rewrite/StatementRewrite.java +++ b/presto-main/src/main/java/com/facebook/presto/sql/rewrite/StatementRewrite.java @@ -20,10 +20,13 @@ import com.facebook.presto.sql.analyzer.QueryExplainer; import com.facebook.presto.sql.parser.SqlParser; import com.facebook.presto.sql.tree.Expression; +import com.facebook.presto.sql.tree.NodeRef; +import com.facebook.presto.sql.tree.Parameter; import com.facebook.presto.sql.tree.Statement; import com.google.common.collect.ImmutableList; import java.util.List; +import java.util.Map; import java.util.Optional; import static java.util.Objects.requireNonNull; @@ -47,11 +50,12 @@ public static Statement rewrite( Optional queryExplainer, Statement node, List parameters, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector) { for (Rewrite rewrite : REWRITES) { - node = requireNonNull(rewrite.rewrite(session, metadata, parser, queryExplainer, node, parameters, accessControl, warningCollector), "Statement rewrite returned null"); + node = requireNonNull(rewrite.rewrite(session, metadata, parser, queryExplainer, node, parameters, parameterLookup, accessControl, warningCollector), "Statement rewrite returned null"); } return node; } @@ -65,6 +69,7 @@ Statement rewrite( Optional queryExplainer, Statement node, List parameters, + Map, Expression> parameterLookup, AccessControl accessControl, WarningCollector warningCollector); } 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 0ec46bff9c25..ab9fa7541948 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 @@ -241,6 +241,7 @@ import static com.facebook.presto.spi.connector.ConnectorSplitManager.SplitSchedulingStrategy.REWINDABLE_GROUPED_SCHEDULING; 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.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.ParsingUtil.createParsingOptions; import static com.facebook.presto.sql.planner.optimizations.PlanNodeSearcher.searchFrom; import static com.facebook.presto.sql.testing.TreeAssertions.assertFormattedSql; @@ -1012,7 +1013,7 @@ public Plan createPlan(Session session, @Language("SQL") String sql, List, Type> expressionTypes = getExpressionTypes(session, metadata, SQL_PARSER, SYMBOL_TYPES, expression, emptyList(), WarningCollector.NOOP); + Map, Type> expressionTypes = getExpressionTypes(session, metadata, SQL_PARSER, SYMBOL_TYPES, expression, emptyMap(), WarningCollector.NOOP); ExpressionInterpreter evaluator = ExpressionInterpreter.expressionInterpreter(expression, metadata, session, expressionTypes); Object result = evaluator.evaluate(variable -> { diff --git a/presto-main/src/test/java/com/facebook/presto/sql/TestExpressionInterpreter.java b/presto-main/src/test/java/com/facebook/presto/sql/TestExpressionInterpreter.java index 2b6ab2fda1eb..54e5be70d79d 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/TestExpressionInterpreter.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/TestExpressionInterpreter.java @@ -98,7 +98,7 @@ import static com.facebook.presto.util.DateTimeZoneIndex.getDateTimeZone; import static io.airlift.slice.Slices.utf8Slice; import static java.lang.String.format; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Locale.ENGLISH; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertThrows; @@ -1604,7 +1604,7 @@ private static RowExpression toRowExpression(Expression expression) private static Object optimize(Expression expression) { - Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, METADATA, SQL_PARSER, SYMBOL_TYPES, expression, emptyList(), WarningCollector.NOOP); + Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, METADATA, SQL_PARSER, SYMBOL_TYPES, expression, emptyMap(), WarningCollector.NOOP); ExpressionInterpreter interpreter = expressionOptimizer(expression, METADATA, TEST_SESSION, expressionTypes); return interpreter.optimize(variable -> { Symbol symbol = new Symbol(variable.getName()); @@ -1789,7 +1789,7 @@ private static void assertRoundTrip(String expression) private static Object evaluate(Expression expression, boolean deterministic) { - Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, METADATA, SQL_PARSER, SYMBOL_TYPES, expression, emptyList(), WarningCollector.NOOP); + Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, METADATA, SQL_PARSER, SYMBOL_TYPES, expression, emptyMap(), WarningCollector.NOOP); Object expressionResult = expressionInterpreter(expression, METADATA, TEST_SESSION, expressionTypes).evaluate(); Object rowExpressionResult = rowExpressionInterpreter(TRANSLATOR.translateAndOptimize(expression), METADATA, TEST_SESSION.toConnectorSession()).evaluate(); diff --git a/presto-main/src/test/java/com/facebook/presto/sql/TestRowExpressionSerde.java b/presto-main/src/test/java/com/facebook/presto/sql/TestRowExpressionSerde.java index 805932bc50f5..d97ea5205d54 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/TestRowExpressionSerde.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/TestRowExpressionSerde.java @@ -86,7 +86,7 @@ import static com.facebook.presto.sql.relational.Expressions.specialForm; import static com.google.inject.multibindings.Multibinder.newSetBinder; import static java.lang.Float.floatToIntBits; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertThrows; import static org.testng.Assert.assertTrue; @@ -282,7 +282,7 @@ private Map, Type> getExpressionTypes(Expression expression) metadata.getFunctionAndTypeManager(), TEST_SESSION, TypeProvider.empty(), - emptyList(), + emptyMap(), node -> new IllegalStateException("Unexpected node: %s" + node), WarningCollector.NOOP, false); diff --git a/presto-main/src/test/java/com/facebook/presto/sql/TestingRowExpressionTranslator.java b/presto-main/src/test/java/com/facebook/presto/sql/TestingRowExpressionTranslator.java index e405d694d7c8..64bacb50ae9d 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/TestingRowExpressionTranslator.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/TestingRowExpressionTranslator.java @@ -35,7 +35,7 @@ import static com.facebook.presto.SessionTestUtils.TEST_SESSION; import static com.facebook.presto.spi.relation.ExpressionOptimizer.Level.OPTIMIZED; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; public class TestingRowExpressionTranslator { @@ -101,7 +101,7 @@ private Map, Type> getExpressionTypes(Expression expression, metadata.getFunctionAndTypeManager(), TEST_SESSION, typeProvider, - emptyList(), + emptyMap(), node -> new IllegalStateException("Unexpected node: %s" + node), WarningCollector.NOOP, false); diff --git a/presto-main/src/test/java/com/facebook/presto/sql/analyzer/AbstractAnalyzerTest.java b/presto-main/src/test/java/com/facebook/presto/sql/analyzer/AbstractAnalyzerTest.java index c5e22cee03aa..03de293bd84e 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/analyzer/AbstractAnalyzerTest.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/analyzer/AbstractAnalyzerTest.java @@ -86,6 +86,7 @@ import static com.facebook.presto.transaction.TransactionBuilder.transaction; import static java.lang.String.format; import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static org.testng.Assert.fail; public class AbstractAnalyzerTest @@ -429,6 +430,7 @@ protected static Analyzer createAnalyzer(Session session, Metadata metadata, War new AllowAllAccessControl(), Optional.empty(), emptyList(), + emptyMap(), warningCollector); } diff --git a/presto-main/src/test/java/com/facebook/presto/sql/gen/CommonSubExpressionBenchmark.java b/presto-main/src/test/java/com/facebook/presto/sql/gen/CommonSubExpressionBenchmark.java index a83849ecf6b0..95788532f898 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/gen/CommonSubExpressionBenchmark.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/gen/CommonSubExpressionBenchmark.java @@ -68,7 +68,7 @@ import static com.facebook.presto.operator.scalar.FunctionAssertions.createExpression; import static com.facebook.presto.spi.relation.ExpressionOptimizer.Level.OPTIMIZED; import static com.facebook.presto.sql.analyzer.ExpressionAnalyzer.getExpressionTypes; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Locale.ENGLISH; import static java.util.stream.Collectors.toList; @@ -183,7 +183,7 @@ private RowExpression rowExpression(String value) { Expression expression = createExpression(value, METADATA, TypeProvider.copyOf(symbolTypes)); - Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, METADATA, SQL_PARSER, TypeProvider.copyOf(symbolTypes), expression, emptyList(), WarningCollector.NOOP); + Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, METADATA, SQL_PARSER, TypeProvider.copyOf(symbolTypes), expression, emptyMap(), WarningCollector.NOOP); RowExpression rowExpression = SqlToRowExpressionTranslator.translate(expression, expressionTypes, sourceLayout, METADATA.getFunctionAndTypeManager(), TEST_SESSION); RowExpressionOptimizer optimizer = new RowExpressionOptimizer(METADATA); return optimizer.optimize(rowExpression, OPTIMIZED, TEST_SESSION.toConnectorSession()); diff --git a/presto-main/src/test/java/com/facebook/presto/sql/gen/PageProcessorBenchmark.java b/presto-main/src/test/java/com/facebook/presto/sql/gen/PageProcessorBenchmark.java index 6154a1f23221..3061e5625896 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/gen/PageProcessorBenchmark.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/gen/PageProcessorBenchmark.java @@ -67,7 +67,7 @@ import static com.facebook.presto.operator.scalar.FunctionAssertions.createExpression; import static com.facebook.presto.spi.relation.ExpressionOptimizer.Level.OPTIMIZED; import static com.facebook.presto.sql.analyzer.ExpressionAnalyzer.getExpressionTypes; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.Locale.ENGLISH; import static java.util.stream.Collectors.toList; @@ -181,7 +181,7 @@ private RowExpression rowExpression(String value) { Expression expression = createExpression(value, METADATA, TypeProvider.copyOf(symbolTypes)); - Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, METADATA, SQL_PARSER, TypeProvider.copyOf(symbolTypes), expression, emptyList(), WarningCollector.NOOP); + Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, METADATA, SQL_PARSER, TypeProvider.copyOf(symbolTypes), expression, emptyMap(), WarningCollector.NOOP); RowExpression rowExpression = SqlToRowExpressionTranslator.translate(expression, expressionTypes, sourceLayout, METADATA.getFunctionAndTypeManager(), TEST_SESSION); RowExpressionOptimizer optimizer = new RowExpressionOptimizer(METADATA); return optimizer.optimize(rowExpression, OPTIMIZED, TEST_SESSION.toConnectorSession()); diff --git a/presto-main/src/test/java/com/facebook/presto/sql/gen/TestCommonSubExpressionRewritter.java b/presto-main/src/test/java/com/facebook/presto/sql/gen/TestCommonSubExpressionRewritter.java index 6e84f64c4a69..77abaac87f9a 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/gen/TestCommonSubExpressionRewritter.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/gen/TestCommonSubExpressionRewritter.java @@ -141,7 +141,7 @@ private RowExpression rowExpression(String sql) new SqlParser(), TYPES, expression, - ImmutableList.of(), + ImmutableMap.of(), WarningCollector.NOOP); return SqlToRowExpressionTranslator.translate( expression, diff --git a/presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/rule/TestInlineSqlFunctions.java b/presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/rule/TestInlineSqlFunctions.java index 0665b4ecb677..0385d51386d8 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/rule/TestInlineSqlFunctions.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/rule/TestInlineSqlFunctions.java @@ -223,7 +223,7 @@ private void assertInlined(RuleTester tester, String inputSql, String expected, tester.getSqlParser(), viewOf(variableTypes), inputSqlExpression, - ImmutableList.of(), + ImmutableMap.of(), WarningCollector.NOOP); Expression inlinedExpression = InlineSqlFunctions.InlineSqlFunctionsRewriter.rewrite( inputSqlExpression, diff --git a/presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/rule/test/PlanBuilder.java b/presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/rule/test/PlanBuilder.java index a189b06a941f..94d46eb008f6 100644 --- a/presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/rule/test/PlanBuilder.java +++ b/presto-main/src/test/java/com/facebook/presto/sql/planner/iterative/rule/test/PlanBuilder.java @@ -925,7 +925,7 @@ public RowExpression rowExpression(String sql) new SqlParser(), getTypes(), expression, - ImmutableList.of(), + ImmutableMap.of(), WarningCollector.NOOP); return SqlToRowExpressionTranslator.translate( expression, diff --git a/presto-main/src/test/java/com/facebook/presto/type/BenchmarkDecimalOperators.java b/presto-main/src/test/java/com/facebook/presto/type/BenchmarkDecimalOperators.java index 3b5556307438..eb26a38db4e1 100644 --- a/presto-main/src/test/java/com/facebook/presto/type/BenchmarkDecimalOperators.java +++ b/presto-main/src/test/java/com/facebook/presto/type/BenchmarkDecimalOperators.java @@ -74,7 +74,7 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static java.math.BigInteger.ONE; import static java.math.BigInteger.ZERO; -import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static java.util.stream.Collectors.toList; import static org.openjdk.jmh.annotations.Scope.Thread; @@ -608,7 +608,7 @@ private RowExpression rowExpression(String value) { Expression expression = createExpression(value, metadata, TypeProvider.copyOf(symbolTypes)); - Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, metadata, SQL_PARSER, TypeProvider.copyOf(symbolTypes), expression, emptyList(), WarningCollector.NOOP); + Map, Type> expressionTypes = getExpressionTypes(TEST_SESSION, metadata, SQL_PARSER, TypeProvider.copyOf(symbolTypes), expression, emptyMap(), WarningCollector.NOOP); RowExpression rowExpression = SqlToRowExpressionTranslator.translate(expression, expressionTypes, sourceLayout, metadata.getFunctionAndTypeManager(), TEST_SESSION); RowExpressionOptimizer optimizer = new RowExpressionOptimizer(metadata); return optimizer.optimize(rowExpression, OPTIMIZED, TEST_SESSION.toConnectorSession()); diff --git a/presto-pinot-toolkit/src/test/java/com/facebook/presto/pinot/TestPinotQueryBase.java b/presto-pinot-toolkit/src/test/java/com/facebook/presto/pinot/TestPinotQueryBase.java index db6875c13637..c4bad6d55b8d 100644 --- a/presto-pinot-toolkit/src/test/java/com/facebook/presto/pinot/TestPinotQueryBase.java +++ b/presto-pinot-toolkit/src/test/java/com/facebook/presto/pinot/TestPinotQueryBase.java @@ -233,7 +233,7 @@ protected RowExpression toRowExpression(Expression expression, Session session) new SqlParser(), typeProvider, expression, - ImmutableList.of(), + ImmutableMap.of(), WarningCollector.NOOP); return SqlToRowExpressionTranslator.translate(expression, expressionTypes, ImmutableMap.of(), functionAndTypeManager, session); } diff --git a/presto-spark-base/src/main/java/com/facebook/presto/spark/planner/PrestoSparkQueryPlanner.java b/presto-spark-base/src/main/java/com/facebook/presto/spark/planner/PrestoSparkQueryPlanner.java index 7d8ef4111640..85521852ab54 100644 --- a/presto-spark-base/src/main/java/com/facebook/presto/spark/planner/PrestoSparkQueryPlanner.java +++ b/presto-spark-base/src/main/java/com/facebook/presto/spark/planner/PrestoSparkQueryPlanner.java @@ -44,6 +44,7 @@ import java.util.Optional; import java.util.Set; +import static com.facebook.presto.sql.ParameterUtils.parameterExtractor; import static com.facebook.presto.sql.planner.LogicalPlanner.Stage.OPTIMIZED_AND_VALIDATED; import static com.facebook.presto.util.StatementUtils.getQueryType; import static java.util.Objects.requireNonNull; @@ -91,6 +92,7 @@ public PlanAndMore createQueryPlan(Session session, PreparedQuery preparedQuery, accessControl, Optional.of(queryExplainer), preparedQuery.getParameters(), + parameterExtractor(preparedQuery.getStatement(), preparedQuery.getParameters()), warningCollector); LogicalPlanner logicalPlanner = new LogicalPlanner( diff --git a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java index 05d1c0e6c32b..9f8e12afda8d 100644 --- a/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java +++ b/presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java @@ -5027,6 +5027,20 @@ public void testExecuteUsingColumnReferenceFails() } } + @Test + public void testExecuteUsingWithWithClause() + { + String query = "WITH src AS (SELECT * FROM (VALUES (1, 4),(2, 5), (3, 6)) AS t(id1, id2) WHERE id2 = ?)" + + " SELECT * from src WHERE id1 between ? and ?"; + + Session session = Session.builder(getSession()) + .addPreparedStatement("my_query", query) + .build(); + assertQuery(session, + "EXECUTE my_query USING 6, 0, 10", + "VALUES (3, 6)"); + } + @Test public void testExecuteNoSuchQuery() {