http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q17_large_gby_variant/q17_large_gby_variant.3.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q17_large_gby_variant/q17_large_gby_variant.3.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q17_large_gby_variant/q17_large_gby_variant.3.ast
index 25bc7f7..63834e1 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q17_large_gby_variant/q17_large_gby_variant.3.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q17_large_gby_variant/q17_large_gby_variant.3.ast
@@ -13,10 +13,9 @@ RecordConstructor [
     FunctionCall asterix.count@1[
       (
         SELECT ELEMENT [
-        FunctionCall asterix.resolve@-1[
-          LiteralExpr [STRING] [l]
+        FunctionCall asterix.field-access-by-name@2[
           Variable [ Name=$g ]
-          Variable [ Name=$l_partkey ]
+          LiteralExpr [STRING] [l]
         ]
         ]
         FROM [          Variable [ Name=$g ]
@@ -41,10 +40,9 @@ RecordConstructor [
           ]
           FROM [            (
               SELECT ELEMENT [
-              FunctionCall asterix.resolve@-1[
-                LiteralExpr [STRING] [l]
+              FunctionCall asterix.field-access-by-name@2[
                 Variable [ Name=$g ]
-                Variable [ Name=$l_partkey ]
+                LiteralExpr [STRING] [l]
               ]
               ]
               FROM [                Variable [ Name=$g ]
@@ -70,10 +68,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -98,10 +95,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -126,10 +122,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -154,10 +149,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -182,10 +176,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -210,10 +203,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -238,10 +230,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -266,10 +257,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -294,10 +284,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$l_partkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q18_large_volume_customer/q18_large_volume_customer.3.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q18_large_volume_customer/q18_large_volume_customer.3.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q18_large_volume_customer/q18_large_volume_customer.3.ast
index 4446895..0ab8030 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q18_large_volume_customer/q18_large_volume_customer.3.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q18_large_volume_customer/q18_large_volume_customer.3.ast
@@ -40,14 +40,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [l]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$o_orderdate ]
-              Variable [ Name=$c_name ]
-              Variable [ Name=$o_orderkey ]
-              Variable [ Name=$o_totalprice ]
-              Variable [ Name=$c_custkey ]
+              LiteralExpr [STRING] [l]
             ]
             ]
             FROM [              Variable [ Name=$g ]
@@ -92,12 +87,9 @@ FROM [  FunctionCall asterix.dataset@1[
             ]
             FROM [              (
                 SELECT ELEMENT [
-                FunctionCall asterix.resolve@-1[
-                  LiteralExpr [STRING] [l]
-                  Variable [ Name=$o ]
-                  Variable [ Name=$l_orderkey ]
+                FunctionCall asterix.field-access-by-name@2[
                   Variable [ Name=$g2 ]
-                  Variable [ Name=$c ]
+                  LiteralExpr [STRING] [l]
                 ]
                 ]
                 FROM [                  Variable [ Name=$g2 ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q20_potential_part_promotion/q20_potential_part_promotion.3.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q20_potential_part_promotion/q20_potential_part_promotion.3.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q20_potential_part_promotion/q20_potential_part_promotion.3.ast
index 9ef07b1..41802c2 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q20_potential_part_promotion/q20_potential_part_promotion.3.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q20_potential_part_promotion/q20_potential_part_promotion.3.ast
@@ -62,11 +62,9 @@ FROM [  (
                   ]
                   FROM [                    (
                       SELECT ELEMENT [
-                      FunctionCall asterix.resolve@-1[
-                        LiteralExpr [STRING] [l]
-                        Variable [ Name=$l_suppkey ]
+                      FunctionCall asterix.field-access-by-name@2[
                         Variable [ Name=$g ]
-                        Variable [ Name=$l_partkey ]
+                        LiteralExpr [STRING] [l]
                       ]
                       ]
                       FROM [                        Variable [ Name=$g ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q21_suppliers_who_kept_orders_waiting/q21_suppliers_who_kept_orders_waiting.3.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q21_suppliers_who_kept_orders_waiting/q21_suppliers_who_kept_orders_waiting.3.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q21_suppliers_who_kept_orders_waiting/q21_suppliers_who_kept_orders_waiting.3.ast
index 62cbc19..b91a2a9 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q21_suppliers_who_kept_orders_waiting/q21_suppliers_who_kept_orders_waiting.3.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q21_suppliers_who_kept_orders_waiting/q21_suppliers_who_kept_orders_waiting.3.ast
@@ -481,23 +481,16 @@ Groupby
 
 Let Variable [ Name=$numwait ]
   :=
-  FunctionCall asterix.sql-count@1[
+  FunctionCall asterix.count@1[
     (
       SELECT ELEMENT [
-      (
-        SELECT ELEMENT [
-        FieldAccessor [
-          Variable [ Name=#1 ]
-          Field=t4
-        ]
-        ]
-        FROM [          Variable [ Name=$g ]
-          AS Variable [ Name=$g ]
-        ]
-      )
+      FunctionCall asterix.field-access-by-name@2[
+        Variable [ Name=$g ]
+        LiteralExpr [STRING] [t4]
+      ]
       ]
       FROM [        Variable [ Name=$g ]
-        AS Variable [ Name=#1 ]
+        AS Variable [ Name=$g ]
       ]
     )
   ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q22_global_sales_opportunity/q22_global_sales_opportunity.3.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q22_global_sales_opportunity/q22_global_sales_opportunity.3.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q22_global_sales_opportunity/q22_global_sales_opportunity.3.ast
index ffd3d1c..adeab44 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q22_global_sales_opportunity/q22_global_sales_opportunity.3.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q22_global_sales_opportunity/q22_global_sales_opportunity.3.ast
@@ -79,10 +79,9 @@ RecordConstructor [
     FunctionCall asterix.count@1[
       (
         SELECT ELEMENT [
-        FunctionCall asterix.resolve@-1[
-          LiteralExpr [STRING] [ct]
+        FunctionCall asterix.field-access-by-name@2[
           Variable [ Name=$g ]
-          Variable [ Name=$cntrycode ]
+          LiteralExpr [STRING] [ct]
         ]
         ]
         FROM [          Variable [ Name=$g ]
@@ -104,10 +103,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [ct]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$cntrycode ]
+              LiteralExpr [STRING] [ct]
             ]
             ]
             FROM [              Variable [ Name=$g ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue562/query-issue562.3.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue562/query-issue562.3.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue562/query-issue562.3.ast
index bbca35e..80ab8ce 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue562/query-issue562.3.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue562/query-issue562.3.ast
@@ -206,10 +206,9 @@ RecordConstructor [
         ]
         FROM [          (
             SELECT ELEMENT [
-            FunctionCall asterix.resolve@-1[
-              LiteralExpr [STRING] [ct]
+            FunctionCall asterix.field-access-by-name@2[
               Variable [ Name=$g ]
-              Variable [ Name=$cntrycode ]
+              LiteralExpr [STRING] [ct]
             ]
             ]
             FROM [              Variable [ Name=$g ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue601/query-issue601.3.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue601/query-issue601.3.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue601/query-issue601.3.ast
index f1705b8..2c32932 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue601/query-issue601.3.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue601/query-issue601.3.ast
@@ -5,32 +5,18 @@ RecordConstructor [
   (
     LiteralExpr [STRING] [l_linenumber]
     :
-    FieldAccessor [
-      FunctionCall asterix.resolve@-1[
-        LiteralExpr [STRING] [l]
-        Variable [ Name=$g ]
-        Variable [ Name=$l_linenumber ]
-      ]
-      Field=l_linenumber
-    ]
+    Variable [ Name=$l_linenumber ]
   )
   (
     LiteralExpr [STRING] [count_order]
     :
-    FunctionCall asterix.sql-count@1[
+    FunctionCall asterix.count@1[
       (
         SELECT ELEMENT [
-        (
-          SELECT ELEMENT [
-          Variable [ Name=$g ]
-          ]
-          FROM [            Variable [ Name=$g ]
-            AS Variable [ Name=$g ]
-          ]
-        )
+        Variable [ Name=$g ]
         ]
         FROM [          Variable [ Name=$g ]
-          AS Variable [ Name=#1 ]
+          AS Variable [ Name=$g ]
         ]
       )
     ]
@@ -55,13 +41,6 @@ Groupby
   )
 
 Orderby
-  FieldAccessor [
-    FunctionCall asterix.resolve@-1[
-      LiteralExpr [STRING] [l]
-      Variable [ Name=$g ]
-      Variable [ Name=$l_linenumber ]
-    ]
-    Field=l_linenumber
-  ]
+  Variable [ Name=$l_linenumber ]
   ASC
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue810-3/query-issue810-3.3.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue810-3/query-issue810-3.3.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue810-3/query-issue810-3.3.ast
index ffae08a..6e101a7 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue810-3/query-issue810-3.3.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/query-issue810-3/query-issue810-3.3.ast
@@ -85,11 +85,9 @@ Let Variable [ Name=$expensives ]
     ]
     FROM [      (
         SELECT ELEMENT [
-        FunctionCall asterix.resolve@-1[
-          LiteralExpr [STRING] [l]
+        FunctionCall asterix.field-access-by-name@2[
           Variable [ Name=$g ]
-          Variable [ Name=$l_linestatus ]
-          Variable [ Name=$l_returnflag ]
+          LiteralExpr [STRING] [l]
         ]
         ]
         FROM [          Variable [ Name=$g ]
@@ -116,12 +114,9 @@ Let Variable [ Name=$cheaps ]
     ]
     FROM [      (
         SELECT ELEMENT [
-        FunctionCall asterix.resolve@-1[
-          LiteralExpr [STRING] [l]
-          Variable [ Name=$expensives ]
+        FunctionCall asterix.field-access-by-name@2[
           Variable [ Name=$g ]
-          Variable [ Name=$l_linestatus ]
-          Variable [ Name=$l_returnflag ]
+          LiteralExpr [STRING] [l]
         ]
         ]
         FROM [          Variable [ Name=$g ]
@@ -171,13 +166,9 @@ Let Variable [ Name=$charges ]
     ]
     FROM [      (
         SELECT ELEMENT [
-        FunctionCall asterix.resolve@-1[
-          LiteralExpr [STRING] [l]
-          Variable [ Name=$expensives ]
+        FunctionCall asterix.field-access-by-name@2[
           Variable [ Name=$g ]
-          Variable [ Name=$l_linestatus ]
-          Variable [ Name=$l_returnflag ]
-          Variable [ Name=$cheaps ]
+          LiteralExpr [STRING] [l]
         ]
         ]
         FROM [          Variable [ Name=$g ]
@@ -209,14 +200,9 @@ Let Variable [ Name=$disc_prices ]
     ]
     FROM [      (
         SELECT ELEMENT [
-        FunctionCall asterix.resolve@-1[
-          LiteralExpr [STRING] [l]
-          Variable [ Name=$expensives ]
+        FunctionCall asterix.field-access-by-name@2[
           Variable [ Name=$g ]
-          Variable [ Name=$l_linestatus ]
-          Variable [ Name=$l_returnflag ]
-          Variable [ Name=$charges ]
-          Variable [ Name=$cheaps ]
+          LiteralExpr [STRING] [l]
         ]
         ]
         FROM [          Variable [ Name=$g ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/user-defined-functions/udf30/udf30.1.ast
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/user-defined-functions/udf30/udf30.1.ast
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/user-defined-functions/udf30/udf30.1.ast
index 646fafc..b787d0d 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/user-defined-functions/udf30/udf30.1.ast
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/user-defined-functions/udf30/udf30.1.ast
@@ -5,7 +5,7 @@ FunctionDecl abc([$y]) {
 Query:
 Let Variable [ Name=$z ]
   :=
-  FunctionCall asterix.resolve@-1[
+  FunctionCall asterix.dataset@1[
     LiteralExpr [STRING] [y]
   ]
 SELECT ELEMENT [

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml 
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index bc919db..0c6493d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -2787,7 +2787,7 @@
     <test-case FilePath="global-aggregate">
       <compilation-unit name="q05_error">
         <output-dir compare="Text">q01</output-dir>
-        <expected-error>Cannot find dataset u in dataverse TinySocial nor an 
alias with name u</expected-error>
+        <expected-error>Type mismatch: function field-access-by-name expects 
its 1st input parameter to be type object, but the actual input type is 
array</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="global-aggregate">
@@ -3579,7 +3579,6 @@
     <test-case FilePath="misc">
       <compilation-unit name="query-ASTERIXDB-1577">
         <output-dir compare="Text">query-ASTERIXDB-1577</output-dir>
-        <expected-error>Type mismatch: function field-access-by-name expects 
its 1st input parameter to be type object, but the actual input type is 
array</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="misc">
@@ -5403,6 +5402,16 @@
         <output-dir compare="Text">fullyqualified2</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="resolution">
+      <compilation-unit name="order_1">
+        <output-dir compare="Text">order_1</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="resolution">
+      <compilation-unit name="groupby_rename_with_sugar">
+        <output-dir compare="Text">groupby_rename_with_sugar</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="scan">
     <test-case FilePath="scan">
@@ -6437,7 +6446,6 @@
     <test-case FilePath="subquery">
       <compilation-unit name="query-ASTERIXDB-1574-3">
         <output-dir compare="Text">query-ASTERIXDB-1574</output-dir>
-        <expected-error>Cannot resolve ambiguous alias reference for undefined 
identifier</expected-error>
       </compilation-unit>
     </test-case>
     <test-case FilePath="subquery">
@@ -9061,12 +9069,6 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="union">
-      <compilation-unit name="union_negative_2">
-        <output-dir compare="Text">union</output-dir>
-        <expected-error>Cannot find dataset t in dataverse TinySocial nor an 
alias with name t</expected-error>
-      </compilation-unit>
-    </test-case>
-    <test-case FilePath="union">
       <compilation-unit name="union_negative_3">
         <output-dir compare="Text">union</output-dir>
         <expected-error>Operation UNION with set semantics is not 
supported.</expected-error>
@@ -9093,6 +9095,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="union">
+      <compilation-unit name="union_orderby_5">
+        <output-dir compare="Text">union_orderby_5</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="union">
       <compilation-unit name="query-ASTERIXDB-1354-2">
         <output-dir compare="Text">query-ASTERIXDB-1354-2</output-dir>
       </compilation-unit>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/pom.xml
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/pom.xml 
b/asterixdb/asterix-lang-common/pom.xml
index 0ee5030..a163e54 100644
--- a/asterixdb/asterix-lang-common/pom.xml
+++ b/asterixdb/asterix-lang-common/pom.xml
@@ -91,6 +91,10 @@
       <artifactId>commons-lang</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-collections4</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.apache.hyracks</groupId>
       <artifactId>algebricks-core</artifactId>
     </dependency>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IReturningStatement.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IReturningStatement.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IReturningStatement.java
index 02e5267..d31b765 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IReturningStatement.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IReturningStatement.java
@@ -19,6 +19,8 @@
 
 package org.apache.asterix.lang.common.base;
 
+import org.apache.asterix.lang.common.struct.VarIdentifier;
+
 import java.util.List;
 
 /**
@@ -64,4 +66,16 @@ public interface IReturningStatement extends Statement {
      *            the main body expression.
      */
     void setBody(Expression expr);
+
+    /**
+     * @return external (pre-defined) variables for the statement
+     */
+    List<VarIdentifier> getExternalVars();
+
+    /**
+     * Sets external (pre-defined) variables for the statement
+     *
+     * @param externalVars external variables
+     */
+    void setExternalVars(List<VarIdentifier> externalVars);
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
index ad277d3..df6d3a5 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/context/Scope.java
@@ -18,40 +18,39 @@
  */
 package org.apache.asterix.lang.common.context;
 
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.ArrayList;
 import java.util.Iterator;
-import java.util.Map;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.Set;
 
 import org.apache.asterix.common.functions.FunctionSignature;
-import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.parser.ScopeChecker;
-import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
 import org.apache.asterix.lang.common.struct.Identifier;
 import org.apache.asterix.lang.common.struct.VarIdentifier;
+import org.apache.commons.collections4.iterators.ReverseListIterator;
 
 public final class Scope {
-    private Scope parent;
-    private Map<String, Identifier> symbols = new HashMap<String, 
Identifier>();
-    private Map<String, Expression> varExprMap = new HashMap<String, 
Expression>();
-    private FunctionSignatures functionSignatures = null;
     private final ScopeChecker scopeChecker;
-    private boolean maskParentScope = false;
-
-    public Scope(ScopeChecker scopeChecker, Scope parent) {
-        this.scopeChecker = scopeChecker;
-        this.parent = parent;
-    }
+    private final Scope parent;
+    private final LinkedHashMap<String, Identifier> symbols;
+    private final boolean maskParentScope;
+    private FunctionSignatures functionSignatures;
 
     public Scope(ScopeChecker scopeChecker) {
         this(scopeChecker, null);
     }
 
+    public Scope(ScopeChecker scopeChecker, Scope parent) {
+        this(scopeChecker, parent, false);
+    }
+
     public Scope(ScopeChecker scopeChecker, Scope parent, boolean 
maskParentScope) {
-        this(scopeChecker, parent);
+        this.scopeChecker = scopeChecker;
+        this.parent = parent;
         this.maskParentScope = maskParentScope;
+        this.symbols = new LinkedHashMap<>();
     }
 
     /**
@@ -81,36 +80,6 @@ public final class Scope {
         symbols.put(ident.getValue(), ident);
     }
 
-    /**
-     * Add a symbol and its definition expression into the scope
-     *
-     * @param ident
-     */
-    public void addSymbolExpressionMappingToScope(VariableExpr ident, 
Expression expr) {
-        varExprMap.put(ident.getVar().getValue(), expr);
-    }
-
-    /**
-     * Remove a symbol and its definition expression into the scope
-     *
-     * @param ident
-     */
-    public Expression removeSymbolExpressionMapping(VariableExpr ident) {
-        if (ident == null) {
-            return null;
-        }
-        return varExprMap.remove(ident.getVar().getValue());
-    }
-
-    /**
-     * @return the variable substituion environment for inlining variable 
references by its original
-     */
-    public VariableSubstitutionEnvironment getVarSubstitutionEnvironment() {
-        VariableSubstitutionEnvironment env = new 
VariableSubstitutionEnvironment();
-        env.addMappings(varExprMap);
-        return env;
-    }
-
     public void addNewVarSymbolToScope(VarIdentifier ident) {
         scopeChecker.incVarCounter();
         ident.setId(scopeChecker.getVarCounter());
@@ -120,8 +89,8 @@ public final class Scope {
     /**
      * Add a FunctionDescriptor into functionSignatures
      *
-     * @param fd
-     *            FunctionDescriptor
+     * @param signature
+     *            FunctionSignature
      * @param varargs
      *            whether this function has varargs
      */
@@ -163,7 +132,6 @@ public final class Scope {
         if (functionSignatures != null && scope.functionSignatures != null) {
             functionSignatures.addAll(scope.functionSignatures);
         }
-        varExprMap.putAll(scope.varExprMap);
     }
 
     /**
@@ -171,16 +139,17 @@ public final class Scope {
      *
      * @return an iterator of visible symbols.
      */
-    public Iterator<Identifier> liveSymbols() {
-        final Iterator<Identifier> identifierIterator = 
symbols.values().iterator();
-        final Iterator<Identifier> parentIterator = parent == null ? null : 
parent.liveSymbols();
+    public Iterator<Identifier> liveSymbols(Scope stopAtExclusive) {
+        final Iterator<Identifier> identifierIterator = new 
ReverseListIterator<>(new ArrayList<>(symbols.values()));
+        final Iterator<Identifier> parentIterator =
+                parent == null || parent == stopAtExclusive ? null : 
parent.liveSymbols(stopAtExclusive);
         return new Iterator<Identifier>() {
             private Identifier currentSymbol = null;
 
             @Override
             public boolean hasNext() {
                 currentSymbol = null;
-                if (identifierIterator != null && 
identifierIterator.hasNext()) {
+                if (identifierIterator.hasNext()) {
                     currentSymbol = identifierIterator.next();
                 } else if (!maskParentScope && parentIterator != null && 
parentIterator.hasNext()) {
                     do {
@@ -214,8 +183,12 @@ public final class Scope {
     }
 
     public Set<VariableExpr> getLiveVariables() {
-        Set<VariableExpr> vars = new HashSet<VariableExpr>();
-        Iterator<Identifier> identifierIterator = liveSymbols();
+        return getLiveVariables(null);
+    }
+
+    public Set<VariableExpr> getLiveVariables(Scope stopAtExclusive) {
+        LinkedHashSet<VariableExpr> vars = new LinkedHashSet<>();
+        Iterator<Identifier> identifierIterator = liveSymbols(stopAtExclusive);
         while (identifierIterator.hasNext()) {
             Identifier identifier = identifierIterator.next();
             if (identifier instanceof VarIdentifier) {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
index 5cc759c..90b457e 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OperatorExpr.java
@@ -98,7 +98,7 @@ public class OperatorExpr extends AbstractExpression {
         addOperator(op);
     }
 
-    public void addOperator(OperatorType op) throws CompilationException {
+    public void addOperator(OperatorType op) {
         if (op == null) {
             throw new NullPointerException();
         }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/ScopeChecker.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/ScopeChecker.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/ScopeChecker.java
index 771ae16..7dadd67 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/ScopeChecker.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/parser/ScopeChecker.java
@@ -60,8 +60,7 @@ public class ScopeChecker {
      * @return new scope
      */
     public final Scope createNewScope() {
-        Scope parent = scopeStack.peek();
-        Scope scope = new Scope(this, parent);// top one as parent
+        Scope scope = extendCurrentScopeNoPush(false);
         scopeStack.push(scope);
         return scope;
     }
@@ -72,20 +71,14 @@ public class ScopeChecker {
      * @return
      */
     public final Scope extendCurrentScope() {
-        return extendCurrentScope(false);
-    }
-
-    public final Scope extendCurrentScope(boolean maskParentScope) {
-        Scope scope = extendCurrentScopeNoPush(maskParentScope);
-        scopeStack.pop();
-        scopeStack.push(scope);
+        Scope scope = extendCurrentScopeNoPush(false);
+        replaceCurrentScope(scope);
         return scope;
     }
 
-    public final Scope extendCurrentScopeNoPush(boolean maskParentScope) {
-        Scope scope = scopeStack.peek();
-        scope = new Scope(this, scope, maskParentScope);
-        return scope;
+    protected final Scope extendCurrentScopeNoPush(boolean maskParentScope) {
+        Scope parent = scopeStack.peek();
+        return new Scope(this, parent, maskParentScope);
     }
 
     public final void replaceCurrentScope(Scope scope) {
@@ -116,6 +109,15 @@ public class ScopeChecker {
     }
 
     /**
+     * get scope preceding the current scope
+     * @return preceding scope or {@code null} if current scope is the top one
+     */
+    public final Scope getPrecedingScope() {
+        int n = scopeStack.size();
+        return n > 1 ? scopeStack.get(n - 2) : null;
+    }
+
+    /**
      * find symbol in the scope
      *
      * @return identifier

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/InsertStatement.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/InsertStatement.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/InsertStatement.java
index 4cc2001..797f48a 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/InsertStatement.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/InsertStatement.java
@@ -28,6 +28,7 @@ import 
org.apache.asterix.lang.common.base.IReturningStatement;
 import org.apache.asterix.lang.common.base.Statement;
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.struct.Identifier;
+import org.apache.asterix.lang.common.struct.VarIdentifier;
 import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
 
 public class InsertStatement implements IReturningStatement {
@@ -114,6 +115,16 @@ public class InsertStatement implements 
IReturningStatement {
     }
 
     @Override
+    public List<VarIdentifier> getExternalVars() {
+        return null;
+    }
+
+    @Override
+    public void setExternalVars(List<VarIdentifier> externalVars) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws 
CompilationException {
         return visitor.visit(this, arg);
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/Query.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/Query.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/Query.java
index 66a55dc..8dc7b87 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/Query.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/Query.java
@@ -26,12 +26,14 @@ import 
org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.IReturningStatement;
 import org.apache.asterix.lang.common.base.Statement;
+import org.apache.asterix.lang.common.struct.VarIdentifier;
 import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
 
 public class Query implements IReturningStatement {
     private final boolean explain;
     private boolean topLevel = true;
     private Expression body;
+    private List<VarIdentifier> externalVars;
     private int varCounter;
 
     public Query(boolean explain) {
@@ -39,10 +41,16 @@ public class Query implements IReturningStatement {
     }
 
     public Query(boolean explain, boolean topLevel, Expression body, int 
varCounter) {
+        this(explain, topLevel, body, varCounter, null);
+    }
+
+    public Query(boolean explain, boolean topLevel, Expression body, int 
varCounter,
+            List<VarIdentifier> externalVars) {
         this.explain = explain;
         this.topLevel = topLevel;
         this.body = body;
         this.varCounter = varCounter;
+        this.externalVars = externalVars;
     }
 
     @Override
@@ -79,6 +87,16 @@ public class Query implements IReturningStatement {
         return topLevel;
     }
 
+    @Override
+    public List<VarIdentifier> getExternalVars() {
+        return externalVars;
+    }
+
+    @Override
+    public void setExternalVars(List<VarIdentifier> externalVars) {
+        this.externalVars = externalVars;
+    }
+
     public boolean isExplain() {
         return explain;
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/VarIdentifier.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/VarIdentifier.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/VarIdentifier.java
index 091c82d..587dd1c 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/VarIdentifier.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/VarIdentifier.java
@@ -22,14 +22,12 @@ import java.util.Objects;
 
 public final class VarIdentifier extends Identifier {
     private int id = 0;
-    private boolean namedValueAccess = false;
 
     public VarIdentifier() {
-        super();
     }
 
     public VarIdentifier(VarIdentifier v) {
-        this(v.getValue(), v.getId(), v.namedValueAccess());
+        this(v.getValue(), v.getId());
     }
 
     public VarIdentifier(String value) {
@@ -37,14 +35,8 @@ public final class VarIdentifier extends Identifier {
     }
 
     public VarIdentifier(String value, int id) {
-        this(value, id, false);
-    }
-
-    private VarIdentifier(String value, int id, boolean namedValueAccess) {
-        super();
         this.value = value;
         this.id = id;
-        this.namedValueAccess = namedValueAccess;
     }
 
     public void setId(int id) {
@@ -57,17 +49,7 @@ public final class VarIdentifier extends Identifier {
 
     @Override
     public VarIdentifier clone() {
-        VarIdentifier vi = new VarIdentifier(this.value);
-        vi.setId(this.id);
-        return vi;
-    }
-
-    public void setNamedValueAccess(boolean namedValueAccess) {
-        this.namedValueAccess = namedValueAccess;
-    }
-
-    public boolean namedValueAccess() {
-        return namedValueAccess;
+        return new VarIdentifier(value, id);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
index 858a8c2..61617ec 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
@@ -274,7 +274,7 @@ public abstract class AbstractInlineUdfsVisitor extends 
AbstractQueryExpressionV
         } else {
             // Rewrite the function body itself (without setting unbounded 
variables to dataset access).
             // TODO(buyingyi): throw an exception for recursive function 
definition or limit the stack depth.
-            implem.setFuncBody(rewriteFunctionBody(implem.getFuncBody()));
+            implem.setFuncBody(rewriteFunctionBody(implem.getFuncBody(), 
implem.getParamList()));
             // it's one of the functions we want to inline
             List<LetClause> clauses = new ArrayList<>();
             Iterator<VarIdentifier> paramIter = 
implem.getParamList().iterator();
@@ -321,10 +321,13 @@ public abstract class AbstractInlineUdfsVisitor extends 
AbstractQueryExpressionV
         return new Pair<>(changed, newList);
     }
 
-    protected Expression rewriteFunctionBody(Expression expr) throws 
CompilationException {
+    protected Expression rewriteFunctionBody(Expression expr, 
List<VarIdentifier> paramList)
+            throws CompilationException {
         Query wrappedQuery = new Query(false);
         wrappedQuery.setBody(expr);
         wrappedQuery.setTopLevel(false);
+        wrappedQuery.setExternalVars(paramList);
+
         IQueryRewriter queryRewriter = rewriterFactory.createQueryRewriter();
         queryRewriter.rewrite(declaredFunctions, wrappedQuery, 
metadataProvider, context);
         return wrappedQuery.getBody();

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-sqlpp/pom.xml
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/pom.xml 
b/asterixdb/asterix-lang-sqlpp/pom.xml
index 6b19fc7..46c0c4a 100644
--- a/asterixdb/asterix-lang-sqlpp/pom.xml
+++ b/asterixdb/asterix-lang-sqlpp/pom.xml
@@ -162,6 +162,10 @@
       <artifactId>algebricks-core</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-lang3</artifactId>
+    </dependency>
+    <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
       <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
index fbf64f7..a8b3dc6 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppFunctionBodyRewriter.java
@@ -44,25 +44,24 @@ class SqlppFunctionBodyRewriter extends SqlppQueryRewriter {
         // Substitutes group-by key expressions.
         substituteGroupbyKeyExpression();
 
-        // Rewrites SQL-92 global aggregations.
-        rewriteGlobalAggregations();
-
-        // Group-by core/sugar rewrites.
+        // Group-by core rewrites
         rewriteGroupBys();
 
         // Rewrites set operations.
         rewriteSetOperations();
 
+        // Generate ids for variables (considering scopes) and replace global 
variable access with the dataset function.
+        variableCheckAndRewrite();
+
+        // Rewrites SQL-92 global aggregations.
+        rewriteGroupByAggregationSugar();
+
         // Rewrites like/not-like expressions.
         rewriteOperatorExpression();
 
         // Rewrites several variable-arg functions into their corresponding 
internal list-input functions.
         rewriteListInputFunctions();
 
-        // Generates ids for variables (considering scopes) but DOES NOT 
replace unbounded variable access with the dataset function.
-        // An unbounded variable within a function could be a bounded variable 
in the top-level query.
-        variableCheckAndRewrite(false);
-
         // Inlines functions recursively.
         inlineDeclaredUdfs();
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index a2de694..3e9a873 100644
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -56,7 +56,7 @@ import 
org.apache.asterix.lang.sqlpp.rewrites.visitor.OperatorExpressionVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SetOperationVisitor;
 import 
org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppBuiltinFunctionRewriteVisitor;
 import 
org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppDistinctAggregationSugarVisitor;
-import 
org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGlobalAggregationSugarVisitor;
+import 
org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGroupByAggregationSugarVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGroupByVisitor;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppInlineUdfsVisitor;
 import 
org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppListInputFunctionRewriteVisitor;
@@ -90,8 +90,6 @@ class SqlppQueryRewriter implements IQueryRewriter {
         if (topStatement == null) {
             return;
         }
-        // Marks the current variable counter.
-        context.markCounter();
 
         // Sets up parameters.
         setup(declaredFunctions, topStatement, metadataProvider, context);
@@ -105,21 +103,21 @@ class SqlppQueryRewriter implements IQueryRewriter {
         // Substitutes group-by key expressions.
         substituteGroupbyKeyExpression();
 
-        // Rewrites SQL-92 global aggregations.
-        rewriteGlobalAggregations();
-
-        // Group-by core/sugar rewrites.
+        // Group-by core rewrites
         rewriteGroupBys();
 
         // Rewrites set operations.
         rewriteSetOperations();
 
+        // Generate ids for variables (considering scopes) and replace global 
variable access with the dataset function.
+        variableCheckAndRewrite();
+
+        // Rewrites SQL-92 aggregate functions
+        rewriteGroupByAggregationSugar();
+
         // Rewrites like/not-like expressions.
         rewriteOperatorExpression();
 
-        // Generate ids for variables (considering scopes) and replace global 
variable access with the dataset function.
-        variableCheckAndRewrite(true);
-
         // Inlines WITH expressions after variableCheckAndRewrite(...) so that 
the variable scoping for WITH
         // expression is correct.
         inlineWithExpressions();
@@ -138,21 +136,13 @@ class SqlppQueryRewriter implements IQueryRewriter {
         // Rewrites distinct aggregates into regular aggregates
         rewriteDistinctAggregations();
 
-        // Resets the variable counter to the previous marked value.
-        // Therefore, the variable ids in the final query plans will not be 
perturbed
-        // by the additon or removal of intermediate AST rewrites.
-        context.resetCounter();
-
-        // Replace global variable access with the dataset function for 
inlined expressions.
-        variableCheckAndRewrite(true);
-
         // Sets the var counter of the query.
         topStatement.setVarCounter(context.getVarCounter());
     }
 
-    protected void rewriteGlobalAggregations() throws CompilationException {
-        SqlppGlobalAggregationSugarVisitor globalAggregationVisitor = new 
SqlppGlobalAggregationSugarVisitor();
-        topExpr.accept(globalAggregationVisitor, null);
+    protected void rewriteGroupByAggregationSugar() throws 
CompilationException {
+        SqlppGroupByAggregationSugarVisitor visitor = new 
SqlppGroupByAggregationSugarVisitor(context);
+        topExpr.accept(visitor, null);
     }
 
     protected void rewriteDistinctAggregations() throws CompilationException {
@@ -212,9 +202,9 @@ class SqlppQueryRewriter implements IQueryRewriter {
         topExpr.accept(inlineColumnAliasVisitor, null);
     }
 
-    protected void variableCheckAndRewrite(boolean overwrite) throws 
CompilationException {
+    protected void variableCheckAndRewrite() throws CompilationException {
         VariableCheckAndRewriteVisitor variableCheckAndRewriteVisitor =
-                new VariableCheckAndRewriteVisitor(context, overwrite, 
metadataProvider);
+                new VariableCheckAndRewriteVisitor(context, metadataProvider, 
topExpr.getExternalVars());
         topExpr.accept(variableCheckAndRewriteVisitor, null);
     }
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGlobalAggregationSugarVisitor.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGlobalAggregationSugarVisitor.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGlobalAggregationSugarVisitor.java
deleted file mode 100644
index 16ae05c..0000000
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGlobalAggregationSugarVisitor.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.asterix.lang.sqlpp.rewrites.visitor;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-import org.apache.asterix.common.exceptions.CompilationException;
-import org.apache.asterix.lang.common.base.Expression;
-import org.apache.asterix.lang.common.base.ILangExpression;
-import org.apache.asterix.lang.common.clause.GroupbyClause;
-import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
-import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
-import org.apache.asterix.lang.sqlpp.clause.SelectClause;
-import org.apache.asterix.lang.sqlpp.visitor.CheckSql92AggregateVisitor;
-import 
org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
-
-public class SqlppGlobalAggregationSugarVisitor extends 
AbstractSqlppSimpleExpressionVisitor {
-
-    @Override
-    public Expression visit(SelectBlock selectBlock, ILangExpression arg) 
throws CompilationException {
-        SelectClause selectClause = selectBlock.getSelectClause();
-        if (!selectBlock.hasGroupbyClause() && selectBlock.hasFromClause()) {
-            boolean addImplicitGby;
-            if (selectClause.selectRegular()) {
-                addImplicitGby = 
isSql92Aggregate(selectClause.getSelectRegular(), selectBlock);
-            } else {
-                addImplicitGby = 
isSql92Aggregate(selectClause.getSelectElement(), selectBlock);
-            }
-            if (addImplicitGby) {
-                // Adds an implicit group-by clause for SQL-92 global 
aggregate.
-                List<GbyVariableExpressionPair> gbyPairList = new 
ArrayList<>();
-                List<GbyVariableExpressionPair> decorPairList = new 
ArrayList<>();
-                GroupbyClause gbyClause = new GroupbyClause(gbyPairList, 
decorPairList, new HashMap<>(), null, null,
-                        false, true);
-                selectBlock.setGroupbyClause(gbyClause);
-            }
-        }
-        return super.visit(selectBlock, arg);
-    }
-
-    private boolean isSql92Aggregate(ILangExpression expr, SelectBlock 
selectBlock) throws CompilationException {
-        CheckSql92AggregateVisitor visitor = new CheckSql92AggregateVisitor();
-        return expr.accept(visitor, selectBlock);
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
new file mode 100644
index 0000000..6f420b4
--- /dev/null
+++ 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
@@ -0,0 +1,303 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.asterix.lang.sqlpp.rewrites.visitor;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.ILangExpression;
+import org.apache.asterix.lang.common.clause.GroupbyClause;
+import org.apache.asterix.lang.common.clause.LetClause;
+import org.apache.asterix.lang.common.clause.LimitClause;
+import org.apache.asterix.lang.common.clause.OrderbyClause;
+import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.FieldAccessor;
+import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
+import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
+import org.apache.asterix.lang.common.struct.Identifier;
+import org.apache.asterix.lang.common.struct.VarIdentifier;
+import org.apache.asterix.lang.sqlpp.clause.FromClause;
+import org.apache.asterix.lang.sqlpp.clause.FromTerm;
+import org.apache.asterix.lang.sqlpp.clause.HavingClause;
+import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
+import org.apache.asterix.lang.sqlpp.clause.SelectClause;
+import org.apache.asterix.lang.sqlpp.clause.SelectElement;
+import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
+import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
+import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
+import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
+import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
+import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
+import 
org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppExpressionScopingVisitor;
+import 
org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * An AST pre-processor to rewrite group-by sugar queries, which does the 
following transformations:
+ * 1. Rewrite the argument expression of an aggregation function into a 
subquery
+ * 2. Turn a SQL-92 aggregate function into a SQL++ core aggregate function 
when performing 1.
+ * <p>
+ * <p>
+ * For example, this visitor turns the following query:
+ * <pre>
+ * FROM Employee e
+ * JOIN Incentive i ON e.job_category = i.job_category
+ * JOIN SuperStars s ON e.id = s.id
+ * GROUP BY e.department_id AS deptId
+ * GROUP AS eis(e AS e, i AS i, s AS s)
+ * SELECT deptId as deptId, SUM(e.salary + i.bonus) AS star_cost;
+ * </pre>
+ * into the following core-version query:
+ * <pre>
+ * FROM Employee e
+ * JOIN Incentive i ON e.job_category = i.job_category
+ * JOIN SuperStars s ON e.id = s.id
+ * GROUP BY e.department_id AS deptId
+ * GROUP AS eis(e AS e, i AS i, s AS s)
+ * SELECT ELEMENT {
+ *          'deptId': deptId,
+ *          'star_cost': array_sum( (FROM eis AS p SELECT ELEMENT p.e.salary + 
p.i.bonus) )
+ * };
+ * </pre>
+ * where <code>SUM(e.salary + i.bonus)</code>
+ * is turned into <code>array_sum( (FROM eis AS p SELECT ELEMENT p.e.salary + 
p.i.bonus) )</code>
+ */
+public class SqlppGroupByAggregationSugarVisitor extends 
AbstractSqlppExpressionScopingVisitor {
+
+    public SqlppGroupByAggregationSugarVisitor(LangRewritingContext context) {
+        super(context);
+    }
+
+    @Override
+    public Expression visit(SelectBlock selectBlock, ILangExpression arg) 
throws CompilationException {
+        // Traverses the select block in the order of "from", "let"s, "where",
+        // "group by", "let"s, "having" and "select".
+        FromClause fromClause = selectBlock.getFromClause();
+        if (selectBlock.hasFromClause()) {
+            fromClause.accept(this, arg);
+        }
+        if (selectBlock.hasLetClauses()) {
+            List<LetClause> letList = selectBlock.getLetList();
+            for (LetClause letClause : letList) {
+                letClause.accept(this, arg);
+            }
+        }
+        if (selectBlock.hasWhereClause()) {
+            selectBlock.getWhereClause().accept(this, arg);
+        }
+        if (selectBlock.hasGroupbyClause()) {
+            Set<VariableExpr> visibleVarsPreGroupByScope = 
scopeChecker.getCurrentScope().getLiveVariables();
+
+            GroupbyClause groupbyClause = selectBlock.getGroupbyClause();
+            groupbyClause.accept(this, arg);
+            Collection<VariableExpr> visibleVarsInCurrentScope = 
SqlppVariableUtil.getBindingVariables(groupbyClause);
+
+            VariableExpr groupVar = groupbyClause.getGroupVar();
+            Map<Expression, Identifier> groupFieldVars = 
getGroupFieldVariables(groupbyClause);
+
+            Collection<VariableExpr> freeVariablesInGbyLets = new HashSet<>();
+            if (selectBlock.hasLetClausesAfterGroupby()) {
+                List<LetClause> letListAfterGby = 
selectBlock.getLetListAfterGroupby();
+                for (LetClause letClauseAfterGby : letListAfterGby) {
+                    letClauseAfterGby.accept(this, arg);
+                    // Rewrites each let clause after the group-by.
+                    rewriteExpressionUsingGroupVariable(groupVar, 
groupFieldVars, letClauseAfterGby,
+                            visibleVarsPreGroupByScope);
+                    Collection<VariableExpr> freeVariablesInLet =
+                            
SqlppVariableUtil.getFreeVariables(letClauseAfterGby.getBindingExpr());
+                    freeVariablesInLet.removeAll(visibleVarsInCurrentScope);
+                    freeVariablesInGbyLets.addAll(freeVariablesInLet);
+                    
visibleVarsInCurrentScope.add(letClauseAfterGby.getVarExpr());
+                }
+            }
+
+            Collection<VariableExpr> freeVariables = new HashSet<>();
+            if (selectBlock.hasHavingClause()) {
+                // Rewrites the having clause.
+                HavingClause havingClause = selectBlock.getHavingClause();
+                havingClause.accept(this, arg);
+                rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, 
havingClause, visibleVarsPreGroupByScope);
+                
freeVariables.addAll(SqlppVariableUtil.getFreeVariables(havingClause));
+            }
+
+            SelectExpression parentSelectExpression = (SelectExpression) arg;
+            // We cannot rewrite ORDER BY and LIMIT if it's a SET operation 
query.
+            if 
(!parentSelectExpression.getSelectSetOperation().hasRightInputs()) {
+                if (parentSelectExpression.hasOrderby()) {
+                    // Rewrites the ORDER BY clause.
+                    OrderbyClause orderbyClause = 
parentSelectExpression.getOrderbyClause();
+                    orderbyClause.accept(this, arg);
+                    rewriteExpressionUsingGroupVariable(groupVar, 
groupFieldVars, orderbyClause,
+                            visibleVarsPreGroupByScope);
+                    
freeVariables.addAll(SqlppVariableUtil.getFreeVariables(orderbyClause));
+                }
+                if (parentSelectExpression.hasLimit()) {
+                    // Rewrites the LIMIT clause.
+                    LimitClause limitClause = 
parentSelectExpression.getLimitClause();
+                    limitClause.accept(this, arg);
+                    rewriteExpressionUsingGroupVariable(groupVar, 
groupFieldVars, limitClause,
+                            visibleVarsPreGroupByScope);
+                    
freeVariables.addAll(SqlppVariableUtil.getFreeVariables(limitClause));
+                }
+            }
+
+            // Visits the select clause.
+            SelectClause selectClause = selectBlock.getSelectClause();
+            selectClause.accept(this, arg);
+            // Rewrites the select clause.
+            rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, 
selectClause, visibleVarsPreGroupByScope);
+            
freeVariables.addAll(SqlppVariableUtil.getFreeVariables(selectClause));
+            freeVariables.removeAll(visibleVarsInCurrentScope);
+
+            // Gets the final free variables.
+            freeVariables.addAll(freeVariablesInGbyLets);
+
+            // Gets outer scope variables.
+            Collection<VariableExpr> decorVars = 
scopeChecker.getCurrentScope().getLiveVariables();
+            decorVars.removeAll(visibleVarsInCurrentScope);
+
+            // Only retains used free variables.
+            if (!decorVars.containsAll(freeVariables)) {
+                throw new IllegalStateException(decorVars + ":" + 
freeVariables);
+            }
+            decorVars.retainAll(freeVariables);
+
+            if (!decorVars.isEmpty()) {
+                // Adds necessary decoration variables for the GROUP BY.
+                // NOTE: we need to include outer binding variables so as they 
can be evaluated before
+                // the GROUP BY instead of being inlined as part of nested 
pipepline. The current optimzier
+                // is not able to optimize the latter case. The following 
query is such an example:
+                // 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-11
+                List<GbyVariableExpressionPair> decorList = new ArrayList<>();
+                for (VariableExpr var : decorVars) {
+                    decorList.add(new GbyVariableExpressionPair((VariableExpr) 
SqlppRewriteUtil.deepCopy(var),
+                            (Expression) SqlppRewriteUtil.deepCopy(var)));
+                }
+                groupbyClause.getDecorPairList().addAll(decorList);
+            }
+        } else {
+            selectBlock.getSelectClause().accept(this, arg);
+        }
+        return null;
+    }
+
+    private Map<Expression, Identifier> getGroupFieldVariables(GroupbyClause 
groupbyClause) {
+        Map<Expression, Identifier> fieldVars = new HashMap<>();
+        for (Pair<Expression, Identifier> groupField : 
groupbyClause.getGroupFieldList()) {
+            fieldVars.put(groupField.first, groupField.second);
+        }
+        return fieldVars;
+    }
+
+    // Applying sugar rewriting for group-by.
+    private void rewriteExpressionUsingGroupVariable(VariableExpr groupVar, 
Map<Expression, Identifier> fieldVars,
+            ILangExpression expr, Set<VariableExpr> outerScopeVariables) 
throws CompilationException {
+        Sql92AggregateFunctionVisitor visitor =
+                new Sql92AggregateFunctionVisitor(groupVar, fieldVars, 
outerScopeVariables);
+        expr.accept(visitor, null);
+    }
+
+    private final class Sql92AggregateFunctionVisitor extends 
AbstractSqlppSimpleExpressionVisitor {
+
+        private final Expression groupVar;
+
+        private final Map<Expression, Identifier> fieldVars;
+
+        private final Collection<VariableExpr> outerVars;
+
+        private Sql92AggregateFunctionVisitor(Expression groupVar, 
Map<Expression, Identifier> fieldVars,
+                Collection<VariableExpr> outerVars) {
+            this.groupVar = groupVar;
+            this.fieldVars = fieldVars;
+            this.outerVars = outerVars;
+        }
+
+        @Override
+        public Expression visit(CallExpr callExpr, ILangExpression arg) throws 
CompilationException {
+            List<Expression> newExprList = new ArrayList<>();
+            FunctionSignature signature = callExpr.getFunctionSignature();
+            boolean aggregate = 
FunctionMapUtil.isSql92AggregateFunction(signature);
+            boolean rewritten = false;
+            for (Expression expr : callExpr.getExprList()) {
+                Expression newExpr = aggregate ? wrapAggregationArgument(expr) 
: expr;
+                rewritten |= newExpr != expr;
+                newExprList.add(newExpr.accept(this, arg));
+            }
+            if (rewritten) {
+                // Rewrites the SQL-92 function name to core functions,
+                // e.g., SUM --> array_sum
+                
callExpr.setFunctionSignature(FunctionMapUtil.sql92ToCoreAggregateFunction(signature));
+            }
+            callExpr.setExprList(newExprList);
+            return callExpr;
+        }
+
+        private Expression wrapAggregationArgument(Expression argExpr) throws 
CompilationException {
+            Expression expr = argExpr;
+            Set<VariableExpr> freeVars = 
SqlppRewriteUtil.getFreeVariable(expr);
+
+            VariableExpr fromBindingVar = new 
VariableExpr(context.newVariable());
+            FromTerm fromTerm = new FromTerm(groupVar, fromBindingVar, null, 
null);
+            FromClause fromClause = new 
FromClause(Collections.singletonList(fromTerm));
+
+            // Maps field variable expressions to field accesses.
+            Map<Expression, Expression> varExprMap = new HashMap<>();
+            for (VariableExpr usedVar : freeVars) {
+                // Reference to a field in the group variable.
+                if (fieldVars.containsKey(usedVar)) {
+                    // Rewrites to a reference to a field in the group 
variable.
+                    varExprMap.put(usedVar,
+                            new FieldAccessor(fromBindingVar, new 
VarIdentifier(fieldVars.get(usedVar).getValue())));
+                } else if (outerVars.contains(usedVar)) {
+                    // Do nothing
+                } else if (fieldVars.size() == 1) {
+                    // Rewrites to a reference to a single field in the group 
variable.
+                    varExprMap.put(usedVar,
+                            new FieldAccessor(new 
FieldAccessor(fromBindingVar, fieldVars.values().iterator().next()),
+                                    
SqlppVariableUtil.toUserDefinedVariableName(usedVar.getVar())));
+                } else {
+                    throw new CompilationException(
+                            "Cannot resolve alias reference for undefined 
identifier " + usedVar.getVar().getValue()
+                                    + " in " + fieldVars);
+                }
+            }
+
+            // Select clause.
+            SelectElement selectElement =
+                    new 
SelectElement(SqlppRewriteUtil.substituteExpression(expr, varExprMap, context));
+            SelectClause selectClause = new SelectClause(selectElement, null, 
false);
+
+            // Construct the select expression.
+            SelectBlock selectBlock = new SelectBlock(selectClause, 
fromClause, null, null, null, null, null);
+            SelectSetOperation selectSetOperation =
+                    new SelectSetOperation(new SetOperationInput(selectBlock, 
null), null);
+            return new SelectExpression(null, selectSetOperation, null, null, 
true);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/ef1719e3/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupBySugarVisitor.java
----------------------------------------------------------------------
diff --git 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupBySugarVisitor.java
 
b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupBySugarVisitor.java
deleted file mode 100644
index b7604ab..0000000
--- 
a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupBySugarVisitor.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.asterix.lang.sqlpp.rewrites.visitor;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.asterix.common.exceptions.CompilationException;
-import org.apache.asterix.common.functions.FunctionSignature;
-import org.apache.asterix.lang.common.base.Expression;
-import org.apache.asterix.lang.common.base.ILangExpression;
-import org.apache.asterix.lang.common.expression.CallExpr;
-import org.apache.asterix.lang.common.expression.FieldAccessor;
-import org.apache.asterix.lang.common.expression.VariableExpr;
-import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
-import org.apache.asterix.lang.sqlpp.clause.FromClause;
-import org.apache.asterix.lang.sqlpp.clause.FromTerm;
-import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
-import org.apache.asterix.lang.sqlpp.clause.SelectClause;
-import org.apache.asterix.lang.sqlpp.clause.SelectElement;
-import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
-import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
-import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
-import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
-import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
-import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
-import 
org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppExpressionScopingVisitor;
-
-/**
- * An AST pre-processor to rewrite group-by sugar queries, which does the 
following transformations:
- * 1. Rewrite the argument expression of an aggregation function into a 
subquery if the argument
- * expression is not a subquery;
- * 2. Turn a SQL-92 aggregate function into a SQL++ core aggregate function 
when performing 1.
- */
-
-// For example, this visitor turns the following query
-//
-// FROM Employee e
-// JOIN Incentive i ON e.job_category = i.job_category
-// JOIN SuperStars s ON e.id = s.id
-// GROUP BY e.department_id AS deptId
-// GROUP AS eis(e AS e, i AS i, s AS s)
-// SELECT deptId as deptId, SUM(e.salary + i.bonus) AS star_cost;
-//
-// into the following core-version query:
-//
-// FROM Employee e
-// JOIN Incentive i ON e.job_category = i.job_category
-// JOIN SuperStars s ON e.id = s.id
-// GROUP BY e.department_id AS deptId
-// GROUP AS eis(e AS e, i AS i, s AS s)
-// SELECT ELEMENT {
-//          'deptId': deptId,
-//          'star_cost': array_sum( (FROM eis AS p SELECT ELEMENT p.e.salary + 
p.i.bonus) )
-// };
-//
-// where SUM(e.salary + i.bonus) is turned into array_sum( (FROM eis AS p 
SELECT ELEMENT p.e.salary + p.i.bonus) ).
-
-public class SqlppGroupBySugarVisitor extends 
AbstractSqlppExpressionScopingVisitor {
-
-    private final Expression groupVar;
-    private final Collection<VariableExpr> fieldVars;
-
-    public SqlppGroupBySugarVisitor(LangRewritingContext context, Expression 
groupVar,
-            Collection<VariableExpr> fieldVars) {
-        super(context);
-        this.groupVar = groupVar;
-        this.fieldVars = fieldVars;
-    }
-
-    @Override
-    public Expression visit(CallExpr callExpr, ILangExpression arg) throws 
CompilationException {
-        List<Expression> newExprList = new ArrayList<>();
-        FunctionSignature signature = callExpr.getFunctionSignature();
-        boolean aggregate = 
FunctionMapUtil.isSql92AggregateFunction(signature);
-        boolean rewritten = false;
-        for (Expression expr : callExpr.getExprList()) {
-            Expression newExpr = aggregate ? wrapAggregationArgument(expr) : 
expr;
-            rewritten |= newExpr != expr;
-            newExprList.add(newExpr.accept(this, arg));
-        }
-        if (rewritten) {
-            // Rewrites the SQL-92 function name to core functions,
-            // e.g., SUM --> array_sum
-            
callExpr.setFunctionSignature(FunctionMapUtil.sql92ToCoreAggregateFunction(signature));
-        }
-        callExpr.setExprList(newExprList);
-        return callExpr;
-    }
-
-    private Expression wrapAggregationArgument(Expression argExpr) throws 
CompilationException {
-        Expression expr = argExpr;
-        Set<VariableExpr> freeVars = SqlppRewriteUtil.getFreeVariable(expr);
-
-        VariableExpr fromBindingVar = new VariableExpr(context.newVariable());
-        FromTerm fromTerm = new FromTerm(groupVar, fromBindingVar, null, null);
-        FromClause fromClause = new 
FromClause(Collections.singletonList(fromTerm));
-
-        // Maps field variable expressions to field accesses.
-        Map<Expression, Expression> varExprMap = new HashMap<>();
-        for (VariableExpr usedVar : freeVars) {
-            // Reference to a field in the group variable.
-            if (fieldVars.contains(usedVar)) {
-                // Rewrites to a reference to a field in the group variable.
-                varExprMap.put(usedVar, new FieldAccessor(fromBindingVar,
-                        
SqlppVariableUtil.toUserDefinedVariableName(usedVar.getVar())));
-            }
-        }
-
-        // Select clause.
-        SelectElement selectElement =
-                new SelectElement(SqlppRewriteUtil.substituteExpression(expr, 
varExprMap, context));
-        SelectClause selectClause = new SelectClause(selectElement, null, 
false);
-
-        // Construct the select expression.
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, 
null, null, null, null, null);
-        SelectSetOperation selectSetOperation = new SelectSetOperation(new 
SetOperationInput(selectBlock, null), null);
-        return new SelectExpression(null, selectSetOperation, null, null, 
true);
-    }
-}

Reply via email to