Repository: prestodb/presto
Issue: Planning Class cast exception

This query now throws an error:

```
SELECT
  (MAX(x.a) OVER () - x.a) * 100.0 / MAX(x.a) OVER ()
FROM (
  SELECT 1 as a
) x
```

```
Query 20161005_231326_03851_gb7jd failed: com.facebook.presto.sql.tree.SymbolReference cannot be cast to com.facebook.presto.sql.tree.FunctionCall
java.lang.ClassCastException: com.facebook.presto.sql.tree.SymbolReference cannot be cast to com.facebook.presto.sql.tree.FunctionCall
    at com.facebook.presto.sql.planner.QueryPlanner.window(QueryPlanner.java:617)
    at com.facebook.presto.sql.planner.QueryPlanner.plan(QueryPlanner.java:140)
    at com.facebook.presto.sql.planner.RelationPlanner.visitQuerySpecification(RelationPlanner.java:443)
    at com.facebook.presto.sql.planner.RelationPlanner.visitQuerySpecification(RelationPlanner.java:94)
    at com.facebook.presto.sql.tree.QuerySpecification.accept(QuerySpecification.java:125)
    at com.facebook.presto.sql.tree.AstVisitor.process(AstVisitor.java:22)
    at com.facebook.presto.sql.planner.QueryPlanner.planQueryBody(QueryPlanner.java:220)
    at com.facebook.presto.sql.planner.QueryPlanner.plan(QueryPlanner.java:113)
    at com.facebook.presto.sql.planner.RelationPlanner.visitQuery(RelationPlanner.java:436)
    at com.facebook.presto.sql.planner.RelationPlanner.visitQuery(RelationPlanner.java:94)
    at com.facebook.presto.sql.tree.Query.accept(Query.java:103)
    at com.facebook.presto.sql.tree.AstVisitor.process(AstVisitor.java:22)
    at com.facebook.presto.sql.planner.LogicalPlanner.createRelationPlan(LogicalPlanner.java:358)
    at com.facebook.presto.sql.planner.LogicalPlanner.planStatement(LogicalPlanner.java:150)
    at com.facebook.presto.sql.planner.LogicalPlanner.plan(LogicalPlanner.java:112)
    at com.facebook.presto.sql.planner.LogicalPlanner.plan(LogicalPlanner.java:107)
    at com.facebook.presto.execution.SqlQueryExecution.doAnalyzeQuery(SqlQueryExecution.java:291)
    at com.facebook.presto.execution.SqlQueryExecution.analyzeQuery(SqlQueryExecution.java:270)
    at com.facebook.presto.execution.SqlQueryExecution.start(SqlQueryExecution.java:228)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
```


Changed files:
presto-tests/src/main/java/com/facebook/presto/tests/AbstractTestQueries.java, presto-main/src/main/java/com/facebook/presto/sql/planner/QueryPlanner.java

diff --git a/presto-main/src/main/java/com/facebook/presto/sql/planner/QueryPlanner.java b/presto-main/src/main/java/com/facebook/presto/sql/planner/QueryPlanner.java
index 9c25114f99..71f2b7c62b 100644
--- a/presto-main/src/main/java/com/facebook/presto/sql/planner/QueryPlanner.java
+++ b/presto-main/src/main/java/com/facebook/presto/sql/planner/QueryPlanner.java
@@ -600,18 +600,22 @@ class QueryPlanner
             outputTranslations.addIntermediateMapping(windowFunction, parametersReplaced);
             Expression rewritten = subPlan.rewrite(parametersReplaced);
 
+            boolean needCoercion = rewritten instanceof Cast;
+            // Strip out the cast and add it back as a post-projection
+            if (rewritten instanceof Cast) {
+                rewritten = ((Cast) rewritten).getExpression();
+            }
+
             // If refers to existing symbol, don't create another PlanNode
             if (rewritten instanceof SymbolReference) {
+                if (needCoercion) {
+                    subPlan = explicitCoercionSymbols(subPlan, subPlan.getRoot().getOutputSymbols(), ImmutableList.of(windowFunction));
+                }
+
                 continue;
             }
 
             Symbol newSymbol = symbolAllocator.newSymbol(rewritten, analysis.getType(windowFunction));
-
-            boolean needCoercion = rewritten instanceof Cast;
-            // Strip out the cast and add it back as a post-projection
-            if (rewritten instanceof Cast) {
-                rewritten = ((Cast) rewritten).getExpression();
-            }
             outputTranslations.put(parametersReplaced, newSymbol);
 
             WindowNode.Function function = new WindowNode.Function(
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 30393eb08b..45a1af2979 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
@@ -3797,6 +3797,19 @@ public abstract class AbstractTestQueries
                 .build();
 
         assertEquals(actual, expected);
+
+        actual = computeActual("" +
+                "SELECT (MAX(x.a) OVER () - x.a) * 100.0 / MAX(x.a) OVER ()\\n" +
+                "FROM (VALUES 1, 2, 3, 4) x(a)");
+
+        expected = resultBuilder(getSession(), DOUBLE)
+                .row(75.0)
+                .row(50.0)
+                .row(25.0)
+                .row(0.0)
+                .build();
+
+        assertEquals(actual, expected);
     }
 
     @Test