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); - } -}
