Support SQL-compliant group-by syntax.
1. Add AST-level deep equality and expression subsutitions;
2. Fix DeepCopyVisitor and InlineColumnAliasVisitor for edge cases;
3. Add deep equality tests;
4. Add group-by tests for the SQL-compliant syntax.
Change-Id: Ia1cbe1fab216b5f47577d75fd870a537cfe1e84f
Reviewed-on: https://asterix-gerrit.ics.uci.edu/990
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
index fa7b272..0989545 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
@@ -45,6 +45,7 @@
import org.apache.asterix.lang.sqlpp.parser.SqlppParserFactory;
import org.apache.asterix.lang.sqlpp.rewrites.SqlppRewriterFactory;
import org.apache.asterix.lang.sqlpp.util.SqlppAstPrintUtil;
+import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
import org.apache.asterix.metadata.declared.AqlMetadataProvider;
import org.apache.asterix.metadata.entities.Dataset;
import org.apache.asterix.test.aql.TestExecutor;
@@ -52,6 +53,7 @@
import org.apache.asterix.testframework.context.TestFileContext;
import org.apache.asterix.testframework.xml.TestCase.CompilationUnit;
import org.apache.asterix.testframework.xml.TestGroup;
+import org.junit.Assert;
import junit.extensions.PA;
@@ -80,8 +82,8 @@
// Runs the test query.
File expectedResultFile = expectedResultFileCtxs.get(queryCount).getFile();
- File actualResultFile = testCaseCtx.getActualResultFile(cUnit, expectedResultFile,
- new File(actualPath));
+ File actualResultFile =
+ testCaseCtx.getActualResultFile(cUnit, expectedResultFile, new File(actualPath));
testSQLPPParser(testFile, actualResultFile, expectedResultFile);
LOGGER.info(
@@ -132,6 +134,11 @@
IQueryRewriter rewriter = sqlppRewriterFactory.createQueryRewriter();
rewrite(rewriter, functions, query, aqlMetadataProvider,
new LangRewritingContext(query.getVarCounter()));
+
+ // Tests deep copy and deep equality.
+ Query copiedQuery = (Query) SqlppRewriteUtil.deepCopy(query);
+ Assert.assertEquals(query.hashCode(), copiedQuery.hashCode());
+ Assert.assertEquals(query, copiedQuery);
}
SqlppAstPrintUtil.print(st, writer);
}
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.1.ddl.sqlpp
new file mode 100644
index 0000000..90482a7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.1.ddl.sqlpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+drop database test if exists;
+create database test;
+
+use test;
+
+
+create type test.AddressType as
+ closed {
+ street : string,
+ city : string,
+ zip : string,
+ latlong : point
+}
+
+create type test.EventType as
+ closed {
+ event_id : int64,
+ name : string,
+ location : AddressType?,
+ organizers : {{{
+ name : string
+ }
+}},
+ sponsoring_sigs : [{
+ sig_id : int64,
+ chapter_name : string
+ }
+],
+ interest_keywords : {{string}},
+ price : double?,
+ start_time : datetime,
+ end_time : datetime
+}
+
+create external table Event(EventType) using localfs((`path`=`asterix_nc1://data/events/tiny/event.adm`),(`format`=`adm`));
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.2.update.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.2.update.sqlpp
index 64ec0af..bd244d0 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.2.update.sqlpp
@@ -16,22 +16,4 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
-
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
-
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.3.query.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.3.query.sqlpp
index 64ec0af..1c7e44a 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/dapd/q2-6/q2-6.3.query.sqlpp
@@ -16,22 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE test;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+
+SELECT sponsor.sig_id, COUNT(1) total_count,
+ (
+ SELECT e.sponsor.chapter_name, COUNT(e) AS escount
+ FROM es AS e
+ GROUP BY e.sponsor.chapter_name
+ ) chapter_breakdown
+FROM Event,
+ Event.sponsoring_sigs AS sponsor
+GROUP BY sponsor.sig_id GROUP AS es
+ORDER BY total_count DESC
+LIMIT 5
+;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.1.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.1.ddl.sqlpp
index 64ec0af..b4ebc49 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.1.ddl.sqlpp
@@ -16,22 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+DROP DATABASE gby IF EXISTS;
+CREATE DATABASE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
+CREATE TYPE EmployeeType AS {
+ id : string
}
+
+CREATE TYPE IncentiveType AS {
+ job_category: string
+}
+
+CREATE TYPE SuperStarType AS {
+ id : string
+}
+
+CREATE TABLE Employee(EmployeeType) PRIMARY KEY id;
+CREATE TABLE Incentive(IncentiveType) PRIMARY KEY job_category;
+CREATE TABLE SuperStars(SuperStarType) PRIMARY KEY id;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.2.update.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.2.update.sqlpp
index 64ec0af..e6545e0 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.2.update.sqlpp
@@ -16,22 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+INSERT INTO Employee (
+ {
+ 'id': '123',
+ 'job_category': 'Cook',
+ 'salary': 2000,
+ 'department_id': 'K55'
+ }
+);
+
+INSERT INTO Incentive (
+ { 'job_category': 'Cook',
+ 'bonus': 1000
+ }
+)
+
+INSERT INTO SuperStars (
+ {
+ 'id': '123'
+ }
+)
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.3.query.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.3.query.sqlpp
index 64ec0af..5c6cc38 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-2/gby-expr-2.3.query.sqlpp
@@ -16,22 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+FROM Employee e
+ JOIN Incentive i ON e.job_category = i.job_category
+ JOIN SuperStars s ON e.id = s.id
+GROUP BY substr(e.department_id, 1)
+SELECT substr(e.department_id, 1), SUM(e.salary + i.bonus);
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.1.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.1.ddl.sqlpp
index 64ec0af..b4ebc49 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.1.ddl.sqlpp
@@ -16,22 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+DROP DATABASE gby IF EXISTS;
+CREATE DATABASE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
+CREATE TYPE EmployeeType AS {
+ id : string
}
+
+CREATE TYPE IncentiveType AS {
+ job_category: string
+}
+
+CREATE TYPE SuperStarType AS {
+ id : string
+}
+
+CREATE TABLE Employee(EmployeeType) PRIMARY KEY id;
+CREATE TABLE Incentive(IncentiveType) PRIMARY KEY job_category;
+CREATE TABLE SuperStars(SuperStarType) PRIMARY KEY id;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.2.update.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.2.update.sqlpp
index 64ec0af..e6545e0 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.2.update.sqlpp
@@ -16,22 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+INSERT INTO Employee (
+ {
+ 'id': '123',
+ 'job_category': 'Cook',
+ 'salary': 2000,
+ 'department_id': 'K55'
+ }
+);
+
+INSERT INTO Incentive (
+ { 'job_category': 'Cook',
+ 'bonus': 1000
+ }
+)
+
+INSERT INTO SuperStars (
+ {
+ 'id': '123'
+ }
+)
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.3.query.sqlpp
similarity index 64%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.3.query.sqlpp
index 64ec0af..c2fe80b 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr-3/gby-expr-3.3.query.sqlpp
@@ -16,22 +16,18 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
+
+USE gby;
+
+/*
+ * This query tests that the expression substitution rewriter should
+ * try to visit (i.e., substitute) parent expressions first before visiting
+ * child expressions, e.g.: i.bonus + e.salary is a parent expression of i.bonus.
*/
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+FROM Employee e
+ JOIN Incentive i ON e.job_category = i.job_category
+ JOIN SuperStars s ON e.id = s.id
+GROUP BY i.bonus, i.bonus + e.salary
+SELECT i.bonus, i.bonus + e.salary, COUNT(1);
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
-
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.1.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.1.ddl.sqlpp
index 64ec0af..b4ebc49 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.1.ddl.sqlpp
@@ -16,22 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+DROP DATABASE gby IF EXISTS;
+CREATE DATABASE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
+CREATE TYPE EmployeeType AS {
+ id : string
}
+
+CREATE TYPE IncentiveType AS {
+ job_category: string
+}
+
+CREATE TYPE SuperStarType AS {
+ id : string
+}
+
+CREATE TABLE Employee(EmployeeType) PRIMARY KEY id;
+CREATE TABLE Incentive(IncentiveType) PRIMARY KEY job_category;
+CREATE TABLE SuperStars(SuperStarType) PRIMARY KEY id;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.2.update.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.2.update.sqlpp
index 64ec0af..e6545e0 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.2.update.sqlpp
@@ -16,22 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+INSERT INTO Employee (
+ {
+ 'id': '123',
+ 'job_category': 'Cook',
+ 'salary': 2000,
+ 'department_id': 'K55'
+ }
+);
+
+INSERT INTO Incentive (
+ { 'job_category': 'Cook',
+ 'bonus': 1000
+ }
+)
+
+INSERT INTO SuperStars (
+ {
+ 'id': '123'
+ }
+)
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.3.query.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.3.query.sqlpp
index 64ec0af..c2d046d 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/gby-expr/gby-expr.3.query.sqlpp
@@ -16,22 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+FROM Employee e
+ JOIN Incentive i ON e.job_category = i.job_category
+ JOIN SuperStars s ON e.id = s.id
+GROUP BY substr(e.department_id, 1)
+SELECT substr(e.department_id, 1) as deptId, SUM(e.salary + i.bonus) AS star_cost;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.1.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.1.ddl.sqlpp
index 64ec0af..bbccf8c 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.1.ddl.sqlpp
@@ -16,22 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+DROP DATABASE gby IF EXISTS;
+CREATE DATABASE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
+CREATE TYPE EmpType AS {
+ name : string
}
+
+CREATE TABLE Employee(EmpType) PRIMARY KEY name;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.2.update.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.2.update.sqlpp
index 64ec0af..99116f6 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.2.update.sqlpp
@@ -16,22 +16,17 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+INSERT INTO Employee (
+ [
+ { 'name': 'Bill',
+ 'deptno': 'K55',
+ 'salary': 2000 },
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+ { 'name': 'Fred',
+ 'deptno': 'K55',
+ 'salary': 3000 }
+ ]
+);
\ No newline at end of file
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.3.query.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.3.query.sqlpp
index 64ec0af..6187e72 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-01-2/sugar-01-2.3.query.sqlpp
@@ -16,22 +16,11 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+FROM Employee e
+GROUP BY e.deptno GROUP AS g
+SELECT e.deptno AS deptno, AVG(e.salary) AS avgpay,
+ (SELECT i.e.name AS name, i.e.salary AS salary FROM g AS i) AS workers;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.1.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.1.ddl.sqlpp
index 64ec0af..b4ebc49 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.1.ddl.sqlpp
@@ -16,22 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+DROP DATABASE gby IF EXISTS;
+CREATE DATABASE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
+CREATE TYPE EmployeeType AS {
+ id : string
}
+
+CREATE TYPE IncentiveType AS {
+ job_category: string
+}
+
+CREATE TYPE SuperStarType AS {
+ id : string
+}
+
+CREATE TABLE Employee(EmployeeType) PRIMARY KEY id;
+CREATE TABLE Incentive(IncentiveType) PRIMARY KEY job_category;
+CREATE TABLE SuperStars(SuperStarType) PRIMARY KEY id;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.2.update.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.2.update.sqlpp
index 64ec0af..e6545e0 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.2.update.sqlpp
@@ -16,22 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+INSERT INTO Employee (
+ {
+ 'id': '123',
+ 'job_category': 'Cook',
+ 'salary': 2000,
+ 'department_id': 'K55'
+ }
+);
+
+INSERT INTO Incentive (
+ { 'job_category': 'Cook',
+ 'bonus': 1000
+ }
+)
+
+INSERT INTO SuperStars (
+ {
+ 'id': '123'
+ }
+)
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.3.query.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.3.query.sqlpp
index 64ec0af..2b18b3c 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.3.query.sqlpp
@@ -16,22 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+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
+SELECT e.department_id as deptId, SUM(e.salary + i.bonus) AS star_cost;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.4.query.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.4.query.sqlpp
index 64ec0af..8e9eddb 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-02-2/sugar-02-2.4.query.sqlpp
@@ -16,22 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+/* This query tests the column alias rewriting. */
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+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
+HAVING deptId = 'K55'
+SELECT e.department_id AS deptId, SUM(e.salary + i.bonus) AS star_cost
+ORDER BY deptId;
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.1.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.1.ddl.sqlpp
index 64ec0af..7a281d2 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.1.ddl.sqlpp
@@ -16,22 +16,25 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+DROP DATABASE gby IF EXISTS;
+CREATE DATABASE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
+CREATE TYPE EmployeeType AS {
+ id : string
}
+
+CREATE TYPE IncentiveType AS {
+ job_category: string
+}
+
+CREATE TYPE SuperStarType AS {
+ id : string
+}
+
+CREATE TABLE Employee(EmployeeType) PRIMARY KEY id;
+CREATE TABLE Incentive(IncentiveType) PRIMARY KEY job_category;
+CREATE TABLE SuperStars(SuperStarType) PRIMARY KEY id;
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.2.update.sqlpp
similarity index 67%
rename from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
rename to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.2.update.sqlpp
index 64ec0af..19f0c1f 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.2.update.sqlpp
@@ -16,22 +16,27 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+INSERT INTO Employee (
+ {
+ 'id': '123',
+ 'job_category': 'Cook',
+ 'salary': 2000,
+ 'department_id': 'K55'
+ }
+);
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+INSERT INTO Incentive (
+ { 'job_category': 'Cook',
+ 'bonus': 1000
+ }
+)
+
+INSERT INTO SuperStars (
+ {
+ 'id': '123'
+ }
+)
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.3.query.sqlpp
similarity index 66%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.3.query.sqlpp
index 64ec0af..4979375 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-03-2/sugar-03-2.3.query.sqlpp
@@ -16,22 +16,17 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
-
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+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 GROUP AS eis
+SELECT e.department_id as deptId,
+ AVG(e.salary + i.bonus) AS avgpay,
+ ( FROM eis AS v
+ SELECT v.e.id AS id, v.e.salary AS salary, v.i.bonus AS bonus
+ ORDER BY v.i.bonus DESC LIMIT 3
+ ) AS topstar_details
+ ;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.1.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.1.ddl.sqlpp
index 64ec0af..7a281d2 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.1.ddl.sqlpp
@@ -16,22 +16,25 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+DROP DATABASE gby IF EXISTS;
+CREATE DATABASE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
+CREATE TYPE EmployeeType AS {
+ id : string
}
+
+CREATE TYPE IncentiveType AS {
+ job_category: string
+}
+
+CREATE TYPE SuperStarType AS {
+ id : string
+}
+
+CREATE TABLE Employee(EmployeeType) PRIMARY KEY id;
+CREATE TABLE Incentive(IncentiveType) PRIMARY KEY job_category;
+CREATE TABLE SuperStars(SuperStarType) PRIMARY KEY id;
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.2.update.sqlpp
similarity index 64%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.2.update.sqlpp
index 64ec0af..52443b5 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.2.update.sqlpp
@@ -16,22 +16,40 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+INSERT INTO Employee (
+ [
+ {
+ 'id': '123',
+ 'job_category': 'Cook',
+ 'salary': 2000,
+ 'department_id': 'K55'
+ },
+ {
+ 'id': '234',
+ 'job_category': 'Teach',
+ 'salary': 2500,
+ 'department_id': 'K54'
+ }
+ ]
+);
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+INSERT INTO Incentive (
+ [
+ { 'job_category': 'Cook',
+ 'bonus': 1000
+ },
+ { 'job_category': 'Teach',
+ 'bonus': 2000
+ }
+ ]
+)
+
+INSERT INTO SuperStars (
+ {
+ 'id': '123'
+ }
+)
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.3.query.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.3.query.sqlpp
index 64ec0af..4ba84b7 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-04-2/sugar-04-2.3.query.sqlpp
@@ -16,22 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+FROM Employee e, Incentive i
+WHERE e.job_category = i.job_category
+GROUP BY e.department_id
+SELECT e.department_id AS deptId,
+ ( FROM i AS i
+ SELECT i.job_category AS category, i.bonus AS bonus
+ ORDER BY i.bonus DESC LIMIT 3
+ ) AS job_category_details
+ORDER BY deptId DESC;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.1.ddl.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.1.ddl.sqlpp
index 64ec0af..2030780 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.1.ddl.sqlpp
@@ -16,22 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+DROP DATABASE gby IF EXISTS;
+CREATE DATABASE gby;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+USE gby;
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
+CREATE TYPE CarType AS {
+ cid : string
}
+
+CREATE TYPE TireType AS {
+ tid: string
+}
+
+CREATE TABLE Car(CarType) PRIMARY KEY cid;
+CREATE TABLE Tire(TireType) PRIMARY KEY tid;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.2.update.sqlpp
new file mode 100644
index 0000000..275e4fc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.2.update.sqlpp
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+USE gby;
+
+INSERT INTO Car (
+ [
+ {
+ 'cid': '1',
+ 'make': 'Honda',
+ 'model': 'Civic',
+ 'price': 28000,
+ 'tire_size': 'P205/55R16'
+ },
+ {
+ 'cid': '2',
+ 'make': 'Toyota',
+ 'model': 'Corolla',
+ 'price': 27000,
+ 'tire_size': 'P205/55R16'
+ }
+ ]
+);
+
+INSERT INTO Tire (
+ [
+ {
+ 'tid': '1',
+ 'mfr': 'Bridgestone',
+ 'brand': 'Turanza',
+ 'size': 'P205/55R16',
+ 'price': 150
+ },
+ {
+ 'tid': '2',
+ 'mfr': 'Goodyear',
+ 'brand': 'Eagle',
+ 'size': 'P205/55R16',
+ 'price': 100
+ }
+ ]
+)
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.3.query.sqlpp
new file mode 100644
index 0000000..4bc3555
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/group-by/sugar-05-2/sugar-05-2.3.query.sqlpp
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+USE gby;
+
+SELECT ELEMENT {
+ 'Vehicle prices including 4 tires':
+ (
+ FROM Car c JOIN Tire t ON c.tire_size = t.size
+ GROUP BY c.tire_size GROUP AS g
+ SELECT c.tire_size,
+ AVG(c.price + 4 * t.price) AS avg_total_price,
+ ( FROM g AS g
+ SELECT g.c.make AS make,
+ g.c.model AS model,
+ g.t.mfr AS mfr,
+ g.t.brand AS brand,
+ g.c.price + 4 * g.t.price AS price
+ ORDER BY g.c.make, g.c.model, g.t.mfr, g.t.brand
+ ) AS combinations
+ )
+ };
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/subquery/alias_negative/alias_negative.1.query.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/subquery/alias_negative/alias_negative.1.query.sqlpp
index 64ec0af..a05a418 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/subquery/alias_negative/alias_negative.1.query.sqlpp
@@ -16,22 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+USE test;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
+/** This test case checks the error message for a missing alias.*/
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+SELECT * FROM (SELECT 1);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.1.ddl.sqlpp
new file mode 100644
index 0000000..8649a3b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.1.ddl.sqlpp
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+drop database tpch if exists;
+create database tpch;
+
+use tpch;
+
+
+create type tpch.LineItemType as
+ closed {
+ l_orderkey : int64,
+ l_partkey : int64,
+ l_suppkey : int64,
+ l_linenumber : int64,
+ l_quantity : double,
+ l_extendedprice : double,
+ l_discount : double,
+ l_tax : double,
+ l_returnflag : string,
+ l_linestatus : string,
+ l_shipdate : string,
+ l_commitdate : string,
+ l_receiptdate : string,
+ l_shipinstruct : string,
+ l_shipmode : string,
+ l_comment : string
+}
+
+create table LineItem(LineItemType) primary key l_orderkey,l_linenumber;
+
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.2.update.sqlpp
similarity index 67%
copy from asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
copy to asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.2.update.sqlpp
index 64ec0af..d996e74 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/AdmSplitInfo.java
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.2.update.sqlpp
@@ -16,22 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-/**
- *
- */
-package org.apache.asterix.lang.common.struct;
-public class AdmSplitInfo {
- public Identifier nodeName;
- public String fileName;
+use tpch;
- public AdmSplitInfo(Identifier nodeName, String fileName) {
- this.nodeName = nodeName;
- this.fileName = fileName;
- }
- @Override
- public String toString() {
- return nodeName.value + ":" + fileName;
- }
-}
+load table LineItem using localfs ((`path`=`asterix_nc1://data/tpch0.001/lineitem.tbl`),(`format`=`delimited-text`),(`delimiter`=`|`)) pre-sorted;
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.3.query.sqlpp
new file mode 100644
index 0000000..3999ace
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/tpch-sql-sugar/q01_pricing_summary_report_2/q01_pricing_summary_report_2.3.query.sqlpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+USE tpch;
+
+/**
+ * This query tests the different treatments of l.l_returnflag
+ * for the case that it is in a non-aggregate projection expression and
+ * the case that it is in a SQL-92 aggregate function projection.
+ */
+
+SELECT l.l_returnflag,
+ l.l_linestatus,
+ sum(l_quantity) AS sum_qty,
+ sum(l_extendedprice) AS sum_base_price,
+ sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
+ sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
+ avg(l_quantity) AS ave_qty,
+ avg(l_extendedprice) AS ave_price,
+ avg(l_discount) AS ave_disc,
+ count(l.l_returnflag) AS count_order
+FROM LineItem l
+WHERE l_shipdate <= '1998-09-02'
+/* +hash */
+GROUP BY l.l_returnflag, l.l_linestatus
+ORDER BY l.l_returnflag, l.l_linestatus
+;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr-2/gby-expr-2.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr-2/gby-expr-2.1.adm
new file mode 100644
index 0000000..fe9bd8c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr-2/gby-expr-2.1.adm
@@ -0,0 +1 @@
+{ "$1": "K55", "$2": 3000 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr-3/gby-expr-3.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr-3/gby-expr-3.1.adm
new file mode 100644
index 0000000..fdb2461
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr-3/gby-expr-3.1.adm
@@ -0,0 +1 @@
+{ "$2": 1, "bonus": 1000, "$1": 3000 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr/gby-expr.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr/gby-expr.1.adm
new file mode 100644
index 0000000..4281a7b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/group-by/gby-expr/gby-expr.1.adm
@@ -0,0 +1 @@
+{ "deptId": "K55", "star_cost": 3000 }
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 494e830..f66e3a8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -1419,6 +1419,11 @@
<output-dir compare="Text">q2</output-dir>
</compilation-unit>
</test-case>
+ <test-case FilePath="dapd">
+ <compilation-unit name="q2-6">
+ <output-dir compare="Text">q2</output-dir>
+ </compilation-unit>
+ </test-case>
<!--
<test-case FilePath="dapd">
<compilation-unit name="q3">
@@ -2388,30 +2393,70 @@
</compilation-unit>
</test-case>
<test-case FilePath="group-by">
+ <compilation-unit name="sugar-01-2">
+ <output-dir compare="Text">core-01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="group-by">
<compilation-unit name="sugar-02">
<output-dir compare="Text">core-02</output-dir>
</compilation-unit>
</test-case>
<test-case FilePath="group-by">
+ <compilation-unit name="sugar-02-2">
+ <output-dir compare="Text">core-02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="group-by">
<compilation-unit name="sugar-03">
<output-dir compare="Text">core-03</output-dir>
</compilation-unit>
</test-case>
<test-case FilePath="group-by">
+ <compilation-unit name="sugar-03-2">
+ <output-dir compare="Text">core-03</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="group-by">
<compilation-unit name="sugar-04">
<output-dir compare="Text">core-04</output-dir>
</compilation-unit>
</test-case>
<test-case FilePath="group-by">
+ <compilation-unit name="sugar-04-2">
+ <output-dir compare="Text">core-04</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="group-by">
<compilation-unit name="sugar-05">
<output-dir compare="Text">core-05</output-dir>
</compilation-unit>
</test-case>
<test-case FilePath="group-by">
+ <compilation-unit name="sugar-05-2">
+ <output-dir compare="Text">core-05</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="group-by">
<compilation-unit name="null">
<output-dir compare="Text">null</output-dir>
</compilation-unit>
</test-case>
+ <test-case FilePath="group-by">
+ <compilation-unit name="gby-expr">
+ <output-dir compare="Text">gby-expr</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="group-by">
+ <compilation-unit name="gby-expr-2">
+ <output-dir compare="Text">gby-expr-2</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="group-by">
+ <compilation-unit name="gby-expr-3">
+ <output-dir compare="Text">gby-expr-3</output-dir>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="index-join">
<test-case FilePath="index-join">
@@ -5271,6 +5316,12 @@
<output-dir compare="Text">not_in</output-dir>
</compilation-unit>
</test-case>
+ <test-case FilePath="subquery">
+ <compilation-unit name="alias_negative">
+ <output-dir compare="Text">alias_negative</output-dir>
+ <expected-error>Need an alias for the enclosed expression</expected-error>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="subset-collection">
<test-case FilePath="subset-collection">
@@ -5852,6 +5903,11 @@
</compilation-unit>
</test-case>
<test-case FilePath="tpch-sql-sugar">
+ <compilation-unit name="q01_pricing_summary_report_2">
+ <output-dir compare="Text">q01_pricing_summary_report_nt</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="tpch-sql-sugar">
<compilation-unit name="q20_potential_part_promotion">
<output-dir compare="Text">q20_potential_part_promotion</output-dir>
</compilation-unit>
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/GroupbyClause.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/GroupbyClause.java
index b5d78e2..3565c5a 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/GroupbyClause.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/GroupbyClause.java
@@ -28,6 +28,7 @@
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.hyracks.algebricks.common.utils.Pair;
public class GroupbyClause implements Clause {
@@ -36,11 +37,12 @@
private List<GbyVariableExpressionPair> decorPairList;
private List<VariableExpr> withVarList;
private VariableExpr groupVar;
- private List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<Pair<Expression, Identifier>>();
+ private List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<>();
private boolean hashGroupByHint;
private boolean groupAll;
public GroupbyClause() {
+ // Default constructor.
}
public GroupbyClause(List<GbyVariableExpressionPair> gbyPairList, List<GbyVariableExpressionPair> decorPairList,
@@ -122,11 +124,11 @@
}
public boolean hasDecorList() {
- return decorPairList != null && decorPairList.size() > 0;
+ return decorPairList != null && !decorPairList.isEmpty();
}
public boolean hasWithList() {
- return withVarList != null && withVarList.size() > 0;
+ return withVarList != null && !withVarList.isEmpty();
}
public boolean hasGroupVar() {
@@ -134,10 +136,32 @@
}
public boolean hasGroupFieldList() {
- return groupFieldList != null && groupFieldList.size() > 0;
+ return groupFieldList != null && !groupFieldList.isEmpty();
}
public boolean isGroupAll() {
return groupAll;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(decorPairList, gbyPairList, groupAll, groupFieldList, groupVar,
+ hashGroupByHint, withVarList);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof GroupbyClause)) {
+ return false;
+ }
+ GroupbyClause target = (GroupbyClause) object;
+ boolean equals = ObjectUtils.equals(decorPairList, target.decorPairList)
+ && ObjectUtils.equals(gbyPairList, target.gbyPairList) && groupAll == target.groupAll
+ && ObjectUtils.equals(groupFieldList, target.groupFieldList);
+ return equals && ObjectUtils.equals(groupVar, target.groupVar) && hashGroupByHint == target.hashGroupByHint
+ && ObjectUtils.equals(withVarList, target.withVarList);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/LetClause.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/LetClause.java
index 6a4866d..7043a34 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/LetClause.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/LetClause.java
@@ -23,6 +23,7 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class LetClause implements Clause {
private VariableExpr varExpr;
@@ -64,4 +65,21 @@
return visitor.visit(this, arg);
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(bindExpr, varExpr);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof LetClause)) {
+ return false;
+ }
+ LetClause target = (LetClause) object;
+ return bindExpr.equals(target.getBindingExpr()) && varExpr.equals(target.getVarExpr());
+ }
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/LimitClause.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/LimitClause.java
index 7ebedc2..f9123ef 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/LimitClause.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/LimitClause.java
@@ -22,25 +22,27 @@
import org.apache.asterix.lang.common.base.Clause;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class LimitClause implements Clause {
- private Expression limitexpr;
+ private Expression limitExpr;
private Expression offset;
public LimitClause() {
+ // Default constructor.
}
public LimitClause(Expression limitexpr, Expression offset) {
- this.limitexpr = limitexpr;
+ this.limitExpr = limitexpr;
this.offset = offset;
}
public Expression getLimitExpr() {
- return limitexpr;
+ return limitExpr;
}
public void setLimitExpr(Expression limitexpr) {
- this.limitexpr = limitexpr;
+ this.limitExpr = limitexpr;
}
public Expression getOffset() {
@@ -64,4 +66,21 @@
public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
return visitor.visit(this, arg);
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(limitExpr, offset);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof LimitClause)) {
+ return false;
+ }
+ LimitClause target = (LimitClause) object;
+ return limitExpr.equals(target.getLimitExpr()) && ObjectUtils.equals(offset, target.getOffset());
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/OrderbyClause.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/OrderbyClause.java
index 58acd43..8574c76 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/OrderbyClause.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/OrderbyClause.java
@@ -24,6 +24,7 @@
import org.apache.asterix.lang.common.base.Clause;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.hyracks.dataflow.common.data.partition.range.IRangeMap;
public class OrderbyClause implements Clause {
@@ -34,6 +35,7 @@
private int numTuples = -1;
public OrderbyClause() {
+ // Default constructor.
}
public OrderbyClause(List<Expression> orderbyList, List<OrderModifier> modifierList) {
@@ -95,4 +97,22 @@
public void setRangeMap(IRangeMap rangeMap) {
this.rangeMap = rangeMap;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(modifierList, numFrames, numTuples, orderbyList);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof OrderbyClause)) {
+ return false;
+ }
+ OrderbyClause target = (OrderbyClause) object;
+ return ObjectUtils.equals(modifierList, target.modifierList) && numFrames == target.numFrames
+ && numTuples == target.numTuples && orderbyList.equals(target.orderbyList);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/UpdateClause.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/UpdateClause.java
index 90576ce..50bf7a5 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/UpdateClause.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/UpdateClause.java
@@ -25,6 +25,7 @@
import org.apache.asterix.lang.common.statement.InsertStatement;
import org.apache.asterix.lang.common.statement.UpdateStatement;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class UpdateClause implements Clause {
@@ -115,4 +116,25 @@
return elsebranch != null;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(condition, ds, elsebranch, ifbranch, is, target, us, value);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return false;
+ }
+ if (!(object instanceof UpdateClause)) {
+ return false;
+ }
+ UpdateClause other = (UpdateClause) object;
+ boolean equals = ObjectUtils.equals(condition, other.condition) && ObjectUtils.equals(ds, other.ds)
+ && ObjectUtils.equals(elsebranch, other.elsebranch) && ObjectUtils.equals(ifbranch, other.ifbranch);
+ equals = equals && ObjectUtils.equals(is, other.is) && ObjectUtils.equals(target, other.target)
+ && ObjectUtils.equals(us, other.us);
+ return equals && ObjectUtils.equals(value, other.value);
+ }
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/WhereClause.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/WhereClause.java
index d0af3e9..eaa17e2 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/WhereClause.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/clause/WhereClause.java
@@ -26,12 +26,8 @@
public class WhereClause implements Clause {
private Expression whereExpr;
- public Expression getWhereExpr() {
- return whereExpr;
- }
-
- public void setWhereExpr(Expression whereExpr) {
- this.whereExpr = whereExpr;
+ public WhereClause() {
+ // Default constructor.
}
public WhereClause(Expression whereExpr) {
@@ -39,7 +35,12 @@
this.whereExpr = whereExpr;
}
- public WhereClause() {
+ public Expression getWhereExpr() {
+ return whereExpr;
+ }
+
+ public void setWhereExpr(Expression whereExpr) {
+ this.whereExpr = whereExpr;
}
@Override
@@ -52,4 +53,20 @@
return visitor.visit(this, arg);
}
+ @Override
+ public int hashCode() {
+ return whereExpr.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof WhereClause)) {
+ return false;
+ }
+ WhereClause whereClause = (WhereClause) object;
+ return whereExpr.equals(whereClause.getWhereExpr());
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/AbstractAccessor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/AbstractAccessor.java
index c7ac0a1..2b7b748 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/AbstractAccessor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/AbstractAccessor.java
@@ -19,6 +19,7 @@
package org.apache.asterix.lang.common.expression;
import org.apache.asterix.lang.common.base.Expression;
+import org.apache.commons.lang.ObjectUtils;
public abstract class AbstractAccessor implements Expression {
protected Expression expr;
@@ -36,4 +37,21 @@
this.expr = expr;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(expr);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof AbstractAccessor)) {
+ return false;
+ }
+ AbstractAccessor target = (AbstractAccessor) object;
+ return expr.equals(target.expr);
+ }
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/CallExpr.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/CallExpr.java
index 44a40c4..1b7b918 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/CallExpr.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/CallExpr.java
@@ -25,6 +25,7 @@
import org.apache.asterix.lang.common.base.AbstractExpression;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class CallExpr extends AbstractExpression {
private FunctionSignature functionSignature;
@@ -68,6 +69,24 @@
@Override
public String toString() {
- return "call " + String.valueOf(functionSignature);
+ return "call " + functionSignature;
+ }
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(exprList, functionSignature, isBuiltin);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof CallExpr)) {
+ return false;
+ }
+ CallExpr target = (CallExpr) object;
+ return ObjectUtils.equals(exprList, target.exprList)
+ && ObjectUtils.equals(functionSignature, target.functionSignature) && isBuiltin == target.isBuiltin;
}
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/FieldAccessor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/FieldAccessor.java
index e23c799..0a76730 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/FieldAccessor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/FieldAccessor.java
@@ -22,6 +22,7 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class FieldAccessor extends AbstractAccessor {
private Identifier ident;
@@ -53,4 +54,21 @@
public String toString() {
return String.valueOf(expr) + "." + ident.toString();
}
+
+ @Override
+ public int hashCode() {
+ return 31 * super.hashCode() + ObjectUtils.hashCode(ident);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof FieldAccessor)) {
+ return false;
+ }
+ FieldAccessor target = (FieldAccessor) object;
+ return super.equals(target) && ObjectUtils.equals(ident, target.ident);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/FieldBinding.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/FieldBinding.java
index abfbbe3..afadddd 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/FieldBinding.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/FieldBinding.java
@@ -19,12 +19,14 @@
package org.apache.asterix.lang.common.expression;
import org.apache.asterix.lang.common.base.Expression;
+import org.apache.commons.lang3.ObjectUtils;
public class FieldBinding {
private Expression leftExpr;
private Expression rightExpr;
public FieldBinding() {
+ // default constructor.
}
public FieldBinding(Expression leftExpr, Expression rightExpr) {
@@ -49,4 +51,26 @@
this.rightExpr = rightExpr;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(leftExpr, rightExpr);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof FieldBinding)) {
+ return false;
+ }
+ FieldBinding target = (FieldBinding) object;
+ return ObjectUtils.equals(leftExpr, target.leftExpr) && ObjectUtils.equals(rightExpr, target.rightExpr);
+ }
+
+ @Override
+ public String toString() {
+ return leftExpr + ": " + rightExpr;
+ }
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/GbyVariableExpressionPair.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/GbyVariableExpressionPair.java
index bb33918..aaa6526 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/GbyVariableExpressionPair.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/GbyVariableExpressionPair.java
@@ -19,6 +19,7 @@
package org.apache.asterix.lang.common.expression;
import org.apache.asterix.lang.common.base.Expression;
+import org.apache.commons.lang3.ObjectUtils;
public class GbyVariableExpressionPair {
private VariableExpr var; // can be null
@@ -50,4 +51,25 @@
this.expr = expr;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(expr, var);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof GbyVariableExpressionPair)) {
+ return false;
+ }
+ GbyVariableExpressionPair target = (GbyVariableExpressionPair) object;
+ return ObjectUtils.equals(expr, target.expr) && ObjectUtils.equals(var, target.var);
+ }
+
+ @Override
+ public String toString() {
+ return expr + " AS " + var;
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/IfExpr.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/IfExpr.java
index f32a9cc..2709f80 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/IfExpr.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/IfExpr.java
@@ -21,6 +21,7 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class IfExpr implements Expression {
private Expression condExpr;
@@ -28,6 +29,7 @@
private Expression elseExpr;
public IfExpr() {
+ // default constructor
}
public IfExpr(Expression condExpr, Expression thenExpr, Expression elseExpr) {
@@ -69,4 +71,27 @@
public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
return visitor.visit(this, arg);
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(condExpr, elseExpr, thenExpr);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof IfExpr)) {
+ return false;
+ }
+ IfExpr target = (IfExpr) object;
+ return ObjectUtils.equals(condExpr, target.condExpr) && ObjectUtils.equals(elseExpr, target.elseExpr)
+ && ObjectUtils.equals(thenExpr, target.thenExpr);
+ }
+
+ @Override
+ public String toString() {
+ return "if(" + condExpr + ") then " + thenExpr + " else " + elseExpr;
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/IndexAccessor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/IndexAccessor.java
index 898870e..07a8254 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/IndexAccessor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/IndexAccessor.java
@@ -21,26 +21,26 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class IndexAccessor extends AbstractAccessor {
- private boolean any;
+ private boolean isAny;
private Expression indexExpr;
- public final static int ANY = -1;
-
public IndexAccessor(Expression expr, Expression indexExpr) {
super(expr);
- if (indexExpr == null)
- this.any = true;
+ if (indexExpr == null) {
+ this.isAny = true;
+ }
this.indexExpr = indexExpr;
}
public boolean isAny() {
- return any;
+ return isAny;
}
public void setAny(boolean any) {
- this.any = any;
+ this.isAny = any;
}
public Expression getIndexExpr() {
@@ -60,4 +60,26 @@
public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
return visitor.visit(this, arg);
}
+
+ @Override
+ public int hashCode() {
+ return 31 * super.hashCode() + ObjectUtils.hashCodeMulti(indexExpr, isAny);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof IndexAccessor)) {
+ return false;
+ }
+ IndexAccessor target = (IndexAccessor) object;
+ return super.equals(target) && isAny == target.isAny && ObjectUtils.equals(indexExpr, target.indexExpr);
+ }
+
+ @Override
+ public String toString() {
+ return expr + "[" + (isAny ? "?" : indexExpr) + "]";
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/ListConstructor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/ListConstructor.java
index 10e1baa..7fdca69 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/ListConstructor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/ListConstructor.java
@@ -23,12 +23,14 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class ListConstructor implements Expression {
private List<Expression> exprList;
private Type type;
public ListConstructor() {
+ // default constructor.
}
public ListConstructor(Type type, List<Expression> exprList) {
@@ -66,4 +68,21 @@
public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
return visitor.visit(this, arg);
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(exprList, type);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof ListConstructor)) {
+ return false;
+ }
+ ListConstructor target = (ListConstructor) object;
+ return ObjectUtils.equals(exprList, target.exprList) && ObjectUtils.equals(type, target.type);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/LiteralExpr.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/LiteralExpr.java
index a9fa748f..46c3c32 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/LiteralExpr.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/LiteralExpr.java
@@ -22,11 +22,13 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.Literal;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class LiteralExpr implements Expression {
private Literal value;
public LiteralExpr() {
+ // default constructor.
}
public LiteralExpr(Literal value) {
@@ -51,4 +53,21 @@
return visitor.visit(this, arg);
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof LiteralExpr)) {
+ return false;
+ }
+ LiteralExpr target = (LiteralExpr) object;
+ return ObjectUtils.equals(value, target.value);
+ }
+
}
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 bf70df4..fb64ad8 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
@@ -27,6 +27,7 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.struct.OperatorType;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class OperatorExpr extends AbstractExpression {
private List<Expression> exprList;
@@ -117,4 +118,22 @@
}
return false;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(currentop, exprBroadcastIdx, exprList, opList);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof OperatorExpr)) {
+ return false;
+ }
+ OperatorExpr target = (OperatorExpr) object;
+ return currentop == target.isCurrentop() && ObjectUtils.equals(exprBroadcastIdx, target.exprBroadcastIdx)
+ && ObjectUtils.equals(exprList, target.exprList) && ObjectUtils.equals(opList, target.opList);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OrderedListTypeDefinition.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OrderedListTypeDefinition.java
index 99d0674..08b9c53 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OrderedListTypeDefinition.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/OrderedListTypeDefinition.java
@@ -20,8 +20,9 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang.ObjectUtils;
-public class OrderedListTypeDefinition extends TypeExpression {
+public class OrderedListTypeDefinition implements TypeExpression {
private TypeExpression itemTypeExpression;
@@ -43,4 +44,20 @@
return itemTypeExpression;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(itemTypeExpression);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof OrderedListTypeDefinition)) {
+ return false;
+ }
+ OrderedListTypeDefinition target = (OrderedListTypeDefinition) object;
+ return ObjectUtils.equals(itemTypeExpression, target.itemTypeExpression);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/QuantifiedExpression.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/QuantifiedExpression.java
index 78c8ab1..e1372cd 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/QuantifiedExpression.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/QuantifiedExpression.java
@@ -24,6 +24,7 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.struct.QuantifiedPair;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class QuantifiedExpression implements Expression {
private List<QuantifiedPair> quantifiedList;
@@ -79,4 +80,23 @@
EVERY,
SOME
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(quantifiedList, quantifier, satisfiesExpr);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof QuantifiedExpression)) {
+ return false;
+ }
+ QuantifiedExpression target = (QuantifiedExpression) object;
+ return ObjectUtils.equals(quantifiedList, target.quantifiedList)
+ && ObjectUtils.equals(quantifier, target.quantifier)
+ && ObjectUtils.equals(satisfiesExpr, target.satisfiesExpr);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/RecordConstructor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/RecordConstructor.java
index 6c6b415..144b27c 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/RecordConstructor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/RecordConstructor.java
@@ -23,6 +23,7 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class RecordConstructor implements Expression {
private List<FieldBinding> fbList;
@@ -53,4 +54,21 @@
public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
return visitor.visit(this, arg);
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(fbList);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof RecordConstructor)) {
+ return false;
+ }
+ RecordConstructor target = (RecordConstructor) object;
+ return ObjectUtils.equals(fbList, target.fbList);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/RecordTypeDefinition.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/RecordTypeDefinition.java
index 5e5208e..800af9f 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/RecordTypeDefinition.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/RecordTypeDefinition.java
@@ -25,26 +25,24 @@
import org.apache.asterix.common.annotations.UndeclaredFieldsDataGen;
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
-public class RecordTypeDefinition extends TypeExpression {
+public class RecordTypeDefinition implements TypeExpression {
public enum RecordKind {
OPEN,
CLOSED
}
- private ArrayList<String> fieldNames;
- private ArrayList<TypeExpression> fieldTypes;
- private ArrayList<IRecordFieldDataGen> fieldDataGen;
- private ArrayList<Boolean> optionalFields;
+ private final List<String> fieldNames = new ArrayList<>();
+ private final List<TypeExpression> fieldTypes = new ArrayList<>();
+ private final List<IRecordFieldDataGen> fieldDataGen = new ArrayList<>();
+ private final List<Boolean> optionalFields = new ArrayList<>();
private RecordKind recordKind;
private UndeclaredFieldsDataGen undeclaredFieldsDataGen;
public RecordTypeDefinition() {
- fieldNames = new ArrayList<>();
- fieldTypes = new ArrayList<>();
- optionalFields = new ArrayList<>();
- fieldDataGen = new ArrayList<>();
+ // Default constructor.
}
@Override
@@ -102,4 +100,26 @@
return undeclaredFieldsDataGen;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(fieldDataGen, fieldNames, fieldTypes, optionalFields, recordKind,
+ undeclaredFieldsDataGen);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof RecordTypeDefinition)) {
+ return false;
+ }
+ RecordTypeDefinition target = (RecordTypeDefinition) object;
+ boolean equals = fieldDataGen.equals(target.getFieldDataGen()) && fieldNames.equals(target.getFieldNames())
+ && fieldTypes.equals(target.getFieldNames()) && optionalFields.equals(target.getOptionableFields());
+ equals = equals && ObjectUtils.equals(recordKind, target.getRecordKind())
+ && ObjectUtils.equals(undeclaredFieldsDataGen, target.getUndeclaredFieldsDataGen());
+ return equals;
+ }
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/TypeExpression.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/TypeExpression.java
index 409e683..3359be6 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/TypeExpression.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/TypeExpression.java
@@ -20,7 +20,7 @@
import org.apache.asterix.lang.common.base.ILangExpression;
-public abstract class TypeExpression implements ILangExpression {
+public interface TypeExpression extends ILangExpression {
public enum TypeExprKind {
RECORD,
@@ -29,6 +29,6 @@
UNORDEREDLIST
}
- public abstract TypeExprKind getTypeKind();
+ public TypeExprKind getTypeKind();
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/TypeReferenceExpression.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/TypeReferenceExpression.java
index 2c35cc3..49f0667 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/TypeReferenceExpression.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/TypeReferenceExpression.java
@@ -21,8 +21,9 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang.ObjectUtils;
-public class TypeReferenceExpression extends TypeExpression {
+public class TypeReferenceExpression implements TypeExpression {
private final Identifier ident;
@@ -43,4 +44,21 @@
public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
return visitor.visit(this, arg);
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(ident);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof TypeReferenceExpression)) {
+ return false;
+ }
+ TypeReferenceExpression target = (TypeReferenceExpression) object;
+ return ObjectUtils.equals(ident, target.ident);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/UnaryExpr.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/UnaryExpr.java
index cf5eefe..eef8f1c 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/UnaryExpr.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/UnaryExpr.java
@@ -21,12 +21,14 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class UnaryExpr implements Expression {
private Sign sign;
private Expression expr;
public UnaryExpr() {
+ // default constructor
}
public UnaryExpr(Sign sign, Expression expr) {
@@ -64,4 +66,21 @@
public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
return visitor.visit(this, arg);
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(expr, sign);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof UnaryExpr)) {
+ return false;
+ }
+ UnaryExpr target = (UnaryExpr) object;
+ return ObjectUtils.equals(expr, target.expr) && ObjectUtils.equals(sign, target.sign);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/UnorderedListTypeDefinition.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/UnorderedListTypeDefinition.java
index b47ade4..a0726e2 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/UnorderedListTypeDefinition.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/UnorderedListTypeDefinition.java
@@ -20,8 +20,9 @@
import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
-public class UnorderedListTypeDefinition extends TypeExpression {
+public class UnorderedListTypeDefinition implements TypeExpression {
private TypeExpression itemTypeExpression;
@@ -43,4 +44,20 @@
return itemTypeExpression;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(itemTypeExpression);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof OrderedListTypeDefinition)) {
+ return false;
+ }
+ UnorderedListTypeDefinition target = (UnorderedListTypeDefinition) object;
+ return ObjectUtils.equals(itemTypeExpression, target.itemTypeExpression);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/VariableExpr.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/VariableExpr.java
index 9eeb6f8..534c74f 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/VariableExpr.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/expression/VariableExpr.java
@@ -22,6 +22,7 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.struct.VarIdentifier;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class VariableExpr implements Expression {
private VarIdentifier var;
@@ -75,16 +76,19 @@
@Override
public int hashCode() {
- return var.hashCode();
+ return ObjectUtils.hashCode(var);
}
@Override
public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
if (!(obj instanceof VariableExpr)) {
return false;
}
VariableExpr expr = (VariableExpr) obj;
- return var.equals(expr.getVar());
+ return ObjectUtils.equals(var, expr.var);
}
@Override
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/DoubleLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/DoubleLiteral.java
index 1a5066d..f362c15 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/DoubleLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/DoubleLiteral.java
@@ -19,11 +19,9 @@
package org.apache.asterix.lang.common.literal;
import org.apache.asterix.lang.common.base.Literal;
+import org.apache.commons.lang.ObjectUtils;
public class DoubleLiteral extends Literal {
- /**
- *
- */
private static final long serialVersionUID = -5685491458356989250L;
private Double value;
@@ -45,4 +43,26 @@
public Type getLiteralType() {
return Type.DOUBLE;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof DoubleLiteral)) {
+ return false;
+ }
+ DoubleLiteral target = (DoubleLiteral) object;
+ return ObjectUtils.equals(value, target.value);
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/FalseLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/FalseLiteral.java
index 61db616..bde5260 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/FalseLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/FalseLiteral.java
@@ -23,12 +23,11 @@
public class FalseLiteral extends Literal {
private static final long serialVersionUID = -750814844423165149L;
+ public static final FalseLiteral INSTANCE = new FalseLiteral();
private FalseLiteral() {
}
- public final static FalseLiteral INSTANCE = new FalseLiteral();
-
@Override
public Type getLiteralType() {
return Type.FALSE;
@@ -45,8 +44,8 @@
}
@Override
- public boolean equals(Object obj) {
- return obj == INSTANCE;
+ public Boolean getValue() {
+ return Boolean.FALSE;
}
@Override
@@ -55,7 +54,8 @@
}
@Override
- public Boolean getValue() {
- return Boolean.FALSE;
+ public boolean equals(Object obj) {
+ return obj == INSTANCE;
}
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/FloatLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/FloatLiteral.java
index d7c54fa..a3dfd6a 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/FloatLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/FloatLiteral.java
@@ -19,11 +19,9 @@
package org.apache.asterix.lang.common.literal;
import org.apache.asterix.lang.common.base.Literal;
+import org.apache.commons.lang.ObjectUtils;
public class FloatLiteral extends Literal {
- /**
- *
- */
private static final long serialVersionUID = 3273563021227964396L;
private Float value;
@@ -45,4 +43,26 @@
public Type getLiteralType() {
return Type.FLOAT;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof FloatLiteral)) {
+ return false;
+ }
+ FloatLiteral target = (FloatLiteral) object;
+ return ObjectUtils.equals(value, target.value);
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/IntegerLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/IntegerLiteral.java
index e0c1de3..a46a736 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/IntegerLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/IntegerLiteral.java
@@ -19,11 +19,9 @@
package org.apache.asterix.lang.common.literal;
import org.apache.asterix.lang.common.base.Literal;
+import org.apache.commons.lang.ObjectUtils;
public class IntegerLiteral extends Literal {
- /**
- *
- */
private static final long serialVersionUID = -8633520244871361967L;
private Integer value;
@@ -32,6 +30,7 @@
this.value = value;
}
+ @Override
public Integer getValue() {
return value;
}
@@ -44,4 +43,26 @@
public Type getLiteralType() {
return Type.INTEGER;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof IntegerLiteral)) {
+ return false;
+ }
+ IntegerLiteral target = (IntegerLiteral) object;
+ return value.equals(target.getValue());
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/LongIntegerLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/LongIntegerLiteral.java
index 3320dac..66164d1 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/LongIntegerLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/LongIntegerLiteral.java
@@ -19,11 +19,9 @@
package org.apache.asterix.lang.common.literal;
import org.apache.asterix.lang.common.base.Literal;
+import org.apache.commons.lang.ObjectUtils;
public class LongIntegerLiteral extends Literal {
- /**
- *
- */
private static final long serialVersionUID = -8633520244871361967L;
private Long value;
@@ -45,4 +43,26 @@
public Type getLiteralType() {
return Type.LONG;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof LongIntegerLiteral)) {
+ return false;
+ }
+ LongIntegerLiteral target = (LongIntegerLiteral) object;
+ return value.equals(target.getValue());
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/MissingLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/MissingLiteral.java
index 2c2fa8e..c12ed6f 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/MissingLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/MissingLiteral.java
@@ -22,12 +22,11 @@
public class MissingLiteral extends Literal {
private static final long serialVersionUID = 1L;
+ public static final MissingLiteral INSTANCE = new MissingLiteral();
private MissingLiteral() {
}
- public final static MissingLiteral INSTANCE = new MissingLiteral();
-
@Override
public Type getLiteralType() {
return Type.MISSING;
@@ -52,4 +51,9 @@
public Object getValue() {
return null;
}
+
+ @Override
+ public String toString() {
+ return getStringValue();
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/NullLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/NullLiteral.java
index e5fdb1d..197aa6e 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/NullLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/NullLiteral.java
@@ -21,17 +21,12 @@
import org.apache.asterix.lang.common.base.Literal;
public class NullLiteral extends Literal {
-
- /**
- *
- */
private static final long serialVersionUID = -7782153599294838739L;
+ public static final NullLiteral INSTANCE = new NullLiteral();
private NullLiteral() {
}
- public final static NullLiteral INSTANCE = new NullLiteral();
-
@Override
public Type getLiteralType() {
return Type.NULL;
@@ -56,4 +51,9 @@
public Object getValue() {
return null;
}
+
+ @Override
+ public String toString() {
+ return getStringValue();
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/StringLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/StringLiteral.java
index 623c9ee..9caad3e 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/StringLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/StringLiteral.java
@@ -19,6 +19,7 @@
package org.apache.asterix.lang.common.literal;
import org.apache.asterix.lang.common.base.Literal;
+import org.apache.commons.lang.ObjectUtils;
public class StringLiteral extends Literal {
@@ -30,6 +31,7 @@
this.value = value;
}
+ @Override
public String getValue() {
return value;
}
@@ -47,4 +49,26 @@
public String getStringValue() {
return value;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCode(value);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof StringLiteral)) {
+ return false;
+ }
+ StringLiteral target = (StringLiteral) object;
+ return ObjectUtils.equals(value, target.value);
+ }
+
+ @Override
+ public String toString() {
+ return value;
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/TrueLiteral.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/TrueLiteral.java
index a919216..e0ae87d 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/TrueLiteral.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/literal/TrueLiteral.java
@@ -22,12 +22,11 @@
public class TrueLiteral extends Literal {
private static final long serialVersionUID = -8513245514578847512L;
+ public static final TrueLiteral INSTANCE = new TrueLiteral();
private TrueLiteral() {
}
- public final static TrueLiteral INSTANCE = new TrueLiteral();
-
@Override
public Type getLiteralType() {
return Type.TRUE;
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/ExpressionSubstitutionEnvironment.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/ExpressionSubstitutionEnvironment.java
new file mode 100644
index 0000000..8f5597f
--- /dev/null
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/ExpressionSubstitutionEnvironment.java
@@ -0,0 +1,165 @@
+/*
+ * 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.common.rewrites;
+
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.ILangExpression;
+import org.apache.asterix.lang.common.expression.VariableExpr;
+
+import com.google.common.collect.HashMultiset;
+import com.google.common.collect.Multiset;
+
+/**
+ * This class is in charge of substitute expressions by a given mapping while
+ * traversing a given AST. The traversal and expression substitution should
+ * be based on the correct variable scoping. In order to support scoping at the
+ * caller, this class provides methods like mark, reset and pop.
+ */
+public class ExpressionSubstitutionEnvironment {
+
+ @FunctionalInterface
+ public static interface FreeVariableCollector {
+ public Collection<VariableExpr> getFreeVariable(ILangExpression expr) throws AsterixException;
+ }
+
+ @FunctionalInterface
+ public static interface DeepCopier {
+ public ILangExpression deepCopy(ILangExpression expr) throws AsterixException;
+ }
+
+ private Map<Expression, Expression> exprMap = new HashMap<>();
+ private Map<VariableExpr, Expression> freeVarToExprMap = new HashMap<>();
+
+ // We use multiset here because variables can be defined multiple times
+ // in the scope stack.
+ private Multiset<Expression> disabledExpr = HashMultiset.create();
+
+ // Snapshots of variables that should be disabled for replacement,
+ // e.g., if a variable is redefined in a closer scope.
+ private Deque<Multiset<Expression>> disabledExprBackup = new ArrayDeque<>();
+
+ public ExpressionSubstitutionEnvironment() {
+ // Default constructor.
+ }
+
+ public ExpressionSubstitutionEnvironment(Map<Expression, Expression> map, FreeVariableCollector freeVarCollector)
+ throws AsterixException {
+ addMapping(map, freeVarCollector);
+ }
+
+ /**
+ * Finds a substitution expression.
+ *
+ * @param expr
+ * the original expression.
+ * @return the new, replaced expression.
+ */
+ public Expression findSubstitution(Expression expr, DeepCopier deepCopier) throws AsterixException {
+ Expression replacementExpr = exprMap.get(expr);
+ if (replacementExpr != null && !disabledExpr.contains(replacementExpr)) {
+ return (Expression) deepCopier.deepCopy(replacementExpr);
+ }
+ return expr;
+ }
+
+ /**
+ * Disable a substitution when a free variable in the expression is re-defined.
+ *
+ * @param var
+ * a re-defined variable.
+ */
+ public void disableVariable(VariableExpr var) {
+ Expression expr = freeVarToExprMap.get(var);
+ if (expr != null) {
+ disabledExpr.add(expr);
+ }
+ }
+
+ /**
+ * Re-enable a substitution when a re-defined variable exits its scope.
+ *
+ * @param var
+ * a re-defined variable.
+ */
+ public void enableVariable(VariableExpr var) {
+ Expression expr = freeVarToExprMap.get(var);
+ if (expr != null) {
+ disabledExpr.remove(expr);
+ }
+ }
+
+ /**
+ * Tasks a snapshot of the current states.
+ *
+ * @return the snapshot id that can be reset to in the future.
+ */
+ public int mark() {
+ Multiset<Expression> copyOfDisabledExprs = HashMultiset.create();
+ copyOfDisabledExprs.addAll(disabledExpr);
+ disabledExprBackup.push(copyOfDisabledExprs);
+ return disabledExprBackup.size() - 1;
+ }
+
+ /**
+ * Resets the internal states to a snapshot.
+ *
+ * @param depth,
+ * the snapshot id that the caller wants to recover to.
+ */
+ public void reset(int depth) {
+ while (disabledExprBackup.size() > depth) {
+ disabledExpr = disabledExprBackup.pop();
+ }
+ }
+
+ /**
+ * Restores to the most-recent snapshot.
+ */
+ public void pop() {
+ if (!disabledExprBackup.isEmpty()) {
+ disabledExpr = disabledExprBackup.pop();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return exprMap.toString();
+ }
+
+ private void addMapping(Map<Expression, Expression> map, FreeVariableCollector freeVarCollector)
+ throws AsterixException {
+ exprMap.putAll(map);
+ // Put free variable to target expression map.
+ for (Entry<Expression, Expression> entry : map.entrySet()) {
+ Expression targetExpr = entry.getKey();
+ for (VariableExpr freeVar : freeVarCollector.getFreeVariable(targetExpr)) {
+ freeVarToExprMap.put(freeVar, targetExpr);
+ }
+ }
+ }
+
+}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/LangRewritingContext.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/LangRewritingContext.java
index 9036413..10cd7d8 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/LangRewritingContext.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/LangRewritingContext.java
@@ -25,6 +25,7 @@
public final class LangRewritingContext {
private int mark = 0;
private int varCounter;
+ private int systemVarCounter = 1;
private HashMap<Integer, VarIdentifier> oldVarIdToNewVarId = new HashMap<>();
public LangRewritingContext(int varCounter) {
@@ -63,7 +64,7 @@
public VarIdentifier newVariable() {
int id = newId();
// Prefixes system-generated variables with "#".
- return new VarIdentifier("#" + id, id);
+ return new VarIdentifier("#" + (systemVarCounter++), id);
}
public void markCounter() {
@@ -78,4 +79,5 @@
varCounter++;
return varCounter;
}
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/VariableSubstitutionEnvironment.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/VariableSubstitutionEnvironment.java
index 4c4767e..26f528c 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/VariableSubstitutionEnvironment.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/VariableSubstitutionEnvironment.java
@@ -29,7 +29,7 @@
private Map<String, Expression> oldVarToNewExpressionMap = new HashMap<String, Expression>();
public VariableSubstitutionEnvironment() {
-
+ // Default constructor.
}
public VariableSubstitutionEnvironment(Map<VariableExpr, Expression> varExprMap) {
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DeleteStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DeleteStatement.java
index 3a2a933..ba3440f 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DeleteStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DeleteStatement.java
@@ -26,6 +26,7 @@
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class DeleteStatement implements Statement {
@@ -95,4 +96,25 @@
return datasets;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(condition, datasetName, datasets, dataverseName, dataverses, rewrittenQuery,
+ vars);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof DeleteStatement)) {
+ return false;
+ }
+ DeleteStatement target = (DeleteStatement) object;
+ boolean equals = ObjectUtils.equals(condition, target.condition)
+ && ObjectUtils.equals(datasetName, target.datasetName) && ObjectUtils.equals(datasets, target.datasets)
+ && ObjectUtils.equals(dataverseName, target.dataverseName);
+ return equals && ObjectUtils.equals(dataverses, target.dataverses)
+ && ObjectUtils.equals(rewrittenQuery, target.rewrittenQuery) && ObjectUtils.equals(vars, target.vars);
+ }
}
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 de81de0..aab0979 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
@@ -22,6 +22,7 @@
import org.apache.asterix.lang.common.base.Statement;
import org.apache.asterix.lang.common.struct.Identifier;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class InsertStatement implements Statement {
@@ -63,4 +64,22 @@
return visitor.visit(this, arg);
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(datasetName, dataverseName, query);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof InsertStatement)) {
+ return false;
+ }
+ InsertStatement target = (InsertStatement) object;
+ return ObjectUtils.equals(datasetName, target.datasetName)
+ && ObjectUtils.equals(dataverseName, target.dataverseName) && ObjectUtils.equals(query, target.query);
+ }
+
}
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 64ca0c1..a9cba21 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
@@ -25,16 +25,17 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.Statement;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class Query implements Statement {
private boolean topLevel = true;
private Expression body;
private int varCounter;
- private List<String> dataverses = new ArrayList<String>();
- private List<String> datasets = new ArrayList<String>();
+ private List<String> dataverses = new ArrayList<>();
+ private List<String> datasets = new ArrayList<>();
public Query() {
-
+ // Default constructor.
}
public Query(boolean topLevel, Expression body, int varCounter, List<String> dataverses, List<String> datasets) {
@@ -94,4 +95,22 @@
public List<String> getDatasets() {
return datasets;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(body, datasets, dataverses, topLevel);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof Query)) {
+ return false;
+ }
+ Query target = (Query) object;
+ return ObjectUtils.equals(body, target.body) && ObjectUtils.equals(datasets, target.datasets)
+ && ObjectUtils.equals(dataverses, target.dataverses) && topLevel == target.topLevel;
+ }
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java
index c82bbad..c61ec0b 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpdateStatement.java
@@ -26,6 +26,7 @@
import org.apache.asterix.lang.common.clause.UpdateClause;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class UpdateStatement implements Statement {
@@ -67,4 +68,22 @@
return visitor.visit(this, arg);
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(condition, target, ucs, vars);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof UpdateStatement)) {
+ return false;
+ }
+ UpdateStatement update = (UpdateStatement) object;
+ return ObjectUtils.equals(condition, update.condition) && ObjectUtils.equals(target, update.target)
+ && ObjectUtils.equals(ucs, update.ucs) && ObjectUtils.equals(vars, update.vars);
+ }
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java
index f415951..fa11930 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/UpsertStatement.java
@@ -31,4 +31,20 @@
return Kind.UPSERT;
}
+ @Override
+ public int hashCode() {
+ return super.hashCode() + Kind.UPSERT.ordinal();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof UpsertStatement)) {
+ return false;
+ }
+ return super.equals(object);
+ }
+
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/Identifier.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/Identifier.java
index d029e3e..b77fd94 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/Identifier.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/Identifier.java
@@ -18,10 +18,13 @@
*/
package org.apache.asterix.lang.common.struct;
+import org.apache.commons.lang.ObjectUtils;
+
public class Identifier {
protected String value;
public Identifier() {
+ // default constructor.
}
public Identifier(String value) {
@@ -36,22 +39,25 @@
this.value = value;
}
+ @Override
public String toString() {
return value;
}
@Override
public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
if (!(o instanceof Identifier)) {
return false;
- } else {
- Identifier i = (Identifier) o;
- return this.value.equals(i.value);
}
+ Identifier target = (Identifier) o;
+ return ObjectUtils.equals(value, target.value);
}
@Override
public int hashCode() {
- return value.hashCode();
+ return ObjectUtils.hashCode(value);
}
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/QuantifiedPair.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/QuantifiedPair.java
index 6be8918..ab8a3f3 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/QuantifiedPair.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/struct/QuantifiedPair.java
@@ -20,12 +20,14 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.commons.lang3.ObjectUtils;
public class QuantifiedPair {
private VariableExpr varExpr;
private Expression expr;
public QuantifiedPair() {
+ // default constructor
}
public QuantifiedPair(VariableExpr varExpr, Expression expr) {
@@ -49,4 +51,17 @@
this.expr = expr;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(expr, varExpr);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (!(object instanceof QuantifiedPair)) {
+ return false;
+ }
+ QuantifiedPair target = (QuantifiedPair) object;
+ return ObjectUtils.equals(expr, target.expr) && ObjectUtils.equals(varExpr, target.varExpr);
+ }
}
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 6549151..a217bea 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
@@ -18,6 +18,8 @@
*/
package org.apache.asterix.lang.common.struct;
+import org.apache.commons.lang3.ObjectUtils;
+
public final class VarIdentifier extends Identifier {
private int id = 0;
@@ -53,7 +55,7 @@
@Override
public int hashCode() {
- return value.hashCode();
+ return ObjectUtils.hashCodeMulti(value);
}
@Override
@@ -62,6 +64,6 @@
return false;
}
VarIdentifier vid = (VarIdentifier) obj;
- return value.equals(vid.value);
+ return ObjectUtils.equals(value, vid.value);
}
}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/VariableCloneAndSubstitutionUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/VariableCloneAndSubstitutionUtil.java
index 29298db..1948b84 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/VariableCloneAndSubstitutionUtil.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/VariableCloneAndSubstitutionUtil.java
@@ -34,19 +34,22 @@
public class VariableCloneAndSubstitutionUtil {
+ private VariableCloneAndSubstitutionUtil() {
+ }
+
public static List<GbyVariableExpressionPair> substInVarExprPair(LangRewritingContext context,
- List<GbyVariableExpressionPair> gbyVeList, VariableSubstitutionEnvironment arg,
- VariableSubstitutionEnvironment newSubs, CloneAndSubstituteVariablesVisitor visitor)
- throws AsterixException {
- List<GbyVariableExpressionPair> veList = new LinkedList<GbyVariableExpressionPair>();
+ List<GbyVariableExpressionPair> gbyVeList, VariableSubstitutionEnvironment newSubs,
+ CloneAndSubstituteVariablesVisitor visitor) throws AsterixException {
+ VariableSubstitutionEnvironment subs = newSubs;
+ List<GbyVariableExpressionPair> veList = new LinkedList<>();
for (GbyVariableExpressionPair vep : gbyVeList) {
VariableExpr oldGbyVar = vep.getVar();
VariableExpr newGbyVar = null;
if (oldGbyVar != null) {
newGbyVar = visitor.generateNewVariable(context, oldGbyVar);
- newSubs = eliminateSubstFromList(newGbyVar, newSubs);
+ subs = eliminateSubstFromList(newGbyVar, subs);
}
- Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = vep.getExpr().accept(visitor, newSubs);
+ Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = vep.getExpr().accept(visitor, subs);
GbyVariableExpressionPair ve2 = new GbyVariableExpressionPair(newGbyVar, (Expression) p1.first);
veList.add(ve2);
}
@@ -62,7 +65,7 @@
public static List<Expression> visitAndCloneExprList(List<Expression> oldExprList,
VariableSubstitutionEnvironment arg, CloneAndSubstituteVariablesVisitor visitor) throws AsterixException {
- List<Expression> exprs = new ArrayList<Expression>(oldExprList.size());
+ List<Expression> exprs = new ArrayList<>(oldExprList.size());
for (Expression e : oldExprList) {
Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = e.accept(visitor, arg);
exprs.add((Expression) p1.first);
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/CloneAndSubstituteVariablesVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/CloneAndSubstituteVariablesVisitor.java
index d380862..57264be 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/CloneAndSubstituteVariablesVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/CloneAndSubstituteVariablesVisitor.java
@@ -71,25 +71,24 @@
VariableExpr varExpr = lc.getVarExpr();
VariableExpr newVe = generateNewVariable(context, varExpr);
LetClause newLet = new LetClause(newVe, (Expression) p1.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newLet,
- VariableCloneAndSubstitutionUtil.eliminateSubstFromList(lc.getVarExpr(), env));
+ return new Pair<>(newLet, VariableCloneAndSubstitutionUtil.eliminateSubstFromList(lc.getVarExpr(), env));
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(GroupbyClause gc,
VariableSubstitutionEnvironment env) throws AsterixException {
VariableSubstitutionEnvironment newSubs = env;
- List<GbyVariableExpressionPair> newGbyList = VariableCloneAndSubstitutionUtil.substInVarExprPair(context,
- gc.getGbyPairList(), env, newSubs, this);
- List<GbyVariableExpressionPair> newDecorList = gc.hasDecorList() ? VariableCloneAndSubstitutionUtil
- .substInVarExprPair(context, gc.getDecorPairList(), env, newSubs, this)
- : new ArrayList<GbyVariableExpressionPair>();
+ List<GbyVariableExpressionPair> newGbyList =
+ VariableCloneAndSubstitutionUtil.substInVarExprPair(context, gc.getGbyPairList(), newSubs, this);
+ List<GbyVariableExpressionPair> newDecorList = gc.hasDecorList()
+ ? VariableCloneAndSubstitutionUtil.substInVarExprPair(context, gc.getDecorPairList(), newSubs, this)
+ : new ArrayList<>();
VariableExpr newGroupVar = null;
if (gc.hasGroupVar()) {
newGroupVar = generateNewVariable(context, gc.getGroupVar());
}
- List<VariableExpr> wList = new LinkedList<VariableExpr>();
+ List<VariableExpr> wList = new LinkedList<>();
if (gc.hasWithList()) {
for (VariableExpr w : gc.getWithVarList()) {
VarIdentifier newVar = context.getRewrittenVar(w.getVar().getId());
@@ -109,26 +108,26 @@
}
GroupbyClause newGroup = new GroupbyClause(newGbyList, newDecorList, wList, newGroupVar, newGroupFieldList,
gc.hasHashGroupByHint(), gc.isGroupAll());
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newGroup, newSubs);
+ return new Pair<>(newGroup, newSubs);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(QuantifiedExpression qe,
VariableSubstitutionEnvironment env) throws AsterixException {
List<QuantifiedPair> oldPairs = qe.getQuantifiedList();
- List<QuantifiedPair> newPairs = new ArrayList<QuantifiedPair>(oldPairs.size());
+ List<QuantifiedPair> newPairs = new ArrayList<>(oldPairs.size());
VariableSubstitutionEnvironment newSubs = env;
for (QuantifiedPair t : oldPairs) {
VariableExpr newVar = generateNewVariable(context, t.getVarExpr());
newSubs = VariableCloneAndSubstitutionUtil.eliminateSubstFromList(newVar, newSubs);
- Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = visitUnnesBindingExpression(t.getExpr(),
- newSubs);
+ Pair<ILangExpression, VariableSubstitutionEnvironment> p1 =
+ visitUnnesBindingExpression(t.getExpr(), newSubs);
QuantifiedPair t2 = new QuantifiedPair(newVar, (Expression) p1.first);
newPairs.add(t2);
}
Pair<ILangExpression, VariableSubstitutionEnvironment> p2 = qe.getSatisfiesExpr().accept(this, newSubs);
QuantifiedExpression qe2 = new QuantifiedExpression(qe.getQuantifier(), newPairs, (Expression) p2.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(qe2, newSubs);
+ return new Pair<>(qe2, newSubs);
}
@Override
@@ -136,7 +135,7 @@
VariableSubstitutionEnvironment env) throws AsterixException {
Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = wc.getWhereExpr().accept(this, env);
WhereClause newW = new WhereClause((Expression) p1.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newW, p1.second);
+ return new Pair<>(newW, p1.second);
}
@Override
@@ -144,13 +143,13 @@
VariableSubstitutionEnvironment env) throws AsterixException {
List<Expression> exprList = VariableCloneAndSubstitutionUtil.visitAndCloneExprList(pf.getExprList(), env, this);
CallExpr f = new CallExpr(pf.getFunctionSignature(), exprList);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(f, env);
+ return new Pair<>(f, env);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(FunctionDecl fd,
VariableSubstitutionEnvironment env) throws AsterixException {
- List<VarIdentifier> newList = new ArrayList<VarIdentifier>(fd.getParamList().size());
+ List<VarIdentifier> newList = new ArrayList<>(fd.getParamList().size());
for (VarIdentifier vi : fd.getParamList()) {
VariableExpr varExpr = new VariableExpr(vi);
if (!env.constainsOldVar(varExpr)) {
@@ -165,7 +164,7 @@
Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = fd.getFuncBody().accept(this, env);
FunctionDecl newF = new FunctionDecl(fd.getSignature(), newList, (Expression) p1.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newF, env);
+ return new Pair<>(newF, env);
}
@Override
@@ -175,22 +174,22 @@
Pair<ILangExpression, VariableSubstitutionEnvironment> p2 = ifexpr.getThenExpr().accept(this, env);
Pair<ILangExpression, VariableSubstitutionEnvironment> p3 = ifexpr.getElseExpr().accept(this, env);
IfExpr i = new IfExpr((Expression) p1.first, (Expression) p2.first, (Expression) p3.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(i, env);
+ return new Pair<>(i, env);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(LimitClause lc,
VariableSubstitutionEnvironment env) throws AsterixException {
Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = lc.getLimitExpr().accept(this, env);
- Pair<ILangExpression, VariableSubstitutionEnvironment> p2 = null;
+ Pair<ILangExpression, VariableSubstitutionEnvironment> p2;
Expression lcOffsetExpr = lc.getOffset();
if (lcOffsetExpr != null) {
p2 = lcOffsetExpr.accept(this, env);
} else {
- p2 = new Pair<ILangExpression, VariableSubstitutionEnvironment>(null, null);
+ p2 = new Pair<>(null, null);
}
LimitClause c = new LimitClause((Expression) p1.first, (Expression) p2.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(c, env);
+ return new Pair<>(c, env);
}
@Override
@@ -199,38 +198,38 @@
List<Expression> oldExprList = lc.getExprList();
List<Expression> exprs = VariableCloneAndSubstitutionUtil.visitAndCloneExprList(oldExprList, env, this);
ListConstructor c = new ListConstructor(lc.getType(), exprs);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(c, env);
+ return new Pair<>(c, env);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(LiteralExpr l,
VariableSubstitutionEnvironment env) throws AsterixException {
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(l, env);
+ return new Pair<>(l, env);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(OperatorExpr op,
VariableSubstitutionEnvironment env) throws AsterixException {
List<Expression> oldExprList = op.getExprList();
- List<Expression> exprs = new ArrayList<Expression>(oldExprList.size());
+ List<Expression> exprs = new ArrayList<>(oldExprList.size());
for (Expression e : oldExprList) {
Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = e.accept(this, env);
exprs.add((Expression) p1.first);
}
OperatorExpr oe = new OperatorExpr(exprs, op.getExprBroadcastIdx(), op.getOpList(), op.isCurrentop());
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(oe, env);
+ return new Pair<>(oe, env);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(OrderbyClause oc,
VariableSubstitutionEnvironment env) throws AsterixException {
- List<Expression> exprList = VariableCloneAndSubstitutionUtil.visitAndCloneExprList(oc.getOrderbyList(), env,
- this);
+ List<Expression> exprList =
+ VariableCloneAndSubstitutionUtil.visitAndCloneExprList(oc.getOrderbyList(), env, this);
OrderbyClause oc2 = new OrderbyClause(exprList, oc.getModifierList());
oc2.setNumFrames(oc.getNumFrames());
oc2.setNumTuples(oc.getNumTuples());
oc2.setRangeMap(oc.getRangeMap());
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(oc2, env);
+ return new Pair<>(oc2, env);
}
@Override
@@ -239,14 +238,14 @@
Query newQ = new Query();
Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = q.getBody().accept(this, env);
newQ.setBody((Expression) p1.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newQ, p1.second);
+ return new Pair<>(newQ, p1.second);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(RecordConstructor rc,
VariableSubstitutionEnvironment env) throws AsterixException {
List<FieldBinding> oldFbs = rc.getFbList();
- ArrayList<FieldBinding> newFbs = new ArrayList<FieldBinding>(oldFbs.size());
+ ArrayList<FieldBinding> newFbs = new ArrayList<>(oldFbs.size());
for (FieldBinding fb : oldFbs) {
Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = fb.getLeftExpr().accept(this, env);
Pair<ILangExpression, VariableSubstitutionEnvironment> p2 = fb.getRightExpr().accept(this, env);
@@ -254,7 +253,7 @@
newFbs.add(fb2);
}
RecordConstructor newRc = new RecordConstructor(newFbs);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newRc, env);
+ return new Pair<>(newRc, env);
}
@Override
@@ -262,7 +261,7 @@
VariableSubstitutionEnvironment env) throws AsterixException {
Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = u.getExpr().accept(this, env);
UnaryExpr newU = new UnaryExpr(u.getSign(), (Expression) p1.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newU, env);
+ return new Pair<>(newU, env);
}
@Override
@@ -276,7 +275,7 @@
}
IndexAccessor i = new IndexAccessor((Expression) p1.first, indexExpr);
i.setAny(ia.isAny());
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(i, env);
+ return new Pair<>(i, env);
}
@Override
@@ -284,13 +283,13 @@
VariableSubstitutionEnvironment env) throws AsterixException {
Pair<ILangExpression, VariableSubstitutionEnvironment> p = fa.getExpr().accept(this, env);
FieldAccessor newF = new FieldAccessor((Expression) p.first, fa.getIdent());
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newF, p.second);
+ return new Pair<>(newF, p.second);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(VariableExpr v,
VariableSubstitutionEnvironment env) throws AsterixException {
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(rewriteVariableExpr(v, env), env);
+ return new Pair<>(rewriteVariableExpr(v, env), env);
}
// Replace a variable expression if the variable is to-be substituted.
@@ -320,8 +319,7 @@
public VariableExpr generateNewVariable(LangRewritingContext context, VariableExpr varExpr) {
VarIdentifier vi = varExpr.getVar();
VarIdentifier newVar = context.mapOldId(vi.getId(), vi.getValue());
- VariableExpr newVarExpr = new VariableExpr(newVar);
- return newVarExpr;
+ return new VariableExpr(newVar);
}
/**
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
new file mode 100644
index 0000000..1fd561e
--- /dev/null
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
@@ -0,0 +1,245 @@
+/*
+ * 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.common.visitor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Expression;
+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.clause.WhereClause;
+import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.FieldAccessor;
+import org.apache.asterix.lang.common.expression.FieldBinding;
+import org.apache.asterix.lang.common.expression.IfExpr;
+import org.apache.asterix.lang.common.expression.IndexAccessor;
+import org.apache.asterix.lang.common.expression.ListConstructor;
+import org.apache.asterix.lang.common.expression.LiteralExpr;
+import org.apache.asterix.lang.common.expression.OperatorExpr;
+import org.apache.asterix.lang.common.expression.QuantifiedExpression;
+import org.apache.asterix.lang.common.expression.RecordConstructor;
+import org.apache.asterix.lang.common.expression.UnaryExpr;
+import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.rewrites.ExpressionSubstitutionEnvironment;
+import org.apache.asterix.lang.common.rewrites.ExpressionSubstitutionEnvironment.DeepCopier;
+import org.apache.asterix.lang.common.statement.FunctionDecl;
+import org.apache.asterix.lang.common.statement.Query;
+import org.apache.asterix.lang.common.struct.QuantifiedPair;
+import org.apache.asterix.lang.common.visitor.base.AbstractQueryExpressionVisitor;
+
+public abstract class SubstituteExpressionVisitor
+ extends AbstractQueryExpressionVisitor<Expression, ExpressionSubstitutionEnvironment> {
+ private final DeepCopier deepCopier;
+
+ public SubstituteExpressionVisitor(DeepCopier deepCopier) {
+ this.deepCopier = deepCopier;
+ }
+
+ @Override
+ public Expression visit(LetClause lc, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ // Marks the binding variable for future visiting until it exists its scope.
+ env.disableVariable(lc.getVarExpr());
+ lc.setBindingExpr(lc.getBindingExpr().accept(this, env));
+ return null;
+ }
+
+ @Override
+ public Expression visit(Query q, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ q.setBody(q.getBody().accept(this, env));
+ return null;
+ }
+
+ @Override
+ public Expression visit(FunctionDecl fd, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ // Do nothing for a function declaration.
+ return null;
+ }
+
+ @Override
+ public Expression visit(LiteralExpr l, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ return env.findSubstitution(l, deepCopier);
+ }
+
+ @Override
+ public Expression visit(VariableExpr v, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ return env.findSubstitution(v, deepCopier);
+ }
+
+ @Override
+ public Expression visit(ListConstructor lc, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newLc = env.findSubstitution(lc, deepCopier);
+ if (newLc == lc) {
+ lc.setExprList(rewriteExpressionList(lc.getExprList(), env));
+ return lc;
+ } else {
+ return newLc.accept(this, env);
+ }
+ }
+
+ @Override
+ public Expression visit(RecordConstructor rc, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newRc = env.findSubstitution(rc, deepCopier);
+ if (newRc == rc) {
+ for (FieldBinding fb : rc.getFbList()) {
+ fb.setLeftExpr(fb.getLeftExpr().accept(this, env));
+ fb.setRightExpr(fb.getRightExpr().accept(this, env));
+ }
+ return rc;
+ } else {
+ return newRc.accept(this, env);
+ }
+ }
+
+ @Override
+ public Expression visit(OperatorExpr operatorExpr, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newOpertorExpr = env.findSubstitution(operatorExpr, deepCopier);
+ if (newOpertorExpr == operatorExpr) {
+ operatorExpr.setExprList(rewriteExpressionList(operatorExpr.getExprList(), env));
+ return operatorExpr;
+ } else {
+ return newOpertorExpr.accept(this, env);
+ }
+ }
+
+ @Override
+ public Expression visit(FieldAccessor fa, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newFa = env.findSubstitution(fa, deepCopier);
+ if (newFa == fa) {
+ fa.setExpr(fa.getExpr().accept(this, env));
+ return fa;
+ } else {
+ return newFa.accept(this, env);
+ }
+ }
+
+ @Override
+ public Expression visit(IndexAccessor ia, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newIa = env.findSubstitution(ia, deepCopier);
+ if (newIa == ia) {
+ ia.setExpr(ia.getExpr().accept(this, env));
+ ia.setIndexExpr(ia.getIndexExpr().accept(this, env));
+ return ia;
+ } else {
+ return newIa.accept(this, env);
+ }
+ }
+
+ @Override
+ public Expression visit(IfExpr ifexpr, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newIfExpr = env.findSubstitution(ifexpr, deepCopier);
+ if (newIfExpr == ifexpr) {
+ ifexpr.setCondExpr(ifexpr.getCondExpr().accept(this, env));
+ ifexpr.setThenExpr(ifexpr.getThenExpr().accept(this, env));
+ ifexpr.setElseExpr(ifexpr.getElseExpr().accept(this, env));
+ return ifexpr;
+ } else {
+ return newIfExpr.accept(this, env);
+ }
+ }
+
+ @Override
+ public Expression visit(QuantifiedExpression qe, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newQe = env.findSubstitution(qe, deepCopier);
+ if (newQe == qe) {
+ // Rewrites the quantifier list.
+ for (QuantifiedPair pair : qe.getQuantifiedList()) {
+ pair.setExpr(pair.getExpr().accept(this, env));
+ }
+
+ // Rewrites the condition.
+ for (QuantifiedPair pair : qe.getQuantifiedList()) {
+ // Marks each binding var.
+ env.disableVariable(pair.getVarExpr());
+ }
+ qe.setSatisfiesExpr(qe.getSatisfiesExpr().accept(this, env));
+ for (QuantifiedPair pair : qe.getQuantifiedList()) {
+ // Let each binding var exit its scope.
+ env.enableVariable(pair.getVarExpr());
+ }
+ return qe;
+ } else {
+ return newQe.accept(this, env);
+ }
+ }
+
+ @Override
+ public Expression visit(WhereClause wc, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ wc.setWhereExpr(wc.getWhereExpr().accept(this, env));
+ return null;
+ }
+
+ @Override
+ public Expression visit(OrderbyClause oc, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ oc.setOrderbyList(rewriteExpressionList(oc.getOrderbyList(), env));
+ return null;
+ }
+
+ @Override
+ public Expression visit(LimitClause lc, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ lc.setLimitExpr(lc.getLimitExpr().accept(this, env));
+ if (lc.hasOffset()) {
+ lc.setOffset(lc.getOffset().accept(this, env));
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(UnaryExpr u, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newU = env.findSubstitution(u, deepCopier);
+ if (newU == u) {
+ u.setExpr(u.getExpr().accept(this, env));
+ return u;
+ } else {
+ return newU.accept(this, env);
+ }
+ }
+
+ @Override
+ public Expression visit(CallExpr callExpr, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ Expression newCallExpr = env.findSubstitution(callExpr, deepCopier);
+ if (newCallExpr == callExpr) {
+ callExpr.setExprList(rewriteExpressionList(callExpr.getExprList(), env));
+ return callExpr;
+ } else {
+ return newCallExpr.accept(this, env);
+ }
+ }
+
+ /**
+ * Rewrites the expression list.
+ *
+ * @param exprs,
+ * list of expressions.
+ * @param env,
+ * ExpressionSubstitutionEnvironment.
+ * @return a list of rewritten expressions.
+ * @throws AsterixException
+ */
+ protected List<Expression> rewriteExpressionList(List<Expression> exprs, ExpressionSubstitutionEnvironment env)
+ throws AsterixException {
+ List<Expression> newExprs = new ArrayList<>();
+ for (Expression expr : exprs) {
+ newExprs.add(env.findSubstitution(expr, deepCopier));
+ }
+ return newExprs;
+ }
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/AbstractBinaryCorrelateClause.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/AbstractBinaryCorrelateClause.java
index b1dbba5..ed5f404 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/AbstractBinaryCorrelateClause.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/AbstractBinaryCorrelateClause.java
@@ -23,6 +23,7 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.sqlpp.optype.JoinType;
+import org.apache.commons.lang3.ObjectUtils;
public abstract class AbstractBinaryCorrelateClause implements Clause {
@@ -63,4 +64,22 @@
return rightPosVar != null;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(joinType, rightExpr, rightPosVar, rightVar);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof AbstractBinaryCorrelateClause)) {
+ return false;
+ }
+ AbstractBinaryCorrelateClause target = (AbstractBinaryCorrelateClause) object;
+ return ObjectUtils.equals(joinType, target.joinType) && ObjectUtils.equals(rightExpr, target.rightExpr)
+ && ObjectUtils.equals(rightPosVar, target.rightPosVar) && ObjectUtils.equals(rightVar, target.rightVar);
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/AbstractBinaryCorrelateWithConditionClause.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/AbstractBinaryCorrelateWithConditionClause.java
index e1d4a7b..3773ea9 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/AbstractBinaryCorrelateWithConditionClause.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/AbstractBinaryCorrelateWithConditionClause.java
@@ -41,4 +41,21 @@
this.conditionExpr = conditionExpr;
}
+ @Override
+ public int hashCode() {
+ return 31 * super.hashCode() + conditionExpr.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof AbstractBinaryCorrelateWithConditionClause)) {
+ return false;
+ }
+ AbstractBinaryCorrelateWithConditionClause target = (AbstractBinaryCorrelateWithConditionClause) object;
+ return super.equals(target) && conditionExpr.equals(target.getConditionExpression());
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/FromClause.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/FromClause.java
index da6c512..aff731b 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/FromClause.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/FromClause.java
@@ -30,7 +30,7 @@
public class FromClause implements Clause {
- private List<FromTerm> fromTerms = new ArrayList<FromTerm>();
+ private List<FromTerm> fromTerms = new ArrayList<>();
public FromClause(List<FromTerm> fromTerms) {
this.fromTerms = fromTerms;
@@ -54,4 +54,21 @@
public String toString() {
return fromTerms.stream().map(String::valueOf).collect(Collectors.joining(", "));
}
+
+ @Override
+ public int hashCode() {
+ return fromTerms.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof FromClause)) {
+ return false;
+ }
+ FromClause target = (FromClause) object;
+ return fromTerms.equals(target.getFromTerms());
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/FromTerm.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/FromTerm.java
index 82e1f02..d4e522a 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/FromTerm.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/FromTerm.java
@@ -28,19 +28,22 @@
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class FromTerm implements Clause {
private Expression leftExpr;
private VariableExpr leftVar;
private VariableExpr posVar;
- private List<AbstractBinaryCorrelateClause> correlateClauses;
+ private List<AbstractBinaryCorrelateClause> correlateClauses = new ArrayList<>();
public FromTerm(Expression leftExpr, VariableExpr leftVar, VariableExpr posVar,
List<AbstractBinaryCorrelateClause> correlateClauses) {
this.leftExpr = leftExpr;
this.leftVar = leftVar;
this.posVar = posVar;
- this.correlateClauses = correlateClauses == null ? new ArrayList<>() : correlateClauses;
+ if (correlateClauses != null) {
+ this.correlateClauses.addAll(correlateClauses);
+ }
}
@Override
@@ -85,4 +88,23 @@
public String toString() {
return String.valueOf(leftExpr) + " AS " + leftVar;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(correlateClauses, leftExpr, leftVar, posVar);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof FromTerm)) {
+ return false;
+ }
+ FromTerm target = (FromTerm) object;
+ return ObjectUtils.equals(correlateClauses, target.correlateClauses)
+ && ObjectUtils.equals(leftExpr, target.leftExpr) && ObjectUtils.equals(leftVar, target.leftVar)
+ && ObjectUtils.equals(posVar, target.posVar);
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/HavingClause.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/HavingClause.java
index 98cca9c..19b7692 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/HavingClause.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/HavingClause.java
@@ -50,4 +50,21 @@
this.filterExpression = filterExpression;
}
+ @Override
+ public int hashCode() {
+ return filterExpression.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof HavingClause)) {
+ return false;
+ }
+ HavingClause target = (HavingClause) object;
+ return filterExpression.equals(target.getFilterExpression());
+ }
+
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/Projection.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/Projection.java
index f73ec1e..148cc36 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/Projection.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/Projection.java
@@ -24,6 +24,7 @@
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class Projection implements Clause {
@@ -81,4 +82,22 @@
public String toString() {
return star ? "*" : (String.valueOf(expr) + (exprStar ? ".*" : (hasName() ? " as " + getName() : "")));
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(expr, exprStar, name, star);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof Projection)) {
+ return false;
+ }
+ Projection target = (Projection) object;
+ return ObjectUtils.equals(expr, target.expr) && ObjectUtils.equals(exprStar, target.exprStar)
+ && ObjectUtils.equals(name, target.name) && ObjectUtils.equals(star, target.star);
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectBlock.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectBlock.java
index f63eced..e297335 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectBlock.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectBlock.java
@@ -19,6 +19,7 @@
package org.apache.asterix.lang.sqlpp.clause;
+import java.util.ArrayList;
import java.util.List;
import org.apache.asterix.common.exceptions.AsterixException;
@@ -28,15 +29,16 @@
import org.apache.asterix.lang.common.clause.WhereClause;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class SelectBlock implements Clause {
private SelectClause selectClause;
private FromClause fromClause;
- private List<LetClause> letClauses;
+ private List<LetClause> letClauses = new ArrayList<>();
private WhereClause whereClause;
private GroupbyClause groupbyClause;
- private List<LetClause> letClausesAfterGby;
+ private List<LetClause> letClausesAfterGby = new ArrayList<>();
private HavingClause havingClause;
public SelectBlock(SelectClause selectClause, FromClause fromClause, List<LetClause> letClauses,
@@ -44,11 +46,15 @@
HavingClause havingClause) {
this.selectClause = selectClause;
this.fromClause = fromClause;
- this.letClauses = letClauses;
+ if (letClauses != null) {
+ this.letClauses.addAll(letClauses);
+ }
this.whereClause = whereClause;
this.groupbyClause = groupbyClause;
this.havingClause = havingClause;
- this.letClausesAfterGby = letClausesAfterGby;
+ if (letClausesAfterGby != null) {
+ this.letClausesAfterGby.addAll(letClausesAfterGby);
+ }
}
@Override
@@ -90,7 +96,7 @@
}
public boolean hasLetClauses() {
- return letClauses != null && letClauses.size() > 0;
+ return letClauses != null && !letClauses.isEmpty();
}
public boolean hasWhereClause() {
@@ -102,7 +108,7 @@
}
public boolean hasLetClausesAfterGroupby() {
- return letClausesAfterGby != null && letClausesAfterGby.size() > 0;
+ return letClausesAfterGby != null && !letClausesAfterGby.isEmpty();
}
public List<LetClause> getLetListAfterGroupby() {
@@ -116,4 +122,53 @@
public void setGroupbyClause(GroupbyClause groupbyClause) {
this.groupbyClause = groupbyClause;
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(fromClause, groupbyClause, havingClause, letClauses, letClausesAfterGby,
+ selectClause, whereClause);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof SelectBlock)) {
+ return false;
+ }
+ SelectBlock target = (SelectBlock) object;
+ boolean equals = ObjectUtils.equals(fromClause, target.fromClause)
+ && ObjectUtils.equals(groupbyClause, target.groupbyClause)
+ && ObjectUtils.equals(havingClause, target.havingClause)
+ && ObjectUtils.equals(letClauses, target.letClauses);
+ return equals && ObjectUtils.equals(letClausesAfterGby, target.letClausesAfterGby)
+ && ObjectUtils.equals(selectClause, target.selectClause)
+ && ObjectUtils.equals(whereClause, target.whereClause);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(selectClause);
+ if (hasFromClause()) {
+ sb.append(fromClause);
+ }
+ if (hasLetClauses()) {
+ sb.append(letClauses);
+ }
+ if (hasWhereClause()) {
+ sb.append(whereClause);
+ }
+ if (hasGroupbyClause()) {
+ sb.append(groupbyClause);
+ }
+ if (hasLetClausesAfterGroupby()) {
+ sb.append(letClausesAfterGby);
+ }
+ if (hasHavingClause()) {
+ sb.append(havingClause);
+ }
+ return sb.toString();
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectClause.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectClause.java
index 42c8b29..12e501b 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectClause.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectClause.java
@@ -23,6 +23,7 @@
import org.apache.asterix.lang.common.base.Clause;
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class SelectClause implements Clause {
@@ -69,6 +70,24 @@
@Override
public String toString() {
return "select " + (distinct ? "distinct " : "")
- + (selectElement() ? "element " + String.valueOf(selectElement) : String.valueOf(selectRegular));
+ + (selectElement() ? "element " + selectElement : String.valueOf(selectRegular));
+ }
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(distinct, selectElement, selectRegular);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof SelectClause)) {
+ return false;
+ }
+ SelectClause target = (SelectClause) object;
+ return distinct == target.distinct && ObjectUtils.equals(selectElement, target.selectElement)
+ && ObjectUtils.equals(selectRegular, target.selectRegular);
}
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectElement.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectElement.java
index 14efd0f..6a630b5 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectElement.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectElement.java
@@ -55,4 +55,21 @@
public String toString() {
return String.valueOf(expr);
}
+
+ @Override
+ public int hashCode() {
+ return expr.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof SelectElement)) {
+ return false;
+ }
+ SelectElement target = (SelectElement) object;
+ return expr.equals(target.expr);
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectRegular.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectRegular.java
index 4703e01..1df1e7a 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectRegular.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectRegular.java
@@ -53,4 +53,21 @@
public String toString() {
return projections.stream().map(String::valueOf).collect(Collectors.joining(", "));
}
+
+ @Override
+ public int hashCode() {
+ return projections.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof SelectRegular)) {
+ return false;
+ }
+ SelectRegular target = (SelectRegular) object;
+ return projections.equals(target.getProjections());
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectSetOperation.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectSetOperation.java
index 3af93a7..6e0fb21 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectSetOperation.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectSetOperation.java
@@ -28,15 +28,18 @@
import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class SelectSetOperation implements Clause {
private SetOperationInput leftInput;
- private List<SetOperationRight> rightInputs;
+ private List<SetOperationRight> rightInputs = new ArrayList<>();
public SelectSetOperation(SetOperationInput leftInput, List<SetOperationRight> rightInputs) {
this.leftInput = leftInput;
- this.rightInputs = rightInputs == null ? new ArrayList<SetOperationRight>() : rightInputs;
+ if (rightInputs != null) {
+ this.rightInputs.addAll(rightInputs);
+ }
}
@Override
@@ -58,7 +61,34 @@
}
public boolean hasRightInputs() {
- return rightInputs != null && rightInputs.size() > 0;
+ return rightInputs != null && !rightInputs.isEmpty();
+ }
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(leftInput, rightInputs);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof SelectSetOperation)) {
+ return false;
+ }
+ SelectSetOperation target = (SelectSetOperation) object;
+ return ObjectUtils.equals(leftInput, target.leftInput) && ObjectUtils.equals(rightInputs, target.rightInputs);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(leftInput);
+ for (SetOperationRight right : rightInputs) {
+ sb.append(" " + right);
+ }
+ return sb.toString();
}
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/IndependentSubquery.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/IndependentSubquery.java
index 3825092..3b4c1aa 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/IndependentSubquery.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/IndependentSubquery.java
@@ -54,4 +54,21 @@
public String toString() {
return String.valueOf(expr);
}
+
+ @Override
+ public int hashCode() {
+ return expr.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof IndependentSubquery)) {
+ return false;
+ }
+ IndependentSubquery target = (IndependentSubquery) object;
+ return this.expr.equals(target.getExpr());
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/SelectExpression.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/SelectExpression.java
index 7f9daf8..a940c47 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/SelectExpression.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/SelectExpression.java
@@ -18,6 +18,7 @@
*/
package org.apache.asterix.lang.sqlpp.expression;
+import java.util.ArrayList;
import java.util.List;
import org.apache.asterix.common.exceptions.AsterixException;
@@ -28,10 +29,11 @@
import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class SelectExpression implements Expression {
- private List<LetClause> letList;
+ private List<LetClause> letList = new ArrayList<>();
private SelectSetOperation selectSetOperation;
private OrderbyClause orderbyClause;
private LimitClause limitClause;
@@ -39,7 +41,9 @@
public SelectExpression(List<LetClause> letList, SelectSetOperation selectSetOperation, OrderbyClause orderbyClause,
LimitClause limitClause, boolean subquery) {
- this.letList = letList;
+ if (letList != null) {
+ this.letList.addAll(letList);
+ }
this.selectSetOperation = selectSetOperation;
this.orderbyClause = orderbyClause;
this.limitClause = limitClause;
@@ -92,4 +96,42 @@
subquery = setSubquery;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(letList, limitClause, orderbyClause, selectSetOperation, subquery);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof SelectExpression)) {
+ return false;
+ }
+ SelectExpression target = (SelectExpression) object;
+ boolean equals =
+ ObjectUtils.equals(letList, target.letList) && ObjectUtils.equals(limitClause, target.limitClause)
+ && ObjectUtils.equals(orderbyClause, target.orderbyClause)
+ && ObjectUtils.equals(selectSetOperation, target.selectSetOperation);
+ return equals && subquery == target.subquery;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(subquery ? "(" : "");
+ if (this.hasLetClauses()) {
+ sb.append(letList.toString());
+ }
+ sb.append(selectSetOperation);
+ if (hasOrderby()) {
+ sb.append(orderbyClause);
+ }
+ if (hasLimit()) {
+ sb.append(limitClause);
+ }
+ sb.append(subquery ? ")" : "");
+ return sb.toString();
+ }
}
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 49823e7..6ddfa40 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
@@ -37,6 +37,12 @@
// Inlines column aliases.
inlineColumnAlias();
+ // Generates column names.
+ generateColumnNames();
+
+ // Substitutes group-by key expressions.
+ substituteGroupbyKeyExpression();
+
// Inlines WITH expressions.
inlineWithExpressions();
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 5a62e1e..d0e2aa3 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
@@ -49,6 +49,7 @@
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.parser.FunctionParser;
import org.apache.asterix.lang.sqlpp.parser.SqlppParserFactory;
+import org.apache.asterix.lang.sqlpp.rewrites.visitor.GenerateColumnNameVisitor;
import org.apache.asterix.lang.sqlpp.rewrites.visitor.InlineColumnAliasVisitor;
import org.apache.asterix.lang.sqlpp.rewrites.visitor.InlineWithExpressionVisitor;
import org.apache.asterix.lang.sqlpp.rewrites.visitor.OperatorExpressionVisitor;
@@ -56,6 +57,7 @@
import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGlobalAggregationSugarVisitor;
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.SubstituteGroupbyExpressionWithVariableVisitor;
import org.apache.asterix.lang.sqlpp.rewrites.visitor.VariableCheckAndRewriteVisitor;
import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
@@ -97,6 +99,12 @@
// Inlines column aliases.
inlineColumnAlias();
+ // Generates column names.
+ generateColumnNames();
+
+ // Substitutes group-by key expressions.
+ substituteGroupbyKeyExpression();
+
// Inlines WITH expressions.
inlineWithExpressions();
@@ -157,10 +165,29 @@
return;
}
// Inlines with expressions.
- InlineWithExpressionVisitor inlineWithExpressionVisitor = new InlineWithExpressionVisitor(context);
+ InlineWithExpressionVisitor inlineWithExpressionVisitor = new InlineWithExpressionVisitor();
inlineWithExpressionVisitor.visit(topExpr, null);
}
+ protected void generateColumnNames() throws AsterixException {
+ if (topExpr == null) {
+ return;
+ }
+ // Generate column names if they are missing in the user query.
+ GenerateColumnNameVisitor generateColumnNameVisitor = new GenerateColumnNameVisitor(context);
+ generateColumnNameVisitor.visit(topExpr, null);
+ }
+
+ protected void substituteGroupbyKeyExpression() throws AsterixException {
+ if (topExpr == null) {
+ return;
+ }
+ // Substitute group-by key expressions that appear in the select clause.
+ SubstituteGroupbyExpressionWithVariableVisitor substituteGbyExprVisitor =
+ new SubstituteGroupbyExpressionWithVariableVisitor();
+ substituteGbyExprVisitor.visit(topExpr, null);
+ }
+
protected void rewriteOperatorExpression() throws AsterixException {
if (topExpr == null) {
return;
@@ -183,8 +210,8 @@
if (topExpr == null) {
return;
}
- VariableCheckAndRewriteVisitor variableCheckAndRewriteVisitor = new VariableCheckAndRewriteVisitor(context,
- overwrite, metadataProvider);
+ VariableCheckAndRewriteVisitor variableCheckAndRewriteVisitor =
+ new VariableCheckAndRewriteVisitor(context, overwrite, metadataProvider);
variableCheckAndRewriteVisitor.visit(topExpr, null);
}
@@ -235,8 +262,8 @@
Function function = lookupUserDefinedFunctionDecl(signature);
if (function == null) {
- FunctionSignature normalizedSignature = FunctionMapUtil.normalizeBuiltinFunctionSignature(signature,
- false);
+ FunctionSignature normalizedSignature =
+ FunctionMapUtil.normalizeBuiltinFunctionSignature(signature, false);
if (AsterixBuiltinFunctions.isBuiltinCompilerFunction(normalizedSignature, includePrivateFunctions)) {
continue;
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/GenerateColumnNameVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/GenerateColumnNameVisitor.java
new file mode 100644
index 0000000..e2edb3a
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/GenerateColumnNameVisitor.java
@@ -0,0 +1,66 @@
+/*
+ * 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.AsterixException;
+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.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
+import org.apache.asterix.lang.sqlpp.clause.Projection;
+import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
+import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
+import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppExpressionScopingVisitor;
+
+// Generates implicit column names for projections in a SELECT clause and group-by keys.
+public class GenerateColumnNameVisitor extends AbstractSqlppExpressionScopingVisitor {
+
+ public GenerateColumnNameVisitor(LangRewritingContext context) {
+ super(context);
+ }
+
+ @Override
+ public Expression visit(SelectBlock selectBlock, ILangExpression arg) throws AsterixException {
+ // Visit selectBlock first so that column names starts from $1.
+ selectBlock.getSelectClause().accept(this, arg);
+ return super.visit(selectBlock, arg);
+ }
+
+ @Override
+ public Expression visit(Projection projection, ILangExpression arg) throws AsterixException {
+ if (!projection.star() && projection.getName() == null) {
+ projection.setName(SqlppVariableUtil.variableNameToDisplayedFieldName(context.newVariable().getValue()));
+ }
+ return super.visit(projection, arg);
+ }
+
+ @Override
+ public Expression visit(GroupbyClause groupbyClause, ILangExpression arg) throws AsterixException {
+ for (GbyVariableExpressionPair gbyKeyPair : groupbyClause.getGbyPairList()) {
+ if (gbyKeyPair.getVar() == null) {
+ gbyKeyPair.setVar(new VariableExpr(context.newVariable()));
+ }
+ }
+ return super.visit(groupbyClause, arg);
+ }
+
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
index 6b74d3f..57cbdc5 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
@@ -130,12 +130,12 @@
@Override
public Void visit(Projection projection, Boolean overwriteWithGbyKeyVarRefs) throws AsterixException {
- if (projection.star()) {
+ if (projection.star() || projection.getName() == null) {
return null;
}
projection.getExpression().accept(this, overwriteWithGbyKeyVarRefs);
- VariableExpr columnAlias = new VariableExpr(
- SqlppVariableUtil.toInternalVariableIdentifier(projection.getName()));
+ VariableExpr columnAlias =
+ new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(projection.getName()));
VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope().getVarSubstitutionEnvironment();
Expression gbyKey = (Expression) SqlppRewriteUtil.deepCopy(env.findSubstitution(columnAlias));
if (overwriteWithGbyKeyVarRefs) {
@@ -220,26 +220,25 @@
// We only need to deal with the case that the left expression (for a field name) is
// a string literal. Otherwise, it is different from a column alias in a projection
// (e.g., foo.name AS name) in regular SQL SELECT.
- if (leftExpr.getKind() == Kind.LITERAL_EXPRESSION) {
- LiteralExpr literalExpr = (LiteralExpr) leftExpr;
- if (literalExpr.getValue().getLiteralType() == Literal.Type.STRING) {
- String fieldName = literalExpr.getValue().getStringValue();
- VariableExpr columnAlias = new VariableExpr(
- SqlppVariableUtil.toInternalVariableIdentifier(fieldName));
- VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope()
- .getVarSubstitutionEnvironment();
- if (overwriteWithGbyKeyVarRefs) {
- // Rewrites the field value expression by the mapped grouping key
- // (for the column alias) if there exists such a mapping.
- Expression gbyKey = (Expression) SqlppRewriteUtil.deepCopy(env.findSubstitution(columnAlias));
- if (gbyKey != null) {
- binding.setRightExpr(gbyKey);
- }
- } else {
- // If this is the first pass, map a field name (i.e., column alias) to the field expression.
- scopeChecker.getCurrentScope().addSymbolExpressionMappingToScope(columnAlias,
- binding.getRightExpr());
+ if (leftExpr.getKind() != Kind.LITERAL_EXPRESSION) {
+ continue;
+ }
+ LiteralExpr literalExpr = (LiteralExpr) leftExpr;
+ if (literalExpr.getValue().getLiteralType() == Literal.Type.STRING) {
+ String fieldName = literalExpr.getValue().getStringValue();
+ VariableExpr columnAlias = new VariableExpr(SqlppVariableUtil.toInternalVariableIdentifier(fieldName));
+ VariableSubstitutionEnvironment env = scopeChecker.getCurrentScope().getVarSubstitutionEnvironment();
+ if (overwriteWithGbyKeyVarRefs) {
+ // Rewrites the field value expression by the mapped grouping key
+ // (for the column alias) if there exists such a mapping.
+ Expression gbyKey = (Expression) SqlppRewriteUtil.deepCopy(env.findSubstitution(columnAlias));
+ if (gbyKey != null) {
+ binding.setRightExpr(gbyKey);
}
+ } else {
+ // If this is the first pass, map a field name (i.e., column alias) to the field expression.
+ scopeChecker.getCurrentScope().addSymbolExpressionMappingToScope(columnAlias,
+ binding.getRightExpr());
}
}
}
@@ -324,8 +323,8 @@
Map<VariableExpr, VariableExpr> oldGbyExprsToNewGbyVarMap = new HashMap<>();
for (GbyVariableExpressionPair gbyVarExpr : gc.getGbyPairList()) {
Expression oldGbyExpr = gbyVarExpr.getExpr();
- Expression newExpr = (Expression) SqlppVariableSubstitutionUtil.substituteVariableWithoutContext(oldGbyExpr,
- env);
+ Expression newExpr =
+ (Expression) SqlppVariableSubstitutionUtil.substituteVariableWithoutContext(oldGbyExpr, env);
newExpr.accept(this, overwriteWithGbyKeyVarRefs);
gbyVarExpr.setExpr(newExpr);
if (oldGbyExpr.getKind() == Kind.VARIABLE_EXPRESSION) {
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineWithExpressionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineWithExpressionVisitor.java
index bec1523..a01c09f 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineWithExpressionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineWithExpressionVisitor.java
@@ -28,17 +28,12 @@
import org.apache.asterix.lang.common.base.ILangExpression;
import org.apache.asterix.lang.common.clause.LetClause;
import org.apache.asterix.lang.common.expression.VariableExpr;
-import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.util.SqlppVariableSubstitutionUtil;
-import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppExpressionScopingVisitor;
+import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
-public class InlineWithExpressionVisitor extends AbstractSqlppExpressionScopingVisitor {
-
- public InlineWithExpressionVisitor(LangRewritingContext context) {
- super(context);
- }
+public class InlineWithExpressionVisitor extends AbstractSqlppSimpleExpressionVisitor {
@Override
public Expression visit(SelectExpression selectExpression, ILangExpression arg) throws AsterixException {
@@ -66,7 +61,9 @@
// Continues to visit the rewritten select expression.
return super.visit(newSelectExpression, arg);
+ } else {
+ // Continues to visit inside the select expression.
+ return super.visit(selectExpression, arg);
}
- return selectExpression;
}
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SubstituteGroupbyExpressionWithVariableVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SubstituteGroupbyExpressionWithVariableVisitor.java
new file mode 100644
index 0000000..c5cd60e
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SubstituteGroupbyExpressionWithVariableVisitor.java
@@ -0,0 +1,89 @@
+/*
+ * 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.HashMap;
+import java.util.Map;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.Expression.Kind;
+import org.apache.asterix.lang.common.base.ILangExpression;
+import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
+import org.apache.asterix.lang.common.rewrites.ExpressionSubstitutionEnvironment;
+import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
+import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
+import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
+import org.apache.asterix.lang.sqlpp.util.SqlppVariableUtil;
+import org.apache.asterix.lang.sqlpp.visitor.SqlppSubstituteExpressionsVisitor;
+import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
+
+// Replaces expressions that appear in having/select/order-by/limit clause and are identical to some
+// group by key expression with the group by key expression.
+public class SubstituteGroupbyExpressionWithVariableVisitor extends AbstractSqlppSimpleExpressionVisitor {
+
+ @Override
+ public Expression visit(SelectBlock selectBlock, ILangExpression arg) throws AsterixException {
+ if (selectBlock.hasGroupbyClause()) {
+ Map<Expression, Expression> map = new HashMap<>();
+ for (GbyVariableExpressionPair gbyKeyPair : selectBlock.getGroupbyClause().getGbyPairList()) {
+ Expression gbyKeyExpr = gbyKeyPair.getExpr();
+ if (gbyKeyExpr.getKind() != Kind.VARIABLE_EXPRESSION) {
+ map.put(gbyKeyExpr, gbyKeyPair.getVar());
+ }
+ }
+
+ // Creates a substitution visitor.
+ ExpressionSubstitutionEnvironment env =
+ new ExpressionSubstitutionEnvironment(map, SqlppVariableUtil::getFreeVariables);
+ SubstituteGroupbyExpressionVisitor visitor = new SubstituteGroupbyExpressionVisitor();
+
+ // Rewrites having/select/order-by/limit clauses.
+ if (selectBlock.hasHavingClause()) {
+ selectBlock.getHavingClause().accept(visitor, env);
+ }
+ selectBlock.getSelectClause().accept(visitor, env);
+ SelectExpression selectExpression = (SelectExpression) arg;
+ if (selectExpression.hasOrderby()) {
+ selectExpression.getOrderbyClause().accept(visitor, env);
+ }
+ if (selectExpression.hasLimit()) {
+ selectExpression.getLimitClause().accept(visitor, env);
+ }
+ }
+ return super.visit(selectBlock, arg);
+ }
+
+}
+
+class SubstituteGroupbyExpressionVisitor extends SqlppSubstituteExpressionsVisitor {
+
+ @Override
+ public Expression visit(CallExpr callExpr, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ FunctionSignature signature = callExpr.getFunctionSignature();
+ if (FunctionMapUtil.isSql92AggregateFunction(signature)) {
+ return callExpr;
+ } else {
+ return super.visit(callExpr, env);
+ }
+ }
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/struct/SetOperationInput.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/struct/SetOperationInput.java
index da89709..55245fe 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/struct/SetOperationInput.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/struct/SetOperationInput.java
@@ -23,6 +23,7 @@
import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
public class SetOperationInput {
@@ -57,4 +58,26 @@
return ((ISqlppVisitor<R, T>) visitor).visit(subquery, arg);
}
}
+
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(selectBlock, subquery);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof SetOperationInput)) {
+ return false;
+ }
+ SetOperationInput target = (SetOperationInput) object;
+ return ObjectUtils.equals(selectBlock, target.selectBlock) && ObjectUtils.equals(subquery, target.subquery);
+ }
+
+ @Override
+ public String toString() {
+ return selectBlock.toString();
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/struct/SetOperationRight.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/struct/SetOperationRight.java
index 5e061e0..ade4119 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/struct/SetOperationRight.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/struct/SetOperationRight.java
@@ -19,6 +19,7 @@
package org.apache.asterix.lang.sqlpp.struct;
import org.apache.asterix.lang.sqlpp.optype.SetOpType;
+import org.apache.commons.lang3.ObjectUtils;
public class SetOperationRight {
@@ -44,4 +45,30 @@
return setOperationRightInput;
}
+ @Override
+ public int hashCode() {
+ return ObjectUtils.hashCodeMulti(opType, setOperationRightInput, setSemantics);
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+ if (!(object instanceof SetOperationRight)) {
+ return false;
+ }
+ SetOperationRight target = (SetOperationRight) object;
+ return ObjectUtils.equals(opType, target.opType)
+ && ObjectUtils.equals(setOperationRightInput, target.setOperationRightInput)
+ && setSemantics == target.setSemantics;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(opType + " " + (setSemantics ? "" : " all "));
+ sb.append(setOperationRightInput);
+ return sb.toString();
+ }
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/ExpressionToVariableUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/ExpressionToVariableUtil.java
index 8817d76..93e1828 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/ExpressionToVariableUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/ExpressionToVariableUtil.java
@@ -19,19 +19,23 @@
package org.apache.asterix.lang.sqlpp.util;
+import org.apache.asterix.common.exceptions.AsterixException;
import org.apache.asterix.lang.common.base.Expression;
import org.apache.asterix.lang.common.base.Expression.Kind;
import org.apache.asterix.lang.common.expression.FieldAccessor;
import org.apache.asterix.lang.common.expression.VariableExpr;
import org.apache.asterix.lang.common.struct.VarIdentifier;
import org.apache.asterix.lang.sqlpp.parser.ParseException;
+import org.apache.log4j.Logger;
public class ExpressionToVariableUtil {
+ private static final Logger LOGGER = Logger.getLogger(ExpressionToVariableUtil.class);
+
private ExpressionToVariableUtil() {
}
- public static String getGeneratedIdentifier(Expression expr) throws ParseException {
+ private static String getGeneratedIdentifier(Expression expr) throws ParseException {
if (expr.getKind() == Kind.VARIABLE_EXPRESSION) {
VariableExpr bindingVarExpr = (VariableExpr) expr;
return bindingVarExpr.getVar().getValue();
@@ -39,15 +43,62 @@
FieldAccessor fa = (FieldAccessor) expr;
return SqlppVariableUtil.toInternalVariableName(fa.getIdent().getValue());
} else {
- throw new ParseException("Need an alias for the enclosed " + expr.getKind() + " expression.");
+ try {
+ throw new ParseException(
+ "Need an alias for the enclosed expression:\n" + SqlppFormatPrintUtil.toString(expr));
+ } catch (AsterixException e) {
+ LOGGER.error(e.getLocalizedMessage(), e);
+ throw new ParseException(e.getLocalizedMessage());
+ }
}
}
- public static VariableExpr getGeneratedVariable(Expression expr) throws ParseException {
- VarIdentifier var = new VarIdentifier(getGeneratedIdentifier(expr));
- VariableExpr varExpr = new VariableExpr();
- varExpr.setVar(var);
- return varExpr;
+ /**
+ * Generates an identifier according to an expression.
+ *
+ * @param expr
+ * the input expression.
+ * @param raiseError,
+ * if it is not possible to generate an identifier from the input expression,
+ * to raise the error if true, and to return a null if false.
+ * @return the generated identifier.
+ * @throws ParseException
+ */
+ public static String getGeneratedIdentifier(Expression expr, boolean raiseError) throws ParseException {
+ try {
+ return getGeneratedIdentifier(expr);
+ } catch (ParseException e) {
+ if (raiseError) {
+ throw e;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Generates a variable according to an expression.
+ *
+ * @param expr
+ * the input expression.
+ * @param raiseError,
+ * if it is not possible to generate a variable from the input expression,
+ * to raise the error if true, and to return a null if false.
+ * @return the generated variable.
+ * @throws ParseException
+ */
+ public static VariableExpr getGeneratedVariable(Expression expr, boolean raiseError) throws ParseException {
+ try {
+ String varName = getGeneratedIdentifier(expr);
+ VarIdentifier var = new VarIdentifier(varName);
+ VariableExpr varExpr = new VariableExpr();
+ varExpr.setVar(var);
+ return varExpr;
+ } catch (ParseException e) {
+ if (raiseError) {
+ throw e;
+ }
+ return null;
+ }
}
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppAstPrintUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppAstPrintUtil.java
index 5888194..f700439 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppAstPrintUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppAstPrintUtil.java
@@ -32,7 +32,11 @@
public class SqlppAstPrintUtil {
- private static final IAstPrintVisitorFactory astPrintVisitor = new SqlppAstPrintVisitorFactory();
+ private static final IAstPrintVisitorFactory astPrintVisitorFactory = new SqlppAstPrintVisitorFactory();
+
+ private SqlppAstPrintUtil() {
+
+ }
/**
* Prints the AST (abstract syntax tree) of an ILangExpression.
@@ -44,7 +48,7 @@
* @throws AsterixException
*/
public static void print(ILangExpression expr, PrintWriter output) throws AsterixException {
- QueryPrintVisitor visitor = astPrintVisitor.createLangVisitor(output);
+ QueryPrintVisitor visitor = astPrintVisitorFactory.createLangVisitor(output);
expr.accept(visitor, 0);
output.flush();
}
@@ -59,7 +63,7 @@
* @throws AsterixException
*/
public static void print(List<Statement> statements, PrintWriter output) throws AsterixException {
- QueryPrintVisitor visitor = astPrintVisitor.createLangVisitor(output);
+ QueryPrintVisitor visitor = astPrintVisitorFactory.createLangVisitor(output);
for (Statement statement : statements) {
statement.accept(visitor, 0);
}
@@ -73,7 +77,7 @@
* @throws AsterixException
*/
public static String toString(ILangExpression expr) throws AsterixException {
- List<ILangExpression> exprs = new ArrayList<ILangExpression>();
+ List<ILangExpression> exprs = new ArrayList<>();
exprs.add(expr);
return toString(exprs);
}
@@ -87,7 +91,7 @@
public static String toString(List<ILangExpression> exprs) throws AsterixException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PrintWriter output = new PrintWriter(bos);
- QueryPrintVisitor visitor = astPrintVisitor.createLangVisitor(output);
+ QueryPrintVisitor visitor = astPrintVisitorFactory.createLangVisitor(output);
for (ILangExpression expr : exprs) {
expr.accept(visitor, 0);
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppFormatPrintUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppFormatPrintUtil.java
index 41760f5..ff0a8e1 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppFormatPrintUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppFormatPrintUtil.java
@@ -30,6 +30,10 @@
public class SqlppFormatPrintUtil {
+ private SqlppFormatPrintUtil() {
+
+ }
+
/**
* Prints the formatted output of an ILangExpression.
*
@@ -67,7 +71,7 @@
* @throws AsterixException
*/
public static String toString(ILangExpression expr) throws AsterixException {
- List<ILangExpression> exprs = new ArrayList<ILangExpression>();
+ List<ILangExpression> exprs = new ArrayList<>();
exprs.add(expr);
return toString(exprs);
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
index 122bde3..4a8c69d 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
@@ -40,8 +40,8 @@
public static Expression rewriteExpressionUsingGroupVariable(VariableExpr groupVar,
Collection<VariableExpr> targetVarList, Collection<VariableExpr> allVisableVars, ILangExpression expr,
LangRewritingContext context) throws AsterixException {
- SqlppGroupBySugarVisitor visitor = new SqlppGroupBySugarVisitor(context, groupVar, targetVarList,
- allVisableVars);
+ SqlppGroupBySugarVisitor visitor =
+ new SqlppGroupBySugarVisitor(context, groupVar, targetVarList, allVisableVars);
return expr.accept(visitor, null);
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
index 559183e..6c48c64 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
@@ -139,7 +139,7 @@
GroupbyClause gbyClause = null;
List<LetClause> gbyLetClauses = new ArrayList<>();
HavingClause havingClause = null;
- SelectClause selectCluase = null;
+ SelectClause selectCluase;
// Traverses the select block in the order of "from", "let"s, "where",
// "group by", "let"s, "having" and "select".
if (selectBlock.hasFromClause()) {
@@ -201,7 +201,7 @@
@Override
public SelectSetOperation visit(SelectSetOperation selectSetOperation, Void arg) throws AsterixException {
SetOperationInput leftInput = selectSetOperation.getLeftInput();
- SetOperationInput newLeftInput = null;
+ SetOperationInput newLeftInput;
if (leftInput.selectBlock()) {
newLeftInput = new SetOperationInput((SelectBlock) leftInput.accept(this, arg), null);
} else {
@@ -209,12 +209,12 @@
}
List<SetOperationRight> rightInputs = new ArrayList<>();
for (SetOperationRight right : selectSetOperation.getRightInputs()) {
- SetOperationInput newRightInput = null;
+ SetOperationInput newRightInput;
SetOperationInput setOpRightInput = right.getSetOperationRightInput();
if (setOpRightInput.selectBlock()) {
- newRightInput = new SetOperationInput((SelectBlock) leftInput.accept(this, arg), null);
+ newRightInput = new SetOperationInput((SelectBlock) setOpRightInput.accept(this, arg), null);
} else {
- newRightInput = new SetOperationInput(null, (SelectExpression) leftInput.accept(this, arg));
+ newRightInput = new SetOperationInput(null, (SelectExpression) setOpRightInput.accept(this, arg));
}
rightInputs.add(new SetOperationRight(right.getSetOpType(), right.isSetSemantics(), newRightInput));
}
@@ -244,7 +244,7 @@
@Override
public OrderbyClause visit(OrderbyClause oc, Void arg) throws AsterixException {
- List<Expression> newOrderbyList = new ArrayList<Expression>();
+ List<Expression> newOrderbyList = new ArrayList<>();
for (Expression orderExpr : oc.getOrderbyList()) {
newOrderbyList.add((Expression) orderExpr.accept(this, arg));
}
@@ -259,11 +259,13 @@
VariableExpr groupVarExpr = null;
List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<>();
for (GbyVariableExpressionPair gbyVarExpr : gc.getGbyPairList()) {
- gbyPairList.add(new GbyVariableExpressionPair((VariableExpr) gbyVarExpr.getVar().accept(this, arg),
+ VariableExpr var = gbyVarExpr.getVar();
+ gbyPairList.add(new GbyVariableExpressionPair(var == null ? null : (VariableExpr) var.accept(this, arg),
(Expression) gbyVarExpr.getExpr().accept(this, arg)));
}
for (GbyVariableExpressionPair gbyVarExpr : gc.getDecorPairList()) {
- decorPairList.add(new GbyVariableExpressionPair((VariableExpr) gbyVarExpr.getVar().accept(this, arg),
+ VariableExpr var = gbyVarExpr.getVar();
+ decorPairList.add(new GbyVariableExpressionPair(var == null ? null : (VariableExpr) var.accept(this, arg),
(Expression) gbyVarExpr.getExpr().accept(this, arg)));
}
for (VariableExpr withVar : gc.getWithVarList()) {
@@ -295,7 +297,7 @@
@Override
public SelectExpression visit(SelectExpression selectExpression, Void arg) throws AsterixException {
List<LetClause> lets = new ArrayList<>();
- SelectSetOperation select = null;
+ SelectSetOperation select;
OrderbyClause orderby = null;
LimitClause limit = null;
@@ -332,7 +334,7 @@
@Override
public ListConstructor visit(ListConstructor lc, Void arg) throws AsterixException {
- List<Expression> newExprList = new ArrayList<Expression>();
+ List<Expression> newExprList = new ArrayList<>();
for (Expression expr : lc.getExprList()) {
newExprList.add((Expression) expr.accept(this, arg));
}
@@ -352,7 +354,7 @@
@Override
public OperatorExpr visit(OperatorExpr operatorExpr, Void arg) throws AsterixException {
- List<Expression> newExprList = new ArrayList<Expression>();
+ List<Expression> newExprList = new ArrayList<>();
for (Expression expr : operatorExpr.getExprList()) {
newExprList.add((Expression) expr.accept(this, arg));
}
@@ -382,7 +384,7 @@
@Override
public CallExpr visit(CallExpr callExpr, Void arg) throws AsterixException {
- List<Expression> newExprList = new ArrayList<Expression>();
+ List<Expression> newExprList = new ArrayList<>();
for (Expression expr : callExpr.getExprList()) {
newExprList.add((Expression) expr.accept(this, arg));
}
@@ -391,8 +393,8 @@
@Override
public VariableExpr visit(VariableExpr varExpr, Void arg) throws AsterixException {
- VariableExpr clonedVar = new VariableExpr(
- new VarIdentifier(varExpr.getVar().getValue(), varExpr.getVar().getId()));
+ VariableExpr clonedVar =
+ new VariableExpr(new VarIdentifier(varExpr.getVar().getValue(), varExpr.getVar().getId()));
clonedVar.setIsNewVar(varExpr.getIsNewVar());
clonedVar.setNamedValueAccess(varExpr.namedValueAccess());
return clonedVar;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
index 8ec2b04..445c835 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
@@ -68,7 +68,7 @@
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(FromClause fromClause,
VariableSubstitutionEnvironment env) throws AsterixException {
VariableSubstitutionEnvironment currentEnv = new VariableSubstitutionEnvironment(env);
- List<FromTerm> newFromTerms = new ArrayList<FromTerm>();
+ List<FromTerm> newFromTerms = new ArrayList<>();
for (FromTerm fromTerm : fromClause.getFromTerms()) {
Pair<ILangExpression, VariableSubstitutionEnvironment> p = fromTerm.accept(this, currentEnv);
newFromTerms.add((FromTerm) p.first);
@@ -76,7 +76,7 @@
// therefore we propagate the substitution environment.
currentEnv = p.second;
}
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(new FromClause(newFromTerms), currentEnv);
+ return new Pair<>(new FromClause(newFromTerms), currentEnv);
}
@Override
@@ -87,7 +87,7 @@
VariableExpr newLeftPosVar = fromTerm.hasPositionalVariable()
? generateNewVariable(context, fromTerm.getPositionalVariable()) : null;
Expression newLeftExpr = (Expression) visitUnnesBindingExpression(fromTerm.getLeftExpression(), env).first;
- List<AbstractBinaryCorrelateClause> newCorrelateClauses = new ArrayList<AbstractBinaryCorrelateClause>();
+ List<AbstractBinaryCorrelateClause> newCorrelateClauses = new ArrayList<>();
VariableSubstitutionEnvironment currentEnv = new VariableSubstitutionEnvironment(env);
currentEnv.removeSubstitution(newLeftVar);
@@ -108,8 +108,7 @@
newCorrelateClauses.add((AbstractBinaryCorrelateClause) correlateClause.accept(this, env).first);
}
}
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(
- new FromTerm(newLeftExpr, newLeftVar, newLeftPosVar, newCorrelateClauses), currentEnv);
+ return new Pair<>(new FromTerm(newLeftExpr, newLeftVar, newLeftPosVar, newCorrelateClauses), currentEnv);
}
@Override
@@ -132,9 +131,9 @@
// The condition can refer to the newRightVar and newRightPosVar.
Expression conditionExpr = (Expression) joinClause.getConditionExpression().accept(this, currentEnv).first;
- JoinClause newJoinClause = new JoinClause(joinClause.getJoinType(), newRightExpr, newRightVar, newRightPosVar,
- conditionExpr);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newJoinClause, currentEnv);
+ JoinClause newJoinClause =
+ new JoinClause(joinClause.getJoinType(), newRightExpr, newRightVar, newRightPosVar, conditionExpr);
+ return new Pair<>(newJoinClause, currentEnv);
}
@Override
@@ -157,9 +156,9 @@
// The condition can refer to the newRightVar and newRightPosVar.
Expression conditionExpr = (Expression) nestClause.getConditionExpression().accept(this, currentEnv).first;
- NestClause newJoinClause = new NestClause(nestClause.getJoinType(), rightExpr, newRightVar, newRightPosVar,
- conditionExpr);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newJoinClause, currentEnv);
+ NestClause newJoinClause =
+ new NestClause(nestClause.getJoinType(), rightExpr, newRightVar, newRightPosVar, conditionExpr);
+ return new Pair<>(newJoinClause, currentEnv);
}
@Override
@@ -180,9 +179,9 @@
currentEnv.removeSubstitution(newRightPosVar);
}
// The condition can refer to the newRightVar and newRightPosVar.
- UnnestClause newJoinClause = new UnnestClause(unnestClause.getJoinType(), rightExpr, newRightVar,
- newRightPosVar);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newJoinClause, currentEnv);
+ UnnestClause newJoinClause =
+ new UnnestClause(unnestClause.getJoinType(), rightExpr, newRightVar, newRightPosVar);
+ return new Pair<>(newJoinClause, currentEnv);
}
@Override
@@ -190,20 +189,20 @@
VariableSubstitutionEnvironment env) throws AsterixException {
Projection newProjection = new Projection((Expression) projection.getExpression().accept(this, env).first,
projection.getName(), projection.star(), projection.exprStar());
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newProjection, env);
+ return new Pair<>(newProjection, env);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(SelectBlock selectBlock,
VariableSubstitutionEnvironment env) throws AsterixException {
Pair<ILangExpression, VariableSubstitutionEnvironment> newFrom = null;
- Pair<ILangExpression, VariableSubstitutionEnvironment> newLet = null;
+ Pair<ILangExpression, VariableSubstitutionEnvironment> newLet;
Pair<ILangExpression, VariableSubstitutionEnvironment> newWhere = null;
Pair<ILangExpression, VariableSubstitutionEnvironment> newGroupby = null;
Pair<ILangExpression, VariableSubstitutionEnvironment> newHaving = null;
- Pair<ILangExpression, VariableSubstitutionEnvironment> newSelect = null;
- List<LetClause> newLetClauses = new ArrayList<LetClause>();
- List<LetClause> newLetClausesAfterGby = new ArrayList<LetClause>();
+ Pair<ILangExpression, VariableSubstitutionEnvironment> newSelect;
+ List<LetClause> newLetClauses = new ArrayList<>();
+ List<LetClause> newLetClausesAfterGby = new ArrayList<>();
VariableSubstitutionEnvironment currentEnv = new VariableSubstitutionEnvironment(env);
if (selectBlock.hasFromClause()) {
@@ -243,12 +242,12 @@
newSelect = selectBlock.getSelectClause().accept(this, currentEnv);
currentEnv = newSelect.second;
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(
- new SelectBlock((SelectClause) newSelect.first, newFrom == null ? null : (FromClause) newFrom.first,
- newLetClauses, newWhere == null ? null : (WhereClause) newWhere.first,
- newGroupby == null ? null : (GroupbyClause) newGroupby.first, newLetClausesAfterGby,
- newHaving == null ? null : (HavingClause) newHaving.first),
- currentEnv);
+ FromClause fromClause = newFrom == null ? null : (FromClause) newFrom.first;
+ WhereClause whereClause = newWhere == null ? null : (WhereClause) newWhere.first;
+ GroupbyClause groupbyClause = newGroupby == null ? null : (GroupbyClause) newGroupby.first;
+ HavingClause havingClause = newHaving == null ? null : (HavingClause) newHaving.first;
+ return new Pair<>(new SelectBlock((SelectClause) newSelect.first, fromClause, newLetClauses, whereClause,
+ groupbyClause, newLetClausesAfterGby, havingClause), currentEnv);
}
@Override
@@ -256,42 +255,41 @@
VariableSubstitutionEnvironment env) throws AsterixException {
boolean distinct = selectClause.distinct();
if (selectClause.selectElement()) {
- Pair<ILangExpression, VariableSubstitutionEnvironment> newSelectElement = selectClause.getSelectElement()
- .accept(this, env);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(
- new SelectClause((SelectElement) newSelectElement.first, null, distinct), newSelectElement.second);
+ Pair<ILangExpression, VariableSubstitutionEnvironment> newSelectElement =
+ selectClause.getSelectElement().accept(this, env);
+ return new Pair<>(new SelectClause((SelectElement) newSelectElement.first, null, distinct),
+ newSelectElement.second);
} else {
- Pair<ILangExpression, VariableSubstitutionEnvironment> newSelectRegular = selectClause.getSelectRegular()
- .accept(this, env);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(
- new SelectClause(null, (SelectRegular) newSelectRegular.first, distinct), newSelectRegular.second);
+ Pair<ILangExpression, VariableSubstitutionEnvironment> newSelectRegular =
+ selectClause.getSelectRegular().accept(this, env);
+ return new Pair<>(new SelectClause(null, (SelectRegular) newSelectRegular.first, distinct),
+ newSelectRegular.second);
}
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(SelectElement selectElement,
VariableSubstitutionEnvironment env) throws AsterixException {
- Pair<ILangExpression, VariableSubstitutionEnvironment> newExpr = selectElement.getExpression().accept(this,
- env);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(new SelectElement((Expression) newExpr.first),
- newExpr.second);
+ Pair<ILangExpression, VariableSubstitutionEnvironment> newExpr =
+ selectElement.getExpression().accept(this, env);
+ return new Pair<>(new SelectElement((Expression) newExpr.first), newExpr.second);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(SelectRegular selectRegular,
VariableSubstitutionEnvironment env) throws AsterixException {
- List<Projection> newProjections = new ArrayList<Projection>();
+ List<Projection> newProjections = new ArrayList<>();
for (Projection projection : selectRegular.getProjections()) {
newProjections.add((Projection) projection.accept(this, env).first);
}
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(new SelectRegular(newProjections), env);
+ return new Pair<>(new SelectRegular(newProjections), env);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(SelectSetOperation selectSetOperation,
VariableSubstitutionEnvironment env) throws AsterixException {
SetOperationInput leftInput = selectSetOperation.getLeftInput();
- SetOperationInput newLeftInput = null;
+ SetOperationInput newLeftInput;
// Sets the left input.
if (leftInput.selectBlock()) {
@@ -303,13 +301,13 @@
}
// Sets the right input
- List<SetOperationRight> newRightInputs = new ArrayList<SetOperationRight>();
+ List<SetOperationRight> newRightInputs = new ArrayList<>();
for (SetOperationRight right : selectSetOperation.getRightInputs()) {
- SetOperationInput newRightInput = null;
+ SetOperationInput newRightInput;
SetOperationInput rightInput = right.getSetOperationRightInput();
if (rightInput.selectBlock()) {
- Pair<ILangExpression, VariableSubstitutionEnvironment> p = rightInput.getSelectBlock().accept(this,
- env);
+ Pair<ILangExpression, VariableSubstitutionEnvironment> p =
+ rightInput.getSelectBlock().accept(this, env);
newRightInput = new SetOperationInput((SelectBlock) p.first, null);
} else {
Pair<ILangExpression, VariableSubstitutionEnvironment> p = rightInput.getSubquery().accept(this, env);
@@ -318,20 +316,20 @@
newRightInputs.add(new SetOperationRight(right.getSetOpType(), right.isSetSemantics(), newRightInput));
}
SelectSetOperation newSelectSetOperation = new SelectSetOperation(newLeftInput, newRightInputs);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newSelectSetOperation, env);
+ return new Pair<>(newSelectSetOperation, env);
}
@Override
public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(SelectExpression selectExpression,
VariableSubstitutionEnvironment env) throws AsterixException {
boolean subquery = selectExpression.isSubquery();
- List<LetClause> newLetList = new ArrayList<LetClause>();
- SelectSetOperation newSelectSetOperation = null;
+ List<LetClause> newLetList = new ArrayList<>();
+ SelectSetOperation newSelectSetOperation;
OrderbyClause newOrderbyClause = null;
LimitClause newLimitClause = null;
VariableSubstitutionEnvironment currentEnv = env;
- Pair<ILangExpression, VariableSubstitutionEnvironment> p = null;
+ Pair<ILangExpression, VariableSubstitutionEnvironment> p;
if (selectExpression.hasLetClauses()) {
for (LetClause letClause : selectExpression.getLetList()) {
p = letClause.accept(this, currentEnv);
@@ -355,7 +353,7 @@
newLimitClause = (LimitClause) p.first;
currentEnv = p.second;
}
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(
+ return new Pair<>(
new SelectExpression(newLetList, newSelectSetOperation, newOrderbyClause, newLimitClause, subquery),
currentEnv);
}
@@ -365,7 +363,7 @@
VariableSubstitutionEnvironment env) throws AsterixException {
Pair<ILangExpression, VariableSubstitutionEnvironment> p = havingClause.getFilterExpression().accept(this, env);
HavingClause newHavingClause = new HavingClause((Expression) p.first);
- return new Pair<ILangExpression, VariableSubstitutionEnvironment>(newHavingClause, p.second);
+ return new Pair<>(newHavingClause, p.second);
}
@Override
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
index e03d711..2dca532 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
@@ -127,7 +127,10 @@
@Override
public Void visit(Projection projection, Integer step) throws AsterixException {
projection.getExpression().accept(this, step);
- out.print(" as " + projection.getName());
+ String name = projection.getName();
+ if (name != null) {
+ out.print(" as " + name);
+ }
return null;
}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
new file mode 100644
index 0000000..af160bf
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppSubstituteExpressionsVisitor.java
@@ -0,0 +1,272 @@
+/*
+ * 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.visitor;
+
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.clause.GroupbyClause;
+import org.apache.asterix.lang.common.clause.LetClause;
+import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
+import org.apache.asterix.lang.common.rewrites.ExpressionSubstitutionEnvironment;
+import org.apache.asterix.lang.common.visitor.SubstituteExpressionVisitor;
+import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
+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.JoinClause;
+import org.apache.asterix.lang.sqlpp.clause.NestClause;
+import org.apache.asterix.lang.sqlpp.clause.Projection;
+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.SelectRegular;
+import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
+import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
+import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
+import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
+import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
+import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+
+public class SqlppSubstituteExpressionsVisitor extends SubstituteExpressionVisitor
+ implements ISqlppVisitor<Expression, ExpressionSubstitutionEnvironment> {
+
+ public SqlppSubstituteExpressionsVisitor() {
+ super(SqlppRewriteUtil::deepCopy);
+ }
+
+ @Override
+ public Expression visit(GroupbyClause gc, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ for (GbyVariableExpressionPair pair : gc.getGbyPairList()) {
+ pair.setExpr(pair.getExpr().accept(this, env));
+ }
+ // Forces from binding variables to exit their scopes, i.e.,
+ // one can still replace from binding variables.
+ env.pop();
+ for (GbyVariableExpressionPair pair : gc.getGbyPairList()) {
+ env.disableVariable(pair.getVar());
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(FromClause fromClause, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ // Marks the states before the from clause, and a consequent
+ // group-by clause will reset env to the state.
+ env.mark();
+ for (FromTerm fromTerm : fromClause.getFromTerms()) {
+ fromTerm.accept(this, env);
+ // From terms are correlated and thus we mask binding variables after
+ // visiting each individual from term.
+ env.disableVariable(fromTerm.getLeftVariable());
+ if (fromTerm.hasPositionalVariable()) {
+ env.disableVariable(fromTerm.getLeftVariable());
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(FromTerm fromTerm, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ fromTerm.setLeftExpression(fromTerm.getLeftExpression().accept(this, env));
+ if (fromTerm.hasCorrelateClauses()) {
+ for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) {
+ correlateClause.accept(this, env);
+ }
+ // correlate clauses are independent and thus we mask their binding variables
+ // after visiting them.
+ for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) {
+ env.disableVariable(correlateClause.getRightVariable());
+ if (correlateClause.hasPositionalVariable()) {
+ env.disableVariable(correlateClause.getPositionalVariable());
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(JoinClause joinClause, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ joinClause.setRightExpression(joinClause.getRightExpression().accept(this, env));
+ // Condition expressions can see the join binding variables, thus we have to mask them for replacement.
+ env.disableVariable(joinClause.getRightVariable());
+ if (joinClause.hasPositionalVariable()) {
+ env.disableVariable(joinClause.getPositionalVariable());
+ }
+ joinClause.setConditionExpression(joinClause.getConditionExpression().accept(this, env));
+ // Re-enable them.
+ env.enableVariable(joinClause.getRightVariable());
+ if (joinClause.hasPositionalVariable()) {
+ env.enableVariable(joinClause.getPositionalVariable());
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(NestClause nestClause, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ nestClause.setRightExpression(nestClause.getRightExpression().accept(this, env));
+ // Condition expressions can see the join binding variables, thus we have to mask them for replacement.
+ env.disableVariable(nestClause.getRightVariable());
+ if (nestClause.hasPositionalVariable()) {
+ env.disableVariable(nestClause.getPositionalVariable());
+ }
+ nestClause.setConditionExpression(nestClause.getConditionExpression().accept(this, env));
+ // Re-enable them.
+ env.enableVariable(nestClause.getRightVariable());
+ if (nestClause.hasPositionalVariable()) {
+ env.enableVariable(nestClause.getPositionalVariable());
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(Projection projection, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ if (!projection.star()) {
+ projection.setExpression(projection.getExpression().accept(this, env));
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(SelectBlock selectBlock, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ // Traverses the select block in the order of "from", "let"s, "where",
+ // "group by", "let"s, "having" and "select".
+ if (selectBlock.hasFromClause()) {
+ selectBlock.getFromClause().accept(this, env);
+ }
+ if (selectBlock.hasLetClauses()) {
+ List<LetClause> letList = selectBlock.getLetList();
+ for (LetClause letClause : letList) {
+ letClause.accept(this, env);
+ }
+ }
+ if (selectBlock.hasWhereClause()) {
+ selectBlock.getWhereClause().accept(this, env);
+ }
+ if (selectBlock.hasGroupbyClause()) {
+ selectBlock.getGroupbyClause().accept(this, env);
+ }
+ if (selectBlock.hasLetClausesAfterGroupby()) {
+ List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
+ for (LetClause letClauseAfterGby : letListAfterGby) {
+ letClauseAfterGby.accept(this, env);
+ }
+ }
+ if (selectBlock.hasHavingClause()) {
+ selectBlock.getHavingClause().accept(this, env);
+ }
+ selectBlock.getSelectClause().accept(this, env);
+ return null;
+ }
+
+ @Override
+ public Expression visit(SelectClause selectClause, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ if (selectClause.selectElement()) {
+ selectClause.getSelectElement().accept(this, env);
+ } else {
+ selectClause.getSelectRegular().accept(this, env);
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(SelectElement selectElement, ExpressionSubstitutionEnvironment env)
+ throws AsterixException {
+ selectElement.setExpression(selectElement.getExpression().accept(this, env));
+ return null;
+ }
+
+ @Override
+ public Expression visit(SelectRegular selectRegular, ExpressionSubstitutionEnvironment env)
+ throws AsterixException {
+ for (Projection projection : selectRegular.getProjections()) {
+ projection.accept(this, env);
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(SelectSetOperation selectSetOperation, ExpressionSubstitutionEnvironment env)
+ throws AsterixException {
+ selectSetOperation.getLeftInput().accept(this, env);
+ for (SetOperationRight right : selectSetOperation.getRightInputs()) {
+ right.getSetOperationRightInput().accept(this, env);
+ }
+ return null;
+ }
+
+ @Override
+ public Expression visit(SelectExpression selectExpression, ExpressionSubstitutionEnvironment env)
+ throws AsterixException {
+ // Backups the current states of env and the end of this method will reset to the returned depth.
+ int depth = env.mark();
+ // visit let list
+ if (selectExpression.hasLetClauses()) {
+ for (LetClause letClause : selectExpression.getLetList()) {
+ letClause.accept(this, env);
+ }
+ }
+
+ // visit the main select.
+ selectExpression.getSelectSetOperation().accept(this, env);
+
+ // visit order by.
+ if (selectExpression.hasOrderby()) {
+ selectExpression.getOrderbyClause().accept(this, env);
+ }
+
+ // visit limit
+ if (selectExpression.hasLimit()) {
+ selectExpression.getLimitClause().accept(this, env);
+ }
+
+ // re-enable the replacements all of all binding variables in the current scope.
+ if (selectExpression.hasLetClauses()) {
+ for (LetClause letClause : selectExpression.getLetList()) {
+ env.enableVariable(letClause.getVarExpr());
+ }
+ }
+ // Restores the states of env to be the same as the beginning .
+ env.reset(depth);
+ return selectExpression;
+ }
+
+ @Override
+ public Expression visit(UnnestClause unnestClause, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ unnestClause.setRightExpression(unnestClause.getRightExpression().accept(this, env));
+ return null;
+ }
+
+ @Override
+ public Expression visit(HavingClause havingClause, ExpressionSubstitutionEnvironment env) throws AsterixException {
+ havingClause.setFilterExpression(havingClause.getFilterExpression().accept(this, env));
+ return null;
+ }
+
+ @Override
+ public Expression visit(IndependentSubquery independentSubquery, ExpressionSubstitutionEnvironment env)
+ throws AsterixException {
+ independentSubquery.setExpr(independentSubquery.getExpr().accept(this, env));
+ return null;
+ }
+
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
index dfb15b0..4fbb697 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppExpressionScopingVisitor.java
@@ -60,8 +60,8 @@
public class AbstractSqlppExpressionScopingVisitor extends AbstractSqlppSimpleExpressionVisitor {
- protected final FunctionSignature resolveFunction = new FunctionSignature(MetadataConstants.METADATA_DATAVERSE_NAME,
- "resolve", FunctionIdentifier.VARARGS);
+ protected final FunctionSignature resolveFunction =
+ new FunctionSignature(MetadataConstants.METADATA_DATAVERSE_NAME, "resolve", FunctionIdentifier.VARARGS);
protected final ScopeChecker scopeChecker = new ScopeChecker();
protected final LangRewritingContext context;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
index 2098156..9fd5a6e 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
@@ -250,9 +250,7 @@
// visit order by
if (selectExpression.hasOrderby()) {
- for (Expression orderExpr : selectExpression.getOrderbyClause().getOrderbyList()) {
- orderExpr.accept(this, selectExpression);
- }
+ selectExpression.getOrderbyClause().accept(this, selectExpression);
}
// visit limit
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index dff69ab..06b067e 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -2376,7 +2376,10 @@
)
{
if(!star && name == null){
- name = SqlppVariableUtil.toUserDefinedName(ExpressionToVariableUtil.getGeneratedIdentifier(expr));
+ String generatedColumnIdentifier = ExpressionToVariableUtil.getGeneratedIdentifier(expr, false);
+ if(generatedColumnIdentifier != null){
+ name = SqlppVariableUtil.toUserDefinedName(generatedColumnIdentifier);
+ }
}
return new Projection(expr, name, star, exprStar);
}
@@ -2422,7 +2425,7 @@
)*
{
if(leftVar==null){
- leftVar = ExpressionToVariableUtil.getGeneratedVariable(leftExpr);
+ leftVar = ExpressionToVariableUtil.getGeneratedVariable(leftExpr, true);
}
return new FromTerm(leftExpr, leftVar, posVar, correlateClauses);
}
@@ -2439,7 +2442,7 @@
<JOIN> rightExpr = Expression() ((<AS>)? rightVar = Variable())? (<AT> posVar = Variable())? <ON> conditionExpr = Expression()
{
if(rightVar==null){
- rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr);
+ rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
}
return new JoinClause(joinType, rightExpr, rightVar, posVar, conditionExpr);
}
@@ -2455,7 +2458,7 @@
(<UNNEST>|<CORRELATE>|<FLATTEN>) rightExpr = Expression() ((<AS>)? rightVar = Variable()) (<AT> posVar = Variable())?
{
if(rightVar==null){
- rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr);
+ rightVar = ExpressionToVariableUtil.getGeneratedVariable(rightExpr, true);
}
return new UnnestClause(joinType, rightExpr, rightVar, posVar);
}
@@ -2586,7 +2589,7 @@
)?
{
if(var==null){
- var = ExpressionToVariableUtil.getGeneratedVariable(expr);
+ var = ExpressionToVariableUtil.getGeneratedVariable(expr, false);
}
GbyVariableExpressionPair pair1 = new GbyVariableExpressionPair(var, expr);
vePairList.add(pair1);
@@ -2601,7 +2604,7 @@
)?
{
if(var==null){
- var = ExpressionToVariableUtil.getGeneratedVariable(expr);
+ var = ExpressionToVariableUtil.getGeneratedVariable(expr, false);
}
GbyVariableExpressionPair pair2 = new GbyVariableExpressionPair(var, expr);
vePairList.add(pair2);