From 711ce42a10fa1800202fafba721443b9347ed707 Mon Sep 17 00:00:00 2001 From: Yang Yang Date: Sat, 22 Oct 2016 20:19:20 -0700 Subject: [PATCH] Desugar the expressions before evaluating the constant values ValuesNode is trying to evaluate its expressions to be constant values with ExpressionInterpreter before DesugaringOptimizer has been run, while ExpressionInterpreter is not aware of AT TIME ZONE. And this will cause query failure when using AT TIME ZONE in VALUES. This change will ensure desugaring has been done when evaluating expressions to be constant values. --- .../presto/sql/planner/ExpressionInterpreter.java | 9 ++++++++- .../com/facebook/presto/tests/AbstractTestQueries.java | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) 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 ee47ae2f33eb..02b5ad0d32a7 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 @@ -202,13 +202,20 @@ public Expression rewriteExpression(Expression node, Void context, ExpressionTre } }, expression); + // redo the analysis since above expression rewriter might create new expressions which do not have entries in the type map + ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters); + analyzer.analyze(rewrite, Scope.builder().build()); + + // remove syntax sugar + rewrite = ExpressionTreeRewriter.rewriteWith(new DesugaringRewriter(analyzer.getExpressionTypes()), rewrite); + // expressionInterpreter/optimizer only understands a subset of expression types // TODO: remove this when the new expression tree is implemented Expression canonicalized = CanonicalizeExpressions.canonicalizeExpression(rewrite); // The optimization above may have rewritten the expression tree which breaks all the identity maps, so redo the analysis // to re-analyze coercions that might be necessary - ExpressionAnalyzer analyzer = createConstantAnalyzer(metadata, session, parameters); + analyzer = createConstantAnalyzer(metadata, session, parameters); analyzer.analyze(canonicalized, Scope.builder().build()); // evaluate the expression 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 c8267ffa693a..64b1c3c45b0b 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 @@ -5327,6 +5327,9 @@ public void testAtTimeZone() assertQuery("SELECT TIMESTAMP '2012-10-31 01:00' AT TIME ZONE 'America/Los_Angeles' AT TIME ZONE 'Asia/Shanghai'", "SELECT TIMESTAMP '2012-10-30 18:00:00.000 America/Los_Angeles'"); assertQuery("SELECT min(x) AT TIME ZONE 'America/Los_Angeles' AT TIME ZONE 'UTC' FROM (values TIMESTAMP '1970-01-01 00:01:00+00:00', TIMESTAMP '1970-01-01 08:01:00+08:00', TIMESTAMP '1969-12-31 16:01:00-08:00') t(x)", "values TIMESTAMP '1969-12-31 16:01:00-08:00'"); + + // with AT TIME ZONE in VALUES + assertQuery("SELECT * from (VALUES TIMESTAMP '2012-10-31 01:00' AT TIME ZONE 'Asia/Oral')", "SELECT TIMESTAMP '2012-10-30 18:00:00.000 America/Los_Angeles'"); } @Test