You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@asterixdb.apache.org by "Dmitry Lychagin (Code Review)" <do...@asterixdb.incubator.apache.org> on 2019/01/15 21:16:59 UTC

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Dmitry Lychagin has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/3118

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................

[ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Consolidate LET and WHERE clauses into a single list in the SelectBlock

Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
---
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
M asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java
M asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
M asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
M asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
M asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast
M asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast
M asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectBlock.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SubstituteGroupbyExpressionWithVariableVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
30 files changed, 299 insertions(+), 380 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/18/3118/1

diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
index fef765c..b39136f 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
@@ -32,6 +32,7 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Clause.ClauseType;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.Expression.Kind;
@@ -252,24 +253,18 @@
         if (selectBlock.hasFromClause()) {
             currentOpRef = new MutableObject<>(selectBlock.getFromClause().accept(this, currentOpRef).first);
         }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                currentOpRef = new MutableObject<>(letClause.accept(this, currentOpRef).first);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                currentOpRef = new MutableObject<>(letWhereClause.accept(this, currentOpRef).first);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            currentOpRef = new MutableObject<>(selectBlock.getWhereClause().accept(this, currentOpRef).first);
         }
         if (selectBlock.hasGroupbyClause()) {
             currentOpRef = new MutableObject<>(selectBlock.getGroupbyClause().accept(this, currentOpRef).first);
         }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                currentOpRef = new MutableObject<>(letClause.accept(this, currentOpRef).first);
+        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+            for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                currentOpRef = new MutableObject<>(letHavingClause.accept(this, currentOpRef).first);
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            currentOpRef = new MutableObject<>(selectBlock.getHavingClause().accept(this, currentOpRef).first);
         }
         return processSelectClause(selectBlock, currentOpRef);
     }
@@ -771,16 +766,16 @@
             } else if (projection.star()) {
                 if (selectBlock.hasGroupbyClause()) {
                     getGroupBindings(selectBlock.getGroupbyClause(), fieldBindings, fieldNames);
-                    if (selectBlock.hasLetClausesAfterGroupby()) {
-                        getLetBindings(selectBlock.getLetListAfterGroupby(), fieldBindings, fieldNames);
+                    if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                        getLetBindings(selectBlock.getLetHavingListAfterGroupby(), fieldBindings, fieldNames);
                     }
                 } else if (selectBlock.hasFromClause()) {
                     getFromBindings(selectBlock.getFromClause(), fieldBindings, fieldNames);
-                    if (selectBlock.hasLetClauses()) {
-                        getLetBindings(selectBlock.getLetList(), fieldBindings, fieldNames);
+                    if (selectBlock.hasLetWhereClauses()) {
+                        getLetBindings(selectBlock.getLetWhereList(), fieldBindings, fieldNames);
                     }
-                } else if (selectBlock.hasLetClauses()) {
-                    getLetBindings(selectBlock.getLetList(), fieldBindings, fieldNames);
+                } else if (selectBlock.hasLetWhereClauses()) {
+                    getLetBindings(selectBlock.getLetWhereList(), fieldBindings, fieldNames);
                 }
             } else if (projection.hasName()) {
                 fieldBindings.add(getFieldBinding(projection, fieldNames));
@@ -841,10 +836,13 @@
     }
 
     // Generates all field bindings according to the let clause.
-    private void getLetBindings(List<LetClause> letClauses, List<FieldBinding> outFieldBindings,
+    private void getLetBindings(List<AbstractClause> clauses, List<FieldBinding> outFieldBindings,
             Set<String> outFieldNames) throws CompilationException {
-        for (LetClause letClause : letClauses) {
-            outFieldBindings.add(getFieldBinding(letClause.getVarExpr(), outFieldNames));
+        for (AbstractClause clause : clauses) {
+            if (clause.getClauseType() == ClauseType.LET_CLAUSE) {
+                LetClause letClause = (LetClause) clause;
+                outFieldBindings.add(getFieldBinding(letClause.getVarExpr(), outFieldNames));
+            }
         }
     }
 
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java
index d22e929..194358a 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java
@@ -225,7 +225,8 @@
         // Constructing select clause
         SelectElement selectElement = new SelectElement(previousVarExpr);
         SelectClause selectClause = new SelectClause(selectElement, null, false);
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, whereClause, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause,
+                whereClause != null ? Collections.singletonList(whereClause) : null, null, null);
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         SelectExpression body = new SelectExpression(null, selectSetOperation, null, null, true);
         Query query = new Query(false, true, body, 0);
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
index c51b5e0..c9e4bcc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
@@ -17,7 +17,7 @@
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                         -- STREAM_PROJECT  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- HYBRID_HASH_JOIN [$$42][$$32]  |PARTITIONED|
+                            -- HYBRID_HASH_JOIN [$$42][$$31]  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- STREAM_SELECT  |PARTITIONED|
@@ -25,7 +25,7 @@
                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- ASSIGN  |PARTITIONED|
                                     -- STREAM_PROJECT  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
index a60462d..97d8e3b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
@@ -21,7 +21,7 @@
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- HYBRID_HASH_JOIN [$$42][$$32]  |PARTITIONED|
+                                    -- HYBRID_HASH_JOIN [$$42][$$31]  |PARTITIONED|
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- STREAM_PROJECT  |PARTITIONED|
                                           -- STREAM_SELECT  |PARTITIONED|
@@ -29,7 +29,7 @@
                                               -- DATASOURCE_SCAN  |PARTITIONED|
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                      -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+                                      -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
                                         -- STREAM_PROJECT  |PARTITIONED|
                                           -- ASSIGN  |PARTITIONED|
                                             -- STREAM_PROJECT  |PARTITIONED|
@@ -56,7 +56,7 @@
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- STREAM_PROJECT  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- HYBRID_HASH_JOIN [$$42][$$32]  |PARTITIONED|
+                                            -- HYBRID_HASH_JOIN [$$42][$$31]  |PARTITIONED|
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                 -- STREAM_PROJECT  |PARTITIONED|
                                                   -- STREAM_SELECT  |PARTITIONED|
@@ -64,7 +64,7 @@
                                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                              -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+                                              -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
                                                 -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- STREAM_PROJECT  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
index 6a74727..ef29016 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
@@ -3,10 +3,10 @@
     -- STREAM_LIMIT  |UNPARTITIONED|
       -- STREAM_PROJECT  |PARTITIONED|
         -- ASSIGN  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$119(ASC) ]  |PARTITIONED|
+          -- SORT_MERGE_EXCHANGE [$$120(ASC) ]  |PARTITIONED|
             -- STREAM_LIMIT  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [topK: 100] [$$119(ASC)]  |PARTITIONED|
+                -- STABLE_SORT [topK: 100] [$$120(ASC)]  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- STREAM_SELECT  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast
index a11de35..9a16c6c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast
@@ -96,6 +96,12 @@
  AT
 Variable [ Name=$p ]
 ]
+Where
+  OperatorExpr [
+    Variable [ Name=$p ]
+    <
+    LiteralExpr [LONG] [4]
+  ]
 Let Variable [ Name=#1 ]
   :=
   FieldAccessor [
@@ -113,12 +119,6 @@
   FieldAccessor [
     Variable [ Name=$j ]
     Field=l_orderkey
-  ]
-Where
-  OperatorExpr [
-    Variable [ Name=$p ]
-    <
-    LiteralExpr [LONG] [4]
   ]
 Orderby
   Variable [ Name=#1 ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast
index 92376cd..0da93150 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast
@@ -18,27 +18,6 @@
   ]
   AS Variable [ Name=$user ]
 ]
-Let Variable [ Name=#1 ]
-  :=
-  FieldAccessor [
-    Variable [ Name=$user ]
-    Field=name
-  ]
-Let Variable [ Name=#2 ]
-  :=
-  FieldAccessor [
-    Variable [ Name=$user ]
-    Field=alias
-  ]
-Let Variable [ Name=#3 ]
-  :=
-  FunctionCall TinySocial.substring@2[
-    FieldAccessor [
-      Variable [ Name=$message ]
-      Field=message
-    ]
-    LiteralExpr [LONG] [29]
-  ]
 Where
   OperatorExpr [
     OperatorExpr [
@@ -71,6 +50,27 @@
       LiteralExpr [LONG] [11]
     ]
   ]
+Let Variable [ Name=#1 ]
+  :=
+  FieldAccessor [
+    Variable [ Name=$user ]
+    Field=name
+  ]
+Let Variable [ Name=#2 ]
+  :=
+  FieldAccessor [
+    Variable [ Name=$user ]
+    Field=alias
+  ]
+Let Variable [ Name=#3 ]
+  :=
+  FunctionCall TinySocial.substring@2[
+    FieldAccessor [
+      Variable [ Name=$message ]
+      Field=message
+    ]
+    LiteralExpr [LONG] [29]
+  ]
 Orderby
   Variable [ Name=#1 ]
   ASC
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast
index 92376cd..0da93150 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast
@@ -18,27 +18,6 @@
   ]
   AS Variable [ Name=$user ]
 ]
-Let Variable [ Name=#1 ]
-  :=
-  FieldAccessor [
-    Variable [ Name=$user ]
-    Field=name
-  ]
-Let Variable [ Name=#2 ]
-  :=
-  FieldAccessor [
-    Variable [ Name=$user ]
-    Field=alias
-  ]
-Let Variable [ Name=#3 ]
-  :=
-  FunctionCall TinySocial.substring@2[
-    FieldAccessor [
-      Variable [ Name=$message ]
-      Field=message
-    ]
-    LiteralExpr [LONG] [29]
-  ]
 Where
   OperatorExpr [
     OperatorExpr [
@@ -71,6 +50,27 @@
       LiteralExpr [LONG] [11]
     ]
   ]
+Let Variable [ Name=#1 ]
+  :=
+  FieldAccessor [
+    Variable [ Name=$user ]
+    Field=name
+  ]
+Let Variable [ Name=#2 ]
+  :=
+  FieldAccessor [
+    Variable [ Name=$user ]
+    Field=alias
+  ]
+Let Variable [ Name=#3 ]
+  :=
+  FunctionCall TinySocial.substring@2[
+    FieldAccessor [
+      Variable [ Name=$message ]
+      Field=message
+    ]
+    LiteralExpr [LONG] [29]
+  ]
 Orderby
   Variable [ Name=#1 ]
   ASC
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 83b03ba..c934e32 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
@@ -26,8 +26,6 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
-import org.apache.asterix.lang.common.clause.LetClause;
-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;
 
@@ -35,25 +33,20 @@
 
     private SelectClause selectClause;
     private FromClause fromClause;
-    private List<LetClause> letClauses = new ArrayList<>();
-    private WhereClause whereClause;
+    private final List<AbstractClause> letWhereClauses = new ArrayList<>();
     private GroupbyClause groupbyClause;
-    private List<LetClause> letClausesAfterGby = new ArrayList<>();
-    private HavingClause havingClause;
+    private final List<AbstractClause> letHavingClausesAfterGby = new ArrayList<>();
 
-    public SelectBlock(SelectClause selectClause, FromClause fromClause, List<LetClause> letClauses,
-            WhereClause whereClause, GroupbyClause groupbyClause, List<LetClause> letClausesAfterGby,
-            HavingClause havingClause) {
+    public SelectBlock(SelectClause selectClause, FromClause fromClause, List<AbstractClause> letWhereClauses,
+            GroupbyClause groupbyClause, List<AbstractClause> letHavingClausesAfterGby) {
         this.selectClause = selectClause;
         this.fromClause = fromClause;
-        if (letClauses != null) {
-            this.letClauses.addAll(letClauses);
+        if (letWhereClauses != null) {
+            this.letWhereClauses.addAll(letWhereClauses);
         }
-        this.whereClause = whereClause;
         this.groupbyClause = groupbyClause;
-        this.havingClause = havingClause;
-        if (letClausesAfterGby != null) {
-            this.letClausesAfterGby.addAll(letClausesAfterGby);
+        if (letHavingClausesAfterGby != null) {
+            this.letHavingClausesAfterGby.addAll(letHavingClausesAfterGby);
         }
     }
 
@@ -75,48 +68,32 @@
         return fromClause;
     }
 
-    public List<LetClause> getLetList() {
-        return letClauses;
-    }
-
-    public WhereClause getWhereClause() {
-        return whereClause;
+    public List<AbstractClause> getLetWhereList() {
+        return letWhereClauses;
     }
 
     public GroupbyClause getGroupbyClause() {
         return groupbyClause;
     }
 
-    public HavingClause getHavingClause() {
-        return havingClause;
+    public List<AbstractClause> getLetHavingListAfterGroupby() {
+        return letHavingClausesAfterGby;
     }
 
     public boolean hasFromClause() {
         return fromClause != null;
     }
 
-    public boolean hasLetClauses() {
-        return !letClauses.isEmpty();
-    }
-
-    public boolean hasWhereClause() {
-        return whereClause != null;
+    public boolean hasLetWhereClauses() {
+        return !letWhereClauses.isEmpty();
     }
 
     public boolean hasGroupbyClause() {
         return groupbyClause != null;
     }
 
-    public boolean hasLetClausesAfterGroupby() {
-        return !letClausesAfterGby.isEmpty();
-    }
-
-    public List<LetClause> getLetListAfterGroupby() {
-        return letClausesAfterGby;
-    }
-
-    public boolean hasHavingClause() {
-        return havingClause != null;
+    public boolean hasLetHavingClausesAfterGroupby() {
+        return !letHavingClausesAfterGby.isEmpty();
     }
 
     public void setGroupbyClause(GroupbyClause groupbyClause) {
@@ -125,8 +102,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(fromClause, groupbyClause, havingClause, letClauses, letClausesAfterGby, selectClause,
-                whereClause);
+        return Objects.hash(fromClause, groupbyClause, letWhereClauses, letHavingClausesAfterGby, selectClause);
     }
 
     @Override
@@ -140,9 +116,9 @@
         }
         SelectBlock target = (SelectBlock) object;
         return Objects.equals(fromClause, target.fromClause) && Objects.equals(groupbyClause, target.groupbyClause)
-                && Objects.equals(havingClause, target.havingClause) && Objects.equals(letClauses, target.letClauses)
-                && Objects.equals(letClausesAfterGby, target.letClausesAfterGby)
-                && Objects.equals(selectClause, target.selectClause) && Objects.equals(whereClause, target.whereClause);
+                && Objects.equals(letWhereClauses, target.letWhereClauses)
+                && Objects.equals(letHavingClausesAfterGby, target.letHavingClausesAfterGby)
+                && Objects.equals(selectClause, target.selectClause);
     }
 
     @Override
@@ -150,22 +126,16 @@
         StringBuilder sb = new StringBuilder();
         sb.append(selectClause);
         if (hasFromClause()) {
-            sb.append(" " + fromClause);
+            sb.append(' ').append(fromClause);
         }
-        if (hasLetClauses()) {
-            sb.append(" " + letClauses);
-        }
-        if (hasWhereClause()) {
-            sb.append(" " + whereClause);
+        if (hasLetWhereClauses()) {
+            sb.append(' ').append(letWhereClauses);
         }
         if (hasGroupbyClause()) {
-            sb.append(" " + groupbyClause);
+            sb.append(' ').append(groupbyClause);
         }
-        if (hasLetClausesAfterGroupby()) {
-            sb.append(" " + letClausesAfterGby);
-        }
-        if (hasHavingClause()) {
-            sb.append(" " + havingClause);
+        if (hasLetHavingClausesAfterGroupby()) {
+            sb.append(' ').append(letHavingClausesAfterGby);
         }
         return sb.toString();
     }
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 942fc88..35de051 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
@@ -24,6 +24,7 @@
 import java.util.Set;
 import java.util.HashSet;
 
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
@@ -364,24 +365,18 @@
             if (selectBlock.hasFromClause()) {
                 selectBlock.getFromClause().accept(this, arg);
             }
-            if (selectBlock.hasLetClauses()) {
-                for (LetClause letClause : selectBlock.getLetList()) {
-                    letClause.accept(this, arg);
+            if (selectBlock.hasLetWhereClauses()) {
+                for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                    letWhereClause.accept(this, arg);
                 }
-            }
-            if (selectBlock.hasWhereClause()) {
-                selectBlock.getWhereClause().accept(this, arg);
             }
             if (selectBlock.hasGroupbyClause()) {
                 selectBlock.getGroupbyClause().accept(this, arg);
             }
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                    letClause.accept(this, arg);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(this, arg);
                 }
-            }
-            if (selectBlock.hasHavingClause()) {
-                selectBlock.getHavingClause().accept(this, arg);
             }
             selectBlock.getSelectClause().accept(this, arg);
             return null;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java
index b78cd9c..3606b12 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java
@@ -26,6 +26,7 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.LetClause;
@@ -64,54 +65,47 @@
                 handleUnsupportedClause(clause, extractionList);
             }
         }
-        List<LetClause> letList = selectBlock.getLetList();
-        if (selectBlock.hasLetClauses()) {
-            visitLetClauses(letList, extractionList, arg);
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, arg);
-            introduceLetClauses(extractionList, letList);
+        List<AbstractClause> letWhereList = selectBlock.getLetWhereList();
+        if (!letWhereList.isEmpty()) {
+            visitLetWhereClauses(letWhereList, extractionList, arg);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, arg);
-            introduceLetClauses(extractionList, letList);
+            introduceLetClauses(extractionList, letWhereList);
         }
-        List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            visitLetClauses(letListAfterGby, extractionList, arg);
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, arg);
-            introduceLetClauses(extractionList, letListAfterGby);
+        List<AbstractClause> letHavingListAfterGby = selectBlock.getLetHavingListAfterGroupby();
+        if (!letHavingListAfterGby.isEmpty()) {
+            visitLetWhereClauses(letHavingListAfterGby, extractionList, arg);
         }
         selectBlock.getSelectClause().accept(this, arg);
-        introduceLetClauses(extractionList, selectBlock.hasGroupbyClause() ? letListAfterGby : letList);
+        introduceLetClauses(extractionList, selectBlock.hasGroupbyClause() ? letHavingListAfterGby : letWhereList);
 
         stack.pop();
         return null;
     }
 
-    private void visitLetClauses(List<LetClause> letList, List<Pair<Expression, VarIdentifier>> extractionList,
-            ILangExpression arg) throws CompilationException {
-        List<LetClause> newLetList = new ArrayList<>(letList.size());
-        for (LetClause letClause : letList) {
-            letClause.accept(this, arg);
-            introduceLetClauses(extractionList, newLetList);
-            newLetList.add(letClause);
+    private void visitLetWhereClauses(List<AbstractClause> clauseList,
+            List<Pair<Expression, VarIdentifier>> extractionList, ILangExpression arg) throws CompilationException {
+        List<AbstractClause> newClauseList = new ArrayList<>(clauseList.size());
+        for (AbstractClause letWhereClause : clauseList) {
+            letWhereClause.accept(this, arg);
+            introduceLetClauses(extractionList, newClauseList);
+            newClauseList.add(letWhereClause);
         }
-        if (newLetList.size() > letList.size()) {
-            letList.clear();
-            letList.addAll(newLetList);
+        if (newClauseList.size() > clauseList.size()) {
+            clauseList.clear();
+            clauseList.addAll(newClauseList);
         }
     }
 
-    private void introduceLetClauses(List<Pair<Expression, VarIdentifier>> fromBindingList, List<LetClause> toLetList) {
+    private void introduceLetClauses(List<Pair<Expression, VarIdentifier>> fromBindingList,
+            List<AbstractClause> toLetWhereList) {
         for (Pair<Expression, VarIdentifier> p : fromBindingList) {
             Expression bindExpr = p.first;
             VarIdentifier var = p.second;
             VariableExpr varExpr = new VariableExpr(var);
             varExpr.setSourceLocation(bindExpr.getSourceLocation());
-            toLetList.add(new LetClause(varExpr, bindExpr));
+            toLetWhereList.add(new LetClause(varExpr, bindExpr));
             context.addExcludedForFieldAccessVar(var);
         }
         fromBindingList.clear();
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 a270530..f68688f 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
@@ -18,17 +18,15 @@
  */
 package org.apache.asterix.lang.sqlpp.rewrites.visitor;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.lang.common.base.AbstractClause;
 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;
@@ -77,15 +75,16 @@
         // Removes all FROM/LET binding variables
         if (selectBlock.hasGroupbyClause()) {
             map.keySet().removeAll(SqlppVariableUtil.getBindingVariables(selectBlock.getGroupbyClause()));
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                map.keySet().removeAll(SqlppVariableUtil.getBindingVariables(selectBlock.getLetListAfterGroupby()));
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                map.keySet().removeAll(
+                        SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetHavingListAfterGroupby()));
             }
         } else {
             if (selectBlock.hasFromClause()) {
                 map.keySet().removeAll(SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause()));
             }
-            if (selectBlock.hasLetClauses()) {
-                map.keySet().removeAll(SqlppVariableUtil.getBindingVariables(selectBlock.getLetList()));
+            if (selectBlock.hasLetWhereClauses()) {
+                map.keySet().removeAll(SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetWhereList()));
             }
         }
 
@@ -163,8 +162,8 @@
     private void introduceLetClauses(Map<Expression, VarIdentifier> letVarMap,
             Map<Expression, ColumnAliasBinding> aliasBindingMap, SelectBlock selectBlock) throws CompilationException {
 
-        List<LetClause> targetLetClauses =
-                selectBlock.hasGroupbyClause() ? selectBlock.getLetListAfterGroupby() : selectBlock.getLetList();
+        List<AbstractClause> targetLetClauses = selectBlock.hasGroupbyClause()
+                ? selectBlock.getLetHavingListAfterGroupby() : selectBlock.getLetWhereList();
 
         for (Map.Entry<Expression, VarIdentifier> me : letVarMap.entrySet()) {
             Expression columnAliasVarExpr = me.getKey();
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java
index f0a0f87..dd02dbe 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java
@@ -95,7 +95,7 @@
         newFromClause.setSourceLocation(sourceLoc);
         SelectClause selectClause = new SelectClause(new SelectElement(newBindingVar), null, false);
         selectClause.setSourceLocation(sourceLoc);
-        SelectBlock selectBlock = new SelectBlock(selectClause, newFromClause, null, null, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, newFromClause, null, null, null);
         selectBlock.setSourceLocation(sourceLoc);
         SelectSetOperation newSelectSetOperation =
                 new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java
index 2be752d..6e14e74 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java
@@ -144,7 +144,7 @@
         selectClause.setSourceLocation(sourceLoc);
 
         // Construct the select expression.
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null);
         selectBlock.setSourceLocation(sourceLoc);
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         selectSetOperation.setSourceLocation(sourceLoc);
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java
index efcd7e0..180f80c 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java
@@ -119,7 +119,7 @@
         selectClause.setSourceLocation(sourceLoc);
 
         // Construct the select expression.
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null);
         selectBlock.setSourceLocation(sourceLoc);
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         selectSetOperation.setSourceLocation(sourceLoc);
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
index 1c55f99..ad1268f 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
@@ -19,6 +19,7 @@
 package org.apache.asterix.lang.sqlpp.rewrites.visitor;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -84,20 +85,15 @@
 
     @Override
     public Expression visit(SelectBlock selectBlock, ILangExpression arg) throws CompilationException {
-        // Traverses the select block in the order of "from", "let"s, "where",
-        // "group by", "let"s, "having" and "select".
+        // Traverses the select block in the order of "from", "let/where"s, "group by", "let/having"s and "select".
         FromClause fromClause = selectBlock.getFromClause();
         if (selectBlock.hasFromClause()) {
             fromClause.accept(this, arg);
         }
-        if (selectBlock.hasLetClauses()) {
-            List<LetClause> letList = selectBlock.getLetList();
-            for (LetClause letClause : letList) {
-                letClause.accept(this, arg);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                letWhereClause.accept(this, arg);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, arg);
         }
         if (selectBlock.hasGroupbyClause()) {
             Set<VariableExpr> visibleVarsPreGroupByScope = scopeChecker.getCurrentScope().getLiveVariables();
@@ -109,29 +105,30 @@
             VariableExpr groupVar = groupbyClause.getGroupVar();
             Map<Expression, Identifier> groupFieldVars = getGroupFieldVariables(groupbyClause);
 
-            Collection<VariableExpr> freeVariablesInGbyLets = new HashSet<>();
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-                for (LetClause letClauseAfterGby : letListAfterGby) {
-                    letClauseAfterGby.accept(this, arg);
-                    // Rewrites each let clause after the group-by.
-                    rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, letClauseAfterGby,
-                            visibleVarsPreGroupByScope);
-                    Collection<VariableExpr> freeVariablesInLet =
-                            SqlppVariableUtil.getFreeVariables(letClauseAfterGby.getBindingExpr());
-                    freeVariablesInLet.removeAll(visibleVarsInCurrentScope);
-                    freeVariablesInGbyLets.addAll(freeVariablesInLet);
-                    visibleVarsInCurrentScope.add(letClauseAfterGby.getVarExpr());
-                }
-            }
-
             Collection<VariableExpr> freeVariables = new HashSet<>();
-            if (selectBlock.hasHavingClause()) {
-                // Rewrites the having clause.
-                HavingClause havingClause = selectBlock.getHavingClause();
-                havingClause.accept(this, arg);
-                rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, havingClause, visibleVarsPreGroupByScope);
-                freeVariables.addAll(SqlppVariableUtil.getFreeVariables(havingClause));
+            Collection<VariableExpr> freeVariablesInGbyLets = new HashSet<>();
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(this, arg);
+                    // Rewrites each let/having clause after the group-by.
+                    rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, letHavingClause,
+                            visibleVarsPreGroupByScope);
+                    switch (letHavingClause.getClauseType()) {
+                        case LET_CLAUSE:
+                            LetClause letClause = (LetClause) letHavingClause;
+                            Collection<VariableExpr> freeVariablesInClause =
+                                    SqlppVariableUtil.getFreeVariables(letClause.getBindingExpr());
+                            freeVariablesInClause.removeAll(visibleVarsInCurrentScope);
+                            freeVariablesInGbyLets.addAll(freeVariablesInClause);
+                            visibleVarsInCurrentScope.add(letClause.getVarExpr());
+                            break;
+                        case HAVING_CLAUSE:
+                            freeVariables.addAll(SqlppVariableUtil.getFreeVariables(letHavingClause));
+                            break;
+                        default:
+                            throw new IllegalStateException(String.valueOf(letHavingClause.getClauseType()));
+                    }
+                }
             }
 
             SelectExpression parentSelectExpression = (SelectExpression) arg;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
index 84aee71..4fe2699 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
@@ -123,7 +123,7 @@
     private List<Pair<Expression, Identifier>> createGroupFieldList(SelectBlock selectBlock) {
         List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<>();
         addToFieldList(groupFieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause()));
-        addToFieldList(groupFieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getLetList()));
+        addToFieldList(groupFieldList, SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetWhereList()));
         return groupFieldList;
     }
 
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
index 1fd4ff7..2ff6b63 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
@@ -23,6 +23,7 @@
 import java.util.Map;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.IRewriterFactory;
 import org.apache.asterix.lang.common.clause.LetClause;
@@ -135,24 +136,18 @@
         if (selectBlock.hasFromClause()) {
             changed |= selectBlock.getFromClause().accept(this, funcs);
         }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                changed |= letClause.accept(this, funcs);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                changed |= letWhereClause.accept(this, funcs);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            changed |= selectBlock.getWhereClause().accept(this, funcs);
         }
         if (selectBlock.hasGroupbyClause()) {
             changed |= selectBlock.getGroupbyClause().accept(this, funcs);
         }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                changed |= letClause.accept(this, funcs);
+        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+            for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                changed |= letHavingClause.accept(this, funcs);
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            changed |= selectBlock.getHavingClause().accept(this, funcs);
         }
         changed |= selectBlock.getSelectClause().accept(this, funcs);
         return changed;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java
index 0b2d2cf..910552a 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java
@@ -125,9 +125,10 @@
         List<Pair<Expression, Identifier>> fieldList = new ArrayList<>();
         if (selectBlock != null) {
             addToFieldList(fieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause()));
-            addToFieldList(fieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getLetList()));
+            addToFieldList(fieldList, SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetWhereList()));
             addToFieldList(fieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getGroupbyClause()));
-            addToFieldList(fieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getLetListAfterGroupby()));
+            addToFieldList(fieldList,
+                    SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetHavingListAfterGroupby()));
         }
         return fieldList;
     }
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
index 9e937d0..13f1128 100644
--- 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
@@ -24,10 +24,10 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.AbstractClause;
 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.clause.LetClause;
 import org.apache.asterix.lang.common.expression.CallExpr;
 import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
@@ -65,13 +65,10 @@
             SubstituteGroupbyExpressionVisitor visitor = new SubstituteGroupbyExpressionVisitor(context, map);
 
             // Rewrites LET/HAVING/SELECT clauses.
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                    letClause.accept(visitor, arg);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(visitor, arg);
                 }
-            }
-            if (selectBlock.hasHavingClause()) {
-                selectBlock.getHavingClause().accept(visitor, arg);
             }
             selectBlock.getSelectClause().accept(visitor, arg);
             SelectExpression selectExpression = (SelectExpression) arg;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
index f71ae5b..a186cba 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
@@ -27,6 +27,8 @@
 import java.util.Set;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
+import org.apache.asterix.lang.common.base.Clause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -176,13 +178,16 @@
         return bindingVars;
     }
 
-    public static List<VariableExpr> getBindingVariables(List<LetClause> letClauses) {
+    public static List<VariableExpr> getLetBindingVariables(List<? extends AbstractClause> clauses) {
         List<VariableExpr> bindingVars = new ArrayList<>();
-        if (letClauses == null || letClauses.isEmpty()) {
+        if (clauses == null || clauses.isEmpty()) {
             return bindingVars;
         }
-        for (LetClause letClause : letClauses) {
-            bindingVars.add(letClause.getVarExpr());
+        for (AbstractClause clause : clauses) {
+            if (clause.getClauseType() == Clause.ClauseType.LET_CLAUSE) {
+                LetClause letClause = (LetClause) clause;
+                bindingVars.add(letClause.getVarExpr());
+            }
         }
         return bindingVars;
     }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
index c816d05..b9954a5 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
@@ -116,10 +116,9 @@
 
     @Override
     public Boolean visit(SelectBlock selectBlock, ILangExpression arg) throws CompilationException {
-        boolean hasSubquery = visit(selectBlock.getFromClause(), arg) || visit(selectBlock.getGroupbyClause(), arg)
-                || visit(selectBlock.getHavingClause(), arg) || visit(selectBlock.getWhereClause(), arg);
-        return hasSubquery || visit(selectBlock.getSelectClause(), arg) || visitExprList(selectBlock.getLetList(), arg)
-                || visitExprList(selectBlock.getLetListAfterGroupby(), arg);
+        return visit(selectBlock.getFromClause(), arg) || visit(selectBlock.getGroupbyClause(), arg)
+                || visit(selectBlock.getSelectClause(), arg) || visitExprList(selectBlock.getLetWhereList(), arg)
+                || visitExprList(selectBlock.getLetHavingListAfterGroupby(), arg);
     }
 
     @Override
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 ed92bfd..96409d4 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
@@ -25,6 +25,7 @@
 import java.util.Map.Entry;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -152,41 +153,31 @@
     @Override
     public SelectBlock visit(SelectBlock selectBlock, Void arg) throws CompilationException {
         FromClause fromClause = null;
-        List<LetClause> letClauses = new ArrayList<>();
-        WhereClause whereClause = null;
+        List<AbstractClause> letWhereClauses = new ArrayList<>();
         GroupbyClause gbyClause = null;
-        List<LetClause> gbyLetClauses = new ArrayList<>();
-        HavingClause havingClause = null;
-        SelectClause selectCluase;
-        // Traverses the select block in the order of "from", "let"s, "where",
-        // "group by", "let"s, "having" and "select".
+        List<AbstractClause> gbyLetHavingClauses = new ArrayList<>();
+        SelectClause selectClause;
+        // Traverses the select block in the order of "from", "let/where"s, "group by", "let/having"s, and "select".
         if (selectBlock.hasFromClause()) {
             fromClause = (FromClause) selectBlock.getFromClause().accept(this, arg);
         }
-        if (selectBlock.hasLetClauses()) {
-            List<LetClause> letList = selectBlock.getLetList();
-            for (LetClause letClause : letList) {
-                letClauses.add((LetClause) letClause.accept(this, arg));
+        if (selectBlock.hasLetWhereClauses()) {
+            List<AbstractClause> letWhereList = selectBlock.getLetWhereList();
+            for (AbstractClause letWhereClause : letWhereList) {
+                letWhereClauses.add((AbstractClause) letWhereClause.accept(this, arg));
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            whereClause = (WhereClause) selectBlock.getWhereClause().accept(this, arg);
         }
         if (selectBlock.hasGroupbyClause()) {
             gbyClause = (GroupbyClause) selectBlock.getGroupbyClause().accept(this, arg);
         }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-            for (LetClause letClauseAfterGby : letListAfterGby) {
-                gbyLetClauses.add((LetClause) letClauseAfterGby.accept(this, arg));
+        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+            List<AbstractClause> letHavingListAfterGby = selectBlock.getLetHavingListAfterGroupby();
+            for (AbstractClause letHavingClauseAfterGby : letHavingListAfterGby) {
+                gbyLetHavingClauses.add((AbstractClause) letHavingClauseAfterGby.accept(this, arg));
             }
         }
-        if (selectBlock.hasHavingClause()) {
-            havingClause = (HavingClause) selectBlock.getHavingClause().accept(this, arg);
-        }
-        selectCluase = (SelectClause) selectBlock.getSelectClause().accept(this, arg);
-        SelectBlock copy = new SelectBlock(selectCluase, fromClause, letClauses, whereClause, gbyClause, gbyLetClauses,
-                havingClause);
+        selectClause = (SelectClause) selectBlock.getSelectClause().accept(this, arg);
+        SelectBlock copy = new SelectBlock(selectClause, fromClause, letWhereClauses, gbyClause, gbyLetHavingClauses);
         copy.setSourceLocation(selectBlock.getSourceLocation());
         return copy;
     }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
index b61f4e6..d662988 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
@@ -23,6 +23,7 @@
 import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Clause.ClauseType;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -155,16 +156,16 @@
     public Void visit(SelectBlock selectBlock, Collection<VariableExpr> freeVars) throws CompilationException {
         Collection<VariableExpr> selectFreeVars = new HashSet<>();
         Collection<VariableExpr> fromFreeVars = new HashSet<>();
-        Collection<VariableExpr> letsFreeVars = new HashSet<>();
-        Collection<VariableExpr> whereFreeVars = new HashSet<>();
+        Collection<VariableExpr> letWheresFreeVars = new HashSet<>();
         Collection<VariableExpr> gbyFreeVars = new HashSet<>();
-        Collection<VariableExpr> gbyLetsFreeVars = new HashSet<>();
+        Collection<VariableExpr> gbyLetHavingsFreeVars = new HashSet<>();
 
         Collection<VariableExpr> fromBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause());
-        Collection<VariableExpr> letsBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getLetList());
+        Collection<VariableExpr> letsBindingVars =
+                SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetWhereList());
         Collection<VariableExpr> gbyBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getGroupbyClause());
         Collection<VariableExpr> gbyLetsBindingVars =
-                SqlppVariableUtil.getBindingVariables(selectBlock.getLetListAfterGroupby());
+                SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetHavingListAfterGroupby());
 
         selectBlock.getSelectClause().accept(this, selectFreeVars);
         // Removes group-by, from, let, and gby-let binding vars.
@@ -174,30 +175,20 @@
         if (selectBlock.hasFromClause()) {
             selectBlock.getFromClause().accept(this, fromFreeVars);
         }
-        if (selectBlock.hasLetClauses()) {
-            visitLetClauses(selectBlock.getLetList(), letsFreeVars);
-            letsFreeVars.removeAll(fromBindingVars);
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, whereFreeVars);
-            whereFreeVars.removeAll(fromBindingVars);
-            whereFreeVars.removeAll(letsBindingVars);
+        if (selectBlock.hasLetWhereClauses()) {
+            visitLetWhereClauses(selectBlock.getLetWhereList(), letWheresFreeVars);
+            letWheresFreeVars.removeAll(fromBindingVars);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, gbyFreeVars);
             // Remove group-by and let binding vars.
             gbyFreeVars.removeAll(fromBindingVars);
             gbyFreeVars.removeAll(letsBindingVars);
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                visitLetClauses(selectBlock.getLetListAfterGroupby(), gbyLetsFreeVars);
-                gbyLetsFreeVars.removeAll(fromBindingVars);
-                gbyLetsFreeVars.removeAll(letsBindingVars);
-                gbyLetsFreeVars.removeAll(gbyBindingVars);
-            }
-            if (selectBlock.hasHavingClause()) {
-                selectBlock.getHavingClause().accept(this, selectFreeVars);
-                removeAllBindingVarsInSelectBlock(selectFreeVars, fromBindingVars, letsBindingVars, gbyBindingVars,
-                        gbyLetsBindingVars);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                visitLetWhereClauses(selectBlock.getLetHavingListAfterGroupby(), gbyLetHavingsFreeVars);
+                gbyLetHavingsFreeVars.removeAll(fromBindingVars);
+                gbyLetHavingsFreeVars.removeAll(letsBindingVars);
+                gbyLetHavingsFreeVars.removeAll(gbyBindingVars);
             }
         }
 
@@ -209,10 +200,9 @@
         // Adds all free vars.
         freeVars.addAll(selectFreeVars);
         freeVars.addAll(fromFreeVars);
-        freeVars.addAll(letsFreeVars);
-        freeVars.addAll(whereFreeVars);
+        freeVars.addAll(letWheresFreeVars);
         freeVars.addAll(gbyFreeVars);
-        freeVars.addAll(gbyLetsFreeVars);
+        freeVars.addAll(gbyLetHavingsFreeVars);
         return null;
     }
 
@@ -322,7 +312,7 @@
             throws CompilationException {
         Collection<VariableExpr> letsFreeVars = new HashSet<>();
         Collection<VariableExpr> selectFreeVars = new HashSet<>();
-        visitLetClauses(selectExpression.getLetList(), letsFreeVars);
+        visitLetWhereClauses(selectExpression.getLetList(), letsFreeVars);
 
         // visit order by
         if (selectExpression.hasOrderby()) {
@@ -340,7 +330,7 @@
         selectExpression.getSelectSetOperation().accept(this, selectFreeVars);
 
         // Removed let binding variables.
-        selectFreeVars.removeAll(SqlppVariableUtil.getBindingVariables(selectExpression.getLetList()));
+        selectFreeVars.removeAll(SqlppVariableUtil.getLetBindingVariables(selectExpression.getLetList()));
         freeVars.addAll(letsFreeVars);
         freeVars.addAll(selectFreeVars);
         return null;
@@ -471,22 +461,24 @@
         return null;
     }
 
-    private void visitLetClauses(List<LetClause> letClauses, Collection<VariableExpr> freeVars)
+    private void visitLetWhereClauses(List<? extends AbstractClause> clauseList, Collection<VariableExpr> freeVars)
             throws CompilationException {
-        if (letClauses == null || letClauses.isEmpty()) {
+        if (clauseList == null || clauseList.isEmpty()) {
             return;
         }
         Collection<VariableExpr> bindingVars = new HashSet<>();
-        for (LetClause letClause : letClauses) {
-            Collection<VariableExpr> letFreeVars = new HashSet<>();
-            letClause.accept(this, letFreeVars);
+        for (AbstractClause clause : clauseList) {
+            Collection<VariableExpr> clauseFreeVars = new HashSet<>();
+            clause.accept(this, clauseFreeVars);
 
             // Removes previous binding variables.
-            letFreeVars.removeAll(bindingVars);
-            freeVars.addAll(letFreeVars);
+            clauseFreeVars.removeAll(bindingVars);
+            freeVars.addAll(clauseFreeVars);
 
             // Adds let binding variables into the binding variable collection.
-            bindingVars.add(letClause.getVarExpr());
+            if (clause.getClauseType() == ClauseType.LET_CLAUSE) {
+                bindingVars.add(((LetClause) clause).getVarExpr());
+            }
         }
     }
 
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
index d906a82..da3c5df 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
@@ -24,6 +24,7 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
 import org.apache.asterix.lang.common.clause.LetClause;
@@ -141,24 +142,18 @@
         if (selectBlock.hasFromClause()) {
             selectBlock.getFromClause().accept(this, step);
         }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                letClause.accept(this, step);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                letWhereClause.accept(this, step);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, step);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, step);
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                    letClause.accept(this, step);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(this, step);
                 }
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, step);
         }
         return null;
     }
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 39e1883..dc3e565 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
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Clause.ClauseType;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
@@ -29,7 +30,6 @@
 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.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
@@ -215,13 +215,12 @@
     public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(SelectBlock selectBlock,
             VariableSubstitutionEnvironment env) throws CompilationException {
         Pair<ILangExpression, VariableSubstitutionEnvironment> newFrom = null;
-        Pair<ILangExpression, VariableSubstitutionEnvironment> newLet;
-        Pair<ILangExpression, VariableSubstitutionEnvironment> newWhere = null;
+        Pair<ILangExpression, VariableSubstitutionEnvironment> newLetWhere;
         Pair<ILangExpression, VariableSubstitutionEnvironment> newGroupby = null;
-        Pair<ILangExpression, VariableSubstitutionEnvironment> newHaving = null;
+        Pair<ILangExpression, VariableSubstitutionEnvironment> newLetHaving;
         Pair<ILangExpression, VariableSubstitutionEnvironment> newSelect;
-        List<LetClause> newLetClauses = new ArrayList<>();
-        List<LetClause> newLetClausesAfterGby = new ArrayList<>();
+        List<AbstractClause> newLetWhereClauses = new ArrayList<>();
+        List<AbstractClause> newLetHavingClausesAfterGby = new ArrayList<>();
         VariableSubstitutionEnvironment currentEnv = new VariableSubstitutionEnvironment(env);
 
         if (selectBlock.hasFromClause()) {
@@ -229,44 +228,32 @@
             currentEnv = newFrom.second;
         }
 
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                newLet = letClause.accept(this, currentEnv);
-                currentEnv = newLet.second;
-                newLetClauses.add((LetClause) newLet.first);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                newLetWhere = letWhereClause.accept(this, currentEnv);
+                currentEnv = newLetWhere.second;
+                newLetWhereClauses.add((AbstractClause) newLetWhere.first);
             }
-        }
-
-        if (selectBlock.hasWhereClause()) {
-            newWhere = selectBlock.getWhereClause().accept(this, currentEnv);
-            currentEnv = newWhere.second;
         }
 
         if (selectBlock.hasGroupbyClause()) {
             newGroupby = selectBlock.getGroupbyClause().accept(this, currentEnv);
             currentEnv = newGroupby.second;
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClauseAfterGby : selectBlock.getLetListAfterGroupby()) {
-                    newLet = letClauseAfterGby.accept(this, currentEnv);
-                    currentEnv = newLet.second;
-                    newLetClausesAfterGby.add(letClauseAfterGby);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClauseAfterGby : selectBlock.getLetHavingListAfterGroupby()) {
+                    newLetHaving = letHavingClauseAfterGby.accept(this, currentEnv);
+                    currentEnv = newLetHaving.second;
+                    newLetHavingClausesAfterGby.add((AbstractClause) newLetHaving.first);
                 }
             }
-        }
-
-        if (selectBlock.hasHavingClause()) {
-            newHaving = selectBlock.getHavingClause().accept(this, currentEnv);
-            currentEnv = newHaving.second;
         }
 
         newSelect = selectBlock.getSelectClause().accept(this, currentEnv);
         currentEnv = newSelect.second;
         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;
-        SelectBlock newSelectBlock = new SelectBlock((SelectClause) newSelect.first, fromClause, newLetClauses,
-                whereClause, groupbyClause, newLetClausesAfterGby, havingClause);
+        SelectBlock newSelectBlock = new SelectBlock((SelectClause) newSelect.first, fromClause, newLetWhereClauses,
+                groupbyClause, newLetHavingClausesAfterGby);
         newSelectBlock.setSourceLocation(selectBlock.getSourceLocation());
         return new Pair<>(newSelectBlock, currentEnv);
     }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
index bf57184..8cfd04b 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
@@ -86,7 +86,8 @@
         selectClause.setSourceLocation(deleteStmt.getSourceLocation());
 
         // Construct the select expression.
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, whereClause, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause,
+                whereClause != null ? Collections.singletonList(whereClause) : null, null, null);
         selectBlock.setSourceLocation(var.getSourceLocation());
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         selectSetOperation.setSourceLocation(var.getSourceLocation());
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 1ee3004..e541363 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
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
 import org.apache.asterix.lang.common.clause.LetClause;
@@ -144,24 +145,18 @@
         if (selectBlock.hasFromClause()) {
             selectBlock.getFromClause().accept(this, step);
         }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                letClause.accept(this, step);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                letWhereClause.accept(this, step);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, step);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, step);
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                    letClause.accept(this, step);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(this, step);
                 }
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, step);
         }
         return null;
     }
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 d1092b3..345d5a5 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
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -120,31 +121,22 @@
 
     @Override
     public Expression visit(SelectBlock selectBlock, ILangExpression arg) throws CompilationException {
-        // Traverses the select block in the order of "from", "let"s, "where",
-        // "group by", "let"s, "having" and "select".
+        // Traverses the select block in the order of "from", "let/where"s, "group by", "let/having"s and "select".
         if (selectBlock.hasFromClause()) {
             selectBlock.getFromClause().accept(this, arg);
         }
-        if (selectBlock.hasLetClauses()) {
-            List<LetClause> letList = selectBlock.getLetList();
-            for (LetClause letClause : letList) {
-                letClause.accept(this, arg);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause clause : selectBlock.getLetWhereList()) {
+                clause.accept(this, arg);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, arg);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, arg);
         }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-            for (LetClause letClauseAfterGby : letListAfterGby) {
-                letClauseAfterGby.accept(this, arg);
+        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+            for (AbstractClause clause : selectBlock.getLetHavingListAfterGroupby()) {
+                clause.accept(this, arg);
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, arg);
         }
         selectBlock.getSelectClause().accept(this, arg);
         return null;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 4078389..45ba7c3 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -67,6 +67,7 @@
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionConstants;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.AbstractLangExpression;
 import org.apache.asterix.lang.common.base.AbstractStatement;
 import org.apache.asterix.lang.common.base.Expression;
@@ -3034,9 +3035,11 @@
   FromClause fromClause = null;
   List<LetClause> fromLetClauses = null;
   WhereClause whereClause = null;
+  List<AbstractClause> fromLetWhereClauses = new ArrayList<AbstractClause>();
   GroupbyClause groupbyClause = null;
   List<LetClause> gbyLetClauses = null;
   HavingClause havingClause = null;
+  List<AbstractClause> gbyLetHavingClauses = new ArrayList<AbstractClause>();
   SourceLocation startSrcLoc = null;
 }
 {
@@ -3076,8 +3079,20 @@
      selectClause = SelectClause()
   )
   {
-    SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetClauses, whereClause, groupbyClause,
-      gbyLetClauses, havingClause);
+    if (fromLetClauses != null) {
+      fromLetWhereClauses.addAll(fromLetClauses);
+    }
+    if (whereClause != null) {
+      fromLetWhereClauses.add(whereClause);
+    }
+    if (gbyLetClauses != null) {
+      gbyLetHavingClauses.addAll(gbyLetClauses);
+    }
+    if (havingClause != null) {
+      gbyLetHavingClauses.add(havingClause);
+    }
+    SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetWhereClauses, groupbyClause,
+      gbyLetHavingClauses);
     selectBlock.setSourceLocation(startSrcLoc);
     return selectBlock;
   }

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1: -Integration-Tests

Integration Tests Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-integration-tests/7773/

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Dmitry Lychagin (Code Review)" <do...@asterixdb.incubator.apache.org>.
Dmitry Lychagin has submitted this change and it was merged.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


[ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Consolidate LET and WHERE clauses into a single list in the SelectBlock

Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Reviewed-on: https://asterix-gerrit.ics.uci.edu/3118
Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <je...@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
Reviewed-by: Ali Alsuliman <al...@gmail.com>
---
M asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
M asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java
M asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
M asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
M asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
M asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast
M asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast
M asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/clause/SelectBlock.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SubstituteGroupbyExpressionWithVariableVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/base/AbstractSqlppSimpleExpressionVisitor.java
M asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
30 files changed, 299 insertions(+), 380 deletions(-)

Approvals:
  Ali Alsuliman: Looks good to me, approved
  Jenkins: Verified; ; Verified

Objections:
  Anon. E. Moose #1000171: Violations found
  Jenkins: Violations found



diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
index fef765c..b39136f 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/SqlppExpressionToPlanTranslator.java
@@ -32,6 +32,7 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Clause.ClauseType;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.Expression.Kind;
@@ -252,24 +253,18 @@
         if (selectBlock.hasFromClause()) {
             currentOpRef = new MutableObject<>(selectBlock.getFromClause().accept(this, currentOpRef).first);
         }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                currentOpRef = new MutableObject<>(letClause.accept(this, currentOpRef).first);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                currentOpRef = new MutableObject<>(letWhereClause.accept(this, currentOpRef).first);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            currentOpRef = new MutableObject<>(selectBlock.getWhereClause().accept(this, currentOpRef).first);
         }
         if (selectBlock.hasGroupbyClause()) {
             currentOpRef = new MutableObject<>(selectBlock.getGroupbyClause().accept(this, currentOpRef).first);
         }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                currentOpRef = new MutableObject<>(letClause.accept(this, currentOpRef).first);
+        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+            for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                currentOpRef = new MutableObject<>(letHavingClause.accept(this, currentOpRef).first);
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            currentOpRef = new MutableObject<>(selectBlock.getHavingClause().accept(this, currentOpRef).first);
         }
         return processSelectClause(selectBlock, currentOpRef);
     }
@@ -771,16 +766,16 @@
             } else if (projection.star()) {
                 if (selectBlock.hasGroupbyClause()) {
                     getGroupBindings(selectBlock.getGroupbyClause(), fieldBindings, fieldNames);
-                    if (selectBlock.hasLetClausesAfterGroupby()) {
-                        getLetBindings(selectBlock.getLetListAfterGroupby(), fieldBindings, fieldNames);
+                    if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                        getLetBindings(selectBlock.getLetHavingListAfterGroupby(), fieldBindings, fieldNames);
                     }
                 } else if (selectBlock.hasFromClause()) {
                     getFromBindings(selectBlock.getFromClause(), fieldBindings, fieldNames);
-                    if (selectBlock.hasLetClauses()) {
-                        getLetBindings(selectBlock.getLetList(), fieldBindings, fieldNames);
+                    if (selectBlock.hasLetWhereClauses()) {
+                        getLetBindings(selectBlock.getLetWhereList(), fieldBindings, fieldNames);
                     }
-                } else if (selectBlock.hasLetClauses()) {
-                    getLetBindings(selectBlock.getLetList(), fieldBindings, fieldNames);
+                } else if (selectBlock.hasLetWhereClauses()) {
+                    getLetBindings(selectBlock.getLetWhereList(), fieldBindings, fieldNames);
                 }
             } else if (projection.hasName()) {
                 fieldBindings.add(getFieldBinding(projection, fieldNames));
@@ -841,10 +836,13 @@
     }
 
     // Generates all field bindings according to the let clause.
-    private void getLetBindings(List<LetClause> letClauses, List<FieldBinding> outFieldBindings,
+    private void getLetBindings(List<AbstractClause> clauses, List<FieldBinding> outFieldBindings,
             Set<String> outFieldNames) throws CompilationException {
-        for (LetClause letClause : letClauses) {
-            outFieldBindings.add(getFieldBinding(letClause.getVarExpr(), outFieldNames));
+        for (AbstractClause clause : clauses) {
+            if (clause.getClauseType() == ClauseType.LET_CLAUSE) {
+                LetClause letClause = (LetClause) clause;
+                outFieldBindings.add(getFieldBinding(letClause.getVarExpr(), outFieldNames));
+            }
         }
     }
 
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java
index d22e929..194358a 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/FeedOperations.java
@@ -225,7 +225,8 @@
         // Constructing select clause
         SelectElement selectElement = new SelectElement(previousVarExpr);
         SelectClause selectClause = new SelectClause(selectElement, null, false);
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, whereClause, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause,
+                whereClause != null ? Collections.singletonList(whereClause) : null, null, null);
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         SelectExpression body = new SelectExpression(null, selectSetOperation, null, null, true);
         Query query = new Query(false, true, body, 0);
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
index c51b5e0..c9e4bcc 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in.plan
@@ -17,7 +17,7 @@
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                         -- STREAM_PROJECT  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- HYBRID_HASH_JOIN [$$42][$$32]  |PARTITIONED|
+                            -- HYBRID_HASH_JOIN [$$42][$$31]  |PARTITIONED|
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- STREAM_SELECT  |PARTITIONED|
@@ -25,7 +25,7 @@
                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                              -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+                              -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- ASSIGN  |PARTITIONED|
                                     -- STREAM_PROJECT  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
index a60462d..97d8e3b 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_ps.plan
@@ -21,7 +21,7 @@
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 -- STREAM_PROJECT  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- HYBRID_HASH_JOIN [$$42][$$32]  |PARTITIONED|
+                                    -- HYBRID_HASH_JOIN [$$42][$$31]  |PARTITIONED|
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- STREAM_PROJECT  |PARTITIONED|
                                           -- STREAM_SELECT  |PARTITIONED|
@@ -29,7 +29,7 @@
                                               -- DATASOURCE_SCAN  |PARTITIONED|
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                   -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                      -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+                                      -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
                                         -- STREAM_PROJECT  |PARTITIONED|
                                           -- ASSIGN  |PARTITIONED|
                                             -- STREAM_PROJECT  |PARTITIONED|
@@ -56,7 +56,7 @@
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- STREAM_PROJECT  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- HYBRID_HASH_JOIN [$$42][$$32]  |PARTITIONED|
+                                            -- HYBRID_HASH_JOIN [$$42][$$31]  |PARTITIONED|
                                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                 -- STREAM_PROJECT  |PARTITIONED|
                                                   -- STREAM_SELECT  |PARTITIONED|
@@ -64,7 +64,7 @@
                                                       -- DATASOURCE_SCAN  |PARTITIONED|
                                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                           -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
-                                              -- HASH_PARTITION_EXCHANGE [$$32]  |PARTITIONED|
+                                              -- HASH_PARTITION_EXCHANGE [$$31]  |PARTITIONED|
                                                 -- STREAM_PROJECT  |PARTITIONED|
                                                   -- ASSIGN  |PARTITIONED|
                                                     -- STREAM_PROJECT  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
index 6a74727..ef29016 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/tpcds/query-ASTERIXDB-1580.plan
@@ -3,10 +3,10 @@
     -- STREAM_LIMIT  |UNPARTITIONED|
       -- STREAM_PROJECT  |PARTITIONED|
         -- ASSIGN  |PARTITIONED|
-          -- SORT_MERGE_EXCHANGE [$$119(ASC) ]  |PARTITIONED|
+          -- SORT_MERGE_EXCHANGE [$$120(ASC) ]  |PARTITIONED|
             -- STREAM_LIMIT  |PARTITIONED|
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                -- STABLE_SORT [topK: 100] [$$119(ASC)]  |PARTITIONED|
+                -- STABLE_SORT [topK: 100] [$$120(ASC)]  |PARTITIONED|
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                     -- STREAM_PROJECT  |PARTITIONED|
                       -- STREAM_SELECT  |PARTITIONED|
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast
index a11de35..9a16c6c 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/flwor/at06/at06.3.ast
@@ -96,6 +96,12 @@
  AT
 Variable [ Name=$p ]
 ]
+Where
+  OperatorExpr [
+    Variable [ Name=$p ]
+    <
+    LiteralExpr [LONG] [4]
+  ]
 Let Variable [ Name=#1 ]
   :=
   FieldAccessor [
@@ -113,12 +119,6 @@
   FieldAccessor [
     Variable [ Name=$j ]
     Field=l_orderkey
-  ]
-Where
-  OperatorExpr [
-    Variable [ Name=$p ]
-    <
-    LiteralExpr [LONG] [4]
   ]
 Orderby
   Variable [ Name=#1 ]
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast
index 92376cd..0da93150 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite-open/tinysocial-suite.24.ast
@@ -18,27 +18,6 @@
   ]
   AS Variable [ Name=$user ]
 ]
-Let Variable [ Name=#1 ]
-  :=
-  FieldAccessor [
-    Variable [ Name=$user ]
-    Field=name
-  ]
-Let Variable [ Name=#2 ]
-  :=
-  FieldAccessor [
-    Variable [ Name=$user ]
-    Field=alias
-  ]
-Let Variable [ Name=#3 ]
-  :=
-  FunctionCall TinySocial.substring@2[
-    FieldAccessor [
-      Variable [ Name=$message ]
-      Field=message
-    ]
-    LiteralExpr [LONG] [29]
-  ]
 Where
   OperatorExpr [
     OperatorExpr [
@@ -71,6 +50,27 @@
       LiteralExpr [LONG] [11]
     ]
   ]
+Let Variable [ Name=#1 ]
+  :=
+  FieldAccessor [
+    Variable [ Name=$user ]
+    Field=name
+  ]
+Let Variable [ Name=#2 ]
+  :=
+  FieldAccessor [
+    Variable [ Name=$user ]
+    Field=alias
+  ]
+Let Variable [ Name=#3 ]
+  :=
+  FunctionCall TinySocial.substring@2[
+    FieldAccessor [
+      Variable [ Name=$message ]
+      Field=message
+    ]
+    LiteralExpr [LONG] [29]
+  ]
 Orderby
   Variable [ Name=#1 ]
   ASC
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast
index 92376cd..0da93150 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tinysocial/tinysocial-suite/tinysocial-suite.24.ast
@@ -18,27 +18,6 @@
   ]
   AS Variable [ Name=$user ]
 ]
-Let Variable [ Name=#1 ]
-  :=
-  FieldAccessor [
-    Variable [ Name=$user ]
-    Field=name
-  ]
-Let Variable [ Name=#2 ]
-  :=
-  FieldAccessor [
-    Variable [ Name=$user ]
-    Field=alias
-  ]
-Let Variable [ Name=#3 ]
-  :=
-  FunctionCall TinySocial.substring@2[
-    FieldAccessor [
-      Variable [ Name=$message ]
-      Field=message
-    ]
-    LiteralExpr [LONG] [29]
-  ]
 Where
   OperatorExpr [
     OperatorExpr [
@@ -71,6 +50,27 @@
       LiteralExpr [LONG] [11]
     ]
   ]
+Let Variable [ Name=#1 ]
+  :=
+  FieldAccessor [
+    Variable [ Name=$user ]
+    Field=name
+  ]
+Let Variable [ Name=#2 ]
+  :=
+  FieldAccessor [
+    Variable [ Name=$user ]
+    Field=alias
+  ]
+Let Variable [ Name=#3 ]
+  :=
+  FunctionCall TinySocial.substring@2[
+    FieldAccessor [
+      Variable [ Name=$message ]
+      Field=message
+    ]
+    LiteralExpr [LONG] [29]
+  ]
 Orderby
   Variable [ Name=#1 ]
   ASC
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 83b03ba..c934e32 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
@@ -26,8 +26,6 @@
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
-import org.apache.asterix.lang.common.clause.LetClause;
-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;
 
@@ -35,25 +33,20 @@
 
     private SelectClause selectClause;
     private FromClause fromClause;
-    private List<LetClause> letClauses = new ArrayList<>();
-    private WhereClause whereClause;
+    private final List<AbstractClause> letWhereClauses = new ArrayList<>();
     private GroupbyClause groupbyClause;
-    private List<LetClause> letClausesAfterGby = new ArrayList<>();
-    private HavingClause havingClause;
+    private final List<AbstractClause> letHavingClausesAfterGby = new ArrayList<>();
 
-    public SelectBlock(SelectClause selectClause, FromClause fromClause, List<LetClause> letClauses,
-            WhereClause whereClause, GroupbyClause groupbyClause, List<LetClause> letClausesAfterGby,
-            HavingClause havingClause) {
+    public SelectBlock(SelectClause selectClause, FromClause fromClause, List<AbstractClause> letWhereClauses,
+            GroupbyClause groupbyClause, List<AbstractClause> letHavingClausesAfterGby) {
         this.selectClause = selectClause;
         this.fromClause = fromClause;
-        if (letClauses != null) {
-            this.letClauses.addAll(letClauses);
+        if (letWhereClauses != null) {
+            this.letWhereClauses.addAll(letWhereClauses);
         }
-        this.whereClause = whereClause;
         this.groupbyClause = groupbyClause;
-        this.havingClause = havingClause;
-        if (letClausesAfterGby != null) {
-            this.letClausesAfterGby.addAll(letClausesAfterGby);
+        if (letHavingClausesAfterGby != null) {
+            this.letHavingClausesAfterGby.addAll(letHavingClausesAfterGby);
         }
     }
 
@@ -75,48 +68,32 @@
         return fromClause;
     }
 
-    public List<LetClause> getLetList() {
-        return letClauses;
-    }
-
-    public WhereClause getWhereClause() {
-        return whereClause;
+    public List<AbstractClause> getLetWhereList() {
+        return letWhereClauses;
     }
 
     public GroupbyClause getGroupbyClause() {
         return groupbyClause;
     }
 
-    public HavingClause getHavingClause() {
-        return havingClause;
+    public List<AbstractClause> getLetHavingListAfterGroupby() {
+        return letHavingClausesAfterGby;
     }
 
     public boolean hasFromClause() {
         return fromClause != null;
     }
 
-    public boolean hasLetClauses() {
-        return !letClauses.isEmpty();
-    }
-
-    public boolean hasWhereClause() {
-        return whereClause != null;
+    public boolean hasLetWhereClauses() {
+        return !letWhereClauses.isEmpty();
     }
 
     public boolean hasGroupbyClause() {
         return groupbyClause != null;
     }
 
-    public boolean hasLetClausesAfterGroupby() {
-        return !letClausesAfterGby.isEmpty();
-    }
-
-    public List<LetClause> getLetListAfterGroupby() {
-        return letClausesAfterGby;
-    }
-
-    public boolean hasHavingClause() {
-        return havingClause != null;
+    public boolean hasLetHavingClausesAfterGroupby() {
+        return !letHavingClausesAfterGby.isEmpty();
     }
 
     public void setGroupbyClause(GroupbyClause groupbyClause) {
@@ -125,8 +102,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(fromClause, groupbyClause, havingClause, letClauses, letClausesAfterGby, selectClause,
-                whereClause);
+        return Objects.hash(fromClause, groupbyClause, letWhereClauses, letHavingClausesAfterGby, selectClause);
     }
 
     @Override
@@ -140,9 +116,9 @@
         }
         SelectBlock target = (SelectBlock) object;
         return Objects.equals(fromClause, target.fromClause) && Objects.equals(groupbyClause, target.groupbyClause)
-                && Objects.equals(havingClause, target.havingClause) && Objects.equals(letClauses, target.letClauses)
-                && Objects.equals(letClausesAfterGby, target.letClausesAfterGby)
-                && Objects.equals(selectClause, target.selectClause) && Objects.equals(whereClause, target.whereClause);
+                && Objects.equals(letWhereClauses, target.letWhereClauses)
+                && Objects.equals(letHavingClausesAfterGby, target.letHavingClausesAfterGby)
+                && Objects.equals(selectClause, target.selectClause);
     }
 
     @Override
@@ -150,22 +126,16 @@
         StringBuilder sb = new StringBuilder();
         sb.append(selectClause);
         if (hasFromClause()) {
-            sb.append(" " + fromClause);
+            sb.append(' ').append(fromClause);
         }
-        if (hasLetClauses()) {
-            sb.append(" " + letClauses);
-        }
-        if (hasWhereClause()) {
-            sb.append(" " + whereClause);
+        if (hasLetWhereClauses()) {
+            sb.append(' ').append(letWhereClauses);
         }
         if (hasGroupbyClause()) {
-            sb.append(" " + groupbyClause);
+            sb.append(' ').append(groupbyClause);
         }
-        if (hasLetClausesAfterGroupby()) {
-            sb.append(" " + letClausesAfterGby);
-        }
-        if (hasHavingClause()) {
-            sb.append(" " + havingClause);
+        if (hasLetHavingClausesAfterGroupby()) {
+            sb.append(' ').append(letHavingClausesAfterGby);
         }
         return sb.toString();
     }
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 942fc88..35de051 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
@@ -24,6 +24,7 @@
 import java.util.Set;
 import java.util.HashSet;
 
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
@@ -364,24 +365,18 @@
             if (selectBlock.hasFromClause()) {
                 selectBlock.getFromClause().accept(this, arg);
             }
-            if (selectBlock.hasLetClauses()) {
-                for (LetClause letClause : selectBlock.getLetList()) {
-                    letClause.accept(this, arg);
+            if (selectBlock.hasLetWhereClauses()) {
+                for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                    letWhereClause.accept(this, arg);
                 }
-            }
-            if (selectBlock.hasWhereClause()) {
-                selectBlock.getWhereClause().accept(this, arg);
             }
             if (selectBlock.hasGroupbyClause()) {
                 selectBlock.getGroupbyClause().accept(this, arg);
             }
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                    letClause.accept(this, arg);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(this, arg);
                 }
-            }
-            if (selectBlock.hasHavingClause()) {
-                selectBlock.getHavingClause().accept(this, arg);
             }
             selectBlock.getSelectClause().accept(this, arg);
             return null;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java
index b78cd9c..3606b12 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/AbstractSqlppExpressionExtractionVisitor.java
@@ -26,6 +26,7 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.LetClause;
@@ -64,54 +65,47 @@
                 handleUnsupportedClause(clause, extractionList);
             }
         }
-        List<LetClause> letList = selectBlock.getLetList();
-        if (selectBlock.hasLetClauses()) {
-            visitLetClauses(letList, extractionList, arg);
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, arg);
-            introduceLetClauses(extractionList, letList);
+        List<AbstractClause> letWhereList = selectBlock.getLetWhereList();
+        if (!letWhereList.isEmpty()) {
+            visitLetWhereClauses(letWhereList, extractionList, arg);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, arg);
-            introduceLetClauses(extractionList, letList);
+            introduceLetClauses(extractionList, letWhereList);
         }
-        List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            visitLetClauses(letListAfterGby, extractionList, arg);
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, arg);
-            introduceLetClauses(extractionList, letListAfterGby);
+        List<AbstractClause> letHavingListAfterGby = selectBlock.getLetHavingListAfterGroupby();
+        if (!letHavingListAfterGby.isEmpty()) {
+            visitLetWhereClauses(letHavingListAfterGby, extractionList, arg);
         }
         selectBlock.getSelectClause().accept(this, arg);
-        introduceLetClauses(extractionList, selectBlock.hasGroupbyClause() ? letListAfterGby : letList);
+        introduceLetClauses(extractionList, selectBlock.hasGroupbyClause() ? letHavingListAfterGby : letWhereList);
 
         stack.pop();
         return null;
     }
 
-    private void visitLetClauses(List<LetClause> letList, List<Pair<Expression, VarIdentifier>> extractionList,
-            ILangExpression arg) throws CompilationException {
-        List<LetClause> newLetList = new ArrayList<>(letList.size());
-        for (LetClause letClause : letList) {
-            letClause.accept(this, arg);
-            introduceLetClauses(extractionList, newLetList);
-            newLetList.add(letClause);
+    private void visitLetWhereClauses(List<AbstractClause> clauseList,
+            List<Pair<Expression, VarIdentifier>> extractionList, ILangExpression arg) throws CompilationException {
+        List<AbstractClause> newClauseList = new ArrayList<>(clauseList.size());
+        for (AbstractClause letWhereClause : clauseList) {
+            letWhereClause.accept(this, arg);
+            introduceLetClauses(extractionList, newClauseList);
+            newClauseList.add(letWhereClause);
         }
-        if (newLetList.size() > letList.size()) {
-            letList.clear();
-            letList.addAll(newLetList);
+        if (newClauseList.size() > clauseList.size()) {
+            clauseList.clear();
+            clauseList.addAll(newClauseList);
         }
     }
 
-    private void introduceLetClauses(List<Pair<Expression, VarIdentifier>> fromBindingList, List<LetClause> toLetList) {
+    private void introduceLetClauses(List<Pair<Expression, VarIdentifier>> fromBindingList,
+            List<AbstractClause> toLetWhereList) {
         for (Pair<Expression, VarIdentifier> p : fromBindingList) {
             Expression bindExpr = p.first;
             VarIdentifier var = p.second;
             VariableExpr varExpr = new VariableExpr(var);
             varExpr.setSourceLocation(bindExpr.getSourceLocation());
-            toLetList.add(new LetClause(varExpr, bindExpr));
+            toLetWhereList.add(new LetClause(varExpr, bindExpr));
             context.addExcludedForFieldAccessVar(var);
         }
         fromBindingList.clear();
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 a270530..f68688f 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
@@ -18,17 +18,15 @@
  */
 package org.apache.asterix.lang.sqlpp.rewrites.visitor;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.lang.common.base.AbstractClause;
 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;
@@ -77,15 +75,16 @@
         // Removes all FROM/LET binding variables
         if (selectBlock.hasGroupbyClause()) {
             map.keySet().removeAll(SqlppVariableUtil.getBindingVariables(selectBlock.getGroupbyClause()));
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                map.keySet().removeAll(SqlppVariableUtil.getBindingVariables(selectBlock.getLetListAfterGroupby()));
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                map.keySet().removeAll(
+                        SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetHavingListAfterGroupby()));
             }
         } else {
             if (selectBlock.hasFromClause()) {
                 map.keySet().removeAll(SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause()));
             }
-            if (selectBlock.hasLetClauses()) {
-                map.keySet().removeAll(SqlppVariableUtil.getBindingVariables(selectBlock.getLetList()));
+            if (selectBlock.hasLetWhereClauses()) {
+                map.keySet().removeAll(SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetWhereList()));
             }
         }
 
@@ -163,8 +162,8 @@
     private void introduceLetClauses(Map<Expression, VarIdentifier> letVarMap,
             Map<Expression, ColumnAliasBinding> aliasBindingMap, SelectBlock selectBlock) throws CompilationException {
 
-        List<LetClause> targetLetClauses =
-                selectBlock.hasGroupbyClause() ? selectBlock.getLetListAfterGroupby() : selectBlock.getLetList();
+        List<AbstractClause> targetLetClauses = selectBlock.hasGroupbyClause()
+                ? selectBlock.getLetHavingListAfterGroupby() : selectBlock.getLetWhereList();
 
         for (Map.Entry<Expression, VarIdentifier> me : letVarMap.entrySet()) {
             Expression columnAliasVarExpr = me.getKey();
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java
index f0a0f87..dd02dbe 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SetOperationVisitor.java
@@ -95,7 +95,7 @@
         newFromClause.setSourceLocation(sourceLoc);
         SelectClause selectClause = new SelectClause(new SelectElement(newBindingVar), null, false);
         selectClause.setSourceLocation(sourceLoc);
-        SelectBlock selectBlock = new SelectBlock(selectClause, newFromClause, null, null, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, newFromClause, null, null, null);
         selectBlock.setSourceLocation(sourceLoc);
         SelectSetOperation newSelectSetOperation =
                 new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java
index 2be752d..6e14e74 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/Sql92AggregateFunctionVisitor.java
@@ -144,7 +144,7 @@
         selectClause.setSourceLocation(sourceLoc);
 
         // Construct the select expression.
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null);
         selectBlock.setSourceLocation(sourceLoc);
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         selectSetOperation.setSourceLocation(sourceLoc);
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java
index efcd7e0..180f80c 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppDistinctAggregationSugarVisitor.java
@@ -119,7 +119,7 @@
         selectClause.setSourceLocation(sourceLoc);
 
         // Construct the select expression.
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, null, null);
         selectBlock.setSourceLocation(sourceLoc);
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         selectSetOperation.setSourceLocation(sourceLoc);
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
index 1c55f99..ad1268f 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByAggregationSugarVisitor.java
@@ -19,6 +19,7 @@
 package org.apache.asterix.lang.sqlpp.rewrites.visitor;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -84,20 +85,15 @@
 
     @Override
     public Expression visit(SelectBlock selectBlock, ILangExpression arg) throws CompilationException {
-        // Traverses the select block in the order of "from", "let"s, "where",
-        // "group by", "let"s, "having" and "select".
+        // Traverses the select block in the order of "from", "let/where"s, "group by", "let/having"s and "select".
         FromClause fromClause = selectBlock.getFromClause();
         if (selectBlock.hasFromClause()) {
             fromClause.accept(this, arg);
         }
-        if (selectBlock.hasLetClauses()) {
-            List<LetClause> letList = selectBlock.getLetList();
-            for (LetClause letClause : letList) {
-                letClause.accept(this, arg);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                letWhereClause.accept(this, arg);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, arg);
         }
         if (selectBlock.hasGroupbyClause()) {
             Set<VariableExpr> visibleVarsPreGroupByScope = scopeChecker.getCurrentScope().getLiveVariables();
@@ -109,29 +105,30 @@
             VariableExpr groupVar = groupbyClause.getGroupVar();
             Map<Expression, Identifier> groupFieldVars = getGroupFieldVariables(groupbyClause);
 
-            Collection<VariableExpr> freeVariablesInGbyLets = new HashSet<>();
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-                for (LetClause letClauseAfterGby : letListAfterGby) {
-                    letClauseAfterGby.accept(this, arg);
-                    // Rewrites each let clause after the group-by.
-                    rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, letClauseAfterGby,
-                            visibleVarsPreGroupByScope);
-                    Collection<VariableExpr> freeVariablesInLet =
-                            SqlppVariableUtil.getFreeVariables(letClauseAfterGby.getBindingExpr());
-                    freeVariablesInLet.removeAll(visibleVarsInCurrentScope);
-                    freeVariablesInGbyLets.addAll(freeVariablesInLet);
-                    visibleVarsInCurrentScope.add(letClauseAfterGby.getVarExpr());
-                }
-            }
-
             Collection<VariableExpr> freeVariables = new HashSet<>();
-            if (selectBlock.hasHavingClause()) {
-                // Rewrites the having clause.
-                HavingClause havingClause = selectBlock.getHavingClause();
-                havingClause.accept(this, arg);
-                rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, havingClause, visibleVarsPreGroupByScope);
-                freeVariables.addAll(SqlppVariableUtil.getFreeVariables(havingClause));
+            Collection<VariableExpr> freeVariablesInGbyLets = new HashSet<>();
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(this, arg);
+                    // Rewrites each let/having clause after the group-by.
+                    rewriteExpressionUsingGroupVariable(groupVar, groupFieldVars, letHavingClause,
+                            visibleVarsPreGroupByScope);
+                    switch (letHavingClause.getClauseType()) {
+                        case LET_CLAUSE:
+                            LetClause letClause = (LetClause) letHavingClause;
+                            Collection<VariableExpr> freeVariablesInClause =
+                                    SqlppVariableUtil.getFreeVariables(letClause.getBindingExpr());
+                            freeVariablesInClause.removeAll(visibleVarsInCurrentScope);
+                            freeVariablesInGbyLets.addAll(freeVariablesInClause);
+                            visibleVarsInCurrentScope.add(letClause.getVarExpr());
+                            break;
+                        case HAVING_CLAUSE:
+                            freeVariables.addAll(SqlppVariableUtil.getFreeVariables(letHavingClause));
+                            break;
+                        default:
+                            throw new IllegalStateException(String.valueOf(letHavingClause.getClauseType()));
+                    }
+                }
             }
 
             SelectExpression parentSelectExpression = (SelectExpression) arg;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
index 84aee71..4fe2699 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppGroupByVisitor.java
@@ -123,7 +123,7 @@
     private List<Pair<Expression, Identifier>> createGroupFieldList(SelectBlock selectBlock) {
         List<Pair<Expression, Identifier>> groupFieldList = new ArrayList<>();
         addToFieldList(groupFieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause()));
-        addToFieldList(groupFieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getLetList()));
+        addToFieldList(groupFieldList, SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetWhereList()));
         return groupFieldList;
     }
 
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
index 1fd4ff7..2ff6b63 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
@@ -23,6 +23,7 @@
 import java.util.Map;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.IRewriterFactory;
 import org.apache.asterix.lang.common.clause.LetClause;
@@ -135,24 +136,18 @@
         if (selectBlock.hasFromClause()) {
             changed |= selectBlock.getFromClause().accept(this, funcs);
         }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                changed |= letClause.accept(this, funcs);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                changed |= letWhereClause.accept(this, funcs);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            changed |= selectBlock.getWhereClause().accept(this, funcs);
         }
         if (selectBlock.hasGroupbyClause()) {
             changed |= selectBlock.getGroupbyClause().accept(this, funcs);
         }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                changed |= letClause.accept(this, funcs);
+        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+            for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                changed |= letHavingClause.accept(this, funcs);
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            changed |= selectBlock.getHavingClause().accept(this, funcs);
         }
         changed |= selectBlock.getSelectClause().accept(this, funcs);
         return changed;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java
index 0b2d2cf..910552a 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppWindowAggregationSugarVisitor.java
@@ -125,9 +125,10 @@
         List<Pair<Expression, Identifier>> fieldList = new ArrayList<>();
         if (selectBlock != null) {
             addToFieldList(fieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause()));
-            addToFieldList(fieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getLetList()));
+            addToFieldList(fieldList, SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetWhereList()));
             addToFieldList(fieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getGroupbyClause()));
-            addToFieldList(fieldList, SqlppVariableUtil.getBindingVariables(selectBlock.getLetListAfterGroupby()));
+            addToFieldList(fieldList,
+                    SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetHavingListAfterGroupby()));
         }
         return fieldList;
     }
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
index 9e937d0..13f1128 100644
--- 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
@@ -24,10 +24,10 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.AbstractClause;
 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.clause.LetClause;
 import org.apache.asterix.lang.common.expression.CallExpr;
 import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
@@ -65,13 +65,10 @@
             SubstituteGroupbyExpressionVisitor visitor = new SubstituteGroupbyExpressionVisitor(context, map);
 
             // Rewrites LET/HAVING/SELECT clauses.
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                    letClause.accept(visitor, arg);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(visitor, arg);
                 }
-            }
-            if (selectBlock.hasHavingClause()) {
-                selectBlock.getHavingClause().accept(visitor, arg);
             }
             selectBlock.getSelectClause().accept(visitor, arg);
             SelectExpression selectExpression = (SelectExpression) arg;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
index f71ae5b..a186cba 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppVariableUtil.java
@@ -27,6 +27,8 @@
 import java.util.Set;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
+import org.apache.asterix.lang.common.base.Clause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -176,13 +178,16 @@
         return bindingVars;
     }
 
-    public static List<VariableExpr> getBindingVariables(List<LetClause> letClauses) {
+    public static List<VariableExpr> getLetBindingVariables(List<? extends AbstractClause> clauses) {
         List<VariableExpr> bindingVars = new ArrayList<>();
-        if (letClauses == null || letClauses.isEmpty()) {
+        if (clauses == null || clauses.isEmpty()) {
             return bindingVars;
         }
-        for (LetClause letClause : letClauses) {
-            bindingVars.add(letClause.getVarExpr());
+        for (AbstractClause clause : clauses) {
+            if (clause.getClauseType() == Clause.ClauseType.LET_CLAUSE) {
+                LetClause letClause = (LetClause) clause;
+                bindingVars.add(letClause.getVarExpr());
+            }
         }
         return bindingVars;
     }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
index c816d05..b9954a5 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
@@ -116,10 +116,9 @@
 
     @Override
     public Boolean visit(SelectBlock selectBlock, ILangExpression arg) throws CompilationException {
-        boolean hasSubquery = visit(selectBlock.getFromClause(), arg) || visit(selectBlock.getGroupbyClause(), arg)
-                || visit(selectBlock.getHavingClause(), arg) || visit(selectBlock.getWhereClause(), arg);
-        return hasSubquery || visit(selectBlock.getSelectClause(), arg) || visitExprList(selectBlock.getLetList(), arg)
-                || visitExprList(selectBlock.getLetListAfterGroupby(), arg);
+        return visit(selectBlock.getFromClause(), arg) || visit(selectBlock.getGroupbyClause(), arg)
+                || visit(selectBlock.getSelectClause(), arg) || visitExprList(selectBlock.getLetWhereList(), arg)
+                || visitExprList(selectBlock.getLetHavingListAfterGroupby(), arg);
     }
 
     @Override
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 ed92bfd..96409d4 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
@@ -25,6 +25,7 @@
 import java.util.Map.Entry;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -152,41 +153,31 @@
     @Override
     public SelectBlock visit(SelectBlock selectBlock, Void arg) throws CompilationException {
         FromClause fromClause = null;
-        List<LetClause> letClauses = new ArrayList<>();
-        WhereClause whereClause = null;
+        List<AbstractClause> letWhereClauses = new ArrayList<>();
         GroupbyClause gbyClause = null;
-        List<LetClause> gbyLetClauses = new ArrayList<>();
-        HavingClause havingClause = null;
-        SelectClause selectCluase;
-        // Traverses the select block in the order of "from", "let"s, "where",
-        // "group by", "let"s, "having" and "select".
+        List<AbstractClause> gbyLetHavingClauses = new ArrayList<>();
+        SelectClause selectClause;
+        // Traverses the select block in the order of "from", "let/where"s, "group by", "let/having"s, and "select".
         if (selectBlock.hasFromClause()) {
             fromClause = (FromClause) selectBlock.getFromClause().accept(this, arg);
         }
-        if (selectBlock.hasLetClauses()) {
-            List<LetClause> letList = selectBlock.getLetList();
-            for (LetClause letClause : letList) {
-                letClauses.add((LetClause) letClause.accept(this, arg));
+        if (selectBlock.hasLetWhereClauses()) {
+            List<AbstractClause> letWhereList = selectBlock.getLetWhereList();
+            for (AbstractClause letWhereClause : letWhereList) {
+                letWhereClauses.add((AbstractClause) letWhereClause.accept(this, arg));
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            whereClause = (WhereClause) selectBlock.getWhereClause().accept(this, arg);
         }
         if (selectBlock.hasGroupbyClause()) {
             gbyClause = (GroupbyClause) selectBlock.getGroupbyClause().accept(this, arg);
         }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-            for (LetClause letClauseAfterGby : letListAfterGby) {
-                gbyLetClauses.add((LetClause) letClauseAfterGby.accept(this, arg));
+        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+            List<AbstractClause> letHavingListAfterGby = selectBlock.getLetHavingListAfterGroupby();
+            for (AbstractClause letHavingClauseAfterGby : letHavingListAfterGby) {
+                gbyLetHavingClauses.add((AbstractClause) letHavingClauseAfterGby.accept(this, arg));
             }
         }
-        if (selectBlock.hasHavingClause()) {
-            havingClause = (HavingClause) selectBlock.getHavingClause().accept(this, arg);
-        }
-        selectCluase = (SelectClause) selectBlock.getSelectClause().accept(this, arg);
-        SelectBlock copy = new SelectBlock(selectCluase, fromClause, letClauses, whereClause, gbyClause, gbyLetClauses,
-                havingClause);
+        selectClause = (SelectClause) selectBlock.getSelectClause().accept(this, arg);
+        SelectBlock copy = new SelectBlock(selectClause, fromClause, letWhereClauses, gbyClause, gbyLetHavingClauses);
         copy.setSourceLocation(selectBlock.getSourceLocation());
         return copy;
     }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
index b61f4e6..d662988 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
@@ -23,6 +23,7 @@
 import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Clause.ClauseType;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -155,16 +156,16 @@
     public Void visit(SelectBlock selectBlock, Collection<VariableExpr> freeVars) throws CompilationException {
         Collection<VariableExpr> selectFreeVars = new HashSet<>();
         Collection<VariableExpr> fromFreeVars = new HashSet<>();
-        Collection<VariableExpr> letsFreeVars = new HashSet<>();
-        Collection<VariableExpr> whereFreeVars = new HashSet<>();
+        Collection<VariableExpr> letWheresFreeVars = new HashSet<>();
         Collection<VariableExpr> gbyFreeVars = new HashSet<>();
-        Collection<VariableExpr> gbyLetsFreeVars = new HashSet<>();
+        Collection<VariableExpr> gbyLetHavingsFreeVars = new HashSet<>();
 
         Collection<VariableExpr> fromBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause());
-        Collection<VariableExpr> letsBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getLetList());
+        Collection<VariableExpr> letsBindingVars =
+                SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetWhereList());
         Collection<VariableExpr> gbyBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getGroupbyClause());
         Collection<VariableExpr> gbyLetsBindingVars =
-                SqlppVariableUtil.getBindingVariables(selectBlock.getLetListAfterGroupby());
+                SqlppVariableUtil.getLetBindingVariables(selectBlock.getLetHavingListAfterGroupby());
 
         selectBlock.getSelectClause().accept(this, selectFreeVars);
         // Removes group-by, from, let, and gby-let binding vars.
@@ -174,30 +175,20 @@
         if (selectBlock.hasFromClause()) {
             selectBlock.getFromClause().accept(this, fromFreeVars);
         }
-        if (selectBlock.hasLetClauses()) {
-            visitLetClauses(selectBlock.getLetList(), letsFreeVars);
-            letsFreeVars.removeAll(fromBindingVars);
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, whereFreeVars);
-            whereFreeVars.removeAll(fromBindingVars);
-            whereFreeVars.removeAll(letsBindingVars);
+        if (selectBlock.hasLetWhereClauses()) {
+            visitLetWhereClauses(selectBlock.getLetWhereList(), letWheresFreeVars);
+            letWheresFreeVars.removeAll(fromBindingVars);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, gbyFreeVars);
             // Remove group-by and let binding vars.
             gbyFreeVars.removeAll(fromBindingVars);
             gbyFreeVars.removeAll(letsBindingVars);
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                visitLetClauses(selectBlock.getLetListAfterGroupby(), gbyLetsFreeVars);
-                gbyLetsFreeVars.removeAll(fromBindingVars);
-                gbyLetsFreeVars.removeAll(letsBindingVars);
-                gbyLetsFreeVars.removeAll(gbyBindingVars);
-            }
-            if (selectBlock.hasHavingClause()) {
-                selectBlock.getHavingClause().accept(this, selectFreeVars);
-                removeAllBindingVarsInSelectBlock(selectFreeVars, fromBindingVars, letsBindingVars, gbyBindingVars,
-                        gbyLetsBindingVars);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                visitLetWhereClauses(selectBlock.getLetHavingListAfterGroupby(), gbyLetHavingsFreeVars);
+                gbyLetHavingsFreeVars.removeAll(fromBindingVars);
+                gbyLetHavingsFreeVars.removeAll(letsBindingVars);
+                gbyLetHavingsFreeVars.removeAll(gbyBindingVars);
             }
         }
 
@@ -209,10 +200,9 @@
         // Adds all free vars.
         freeVars.addAll(selectFreeVars);
         freeVars.addAll(fromFreeVars);
-        freeVars.addAll(letsFreeVars);
-        freeVars.addAll(whereFreeVars);
+        freeVars.addAll(letWheresFreeVars);
         freeVars.addAll(gbyFreeVars);
-        freeVars.addAll(gbyLetsFreeVars);
+        freeVars.addAll(gbyLetHavingsFreeVars);
         return null;
     }
 
@@ -322,7 +312,7 @@
             throws CompilationException {
         Collection<VariableExpr> letsFreeVars = new HashSet<>();
         Collection<VariableExpr> selectFreeVars = new HashSet<>();
-        visitLetClauses(selectExpression.getLetList(), letsFreeVars);
+        visitLetWhereClauses(selectExpression.getLetList(), letsFreeVars);
 
         // visit order by
         if (selectExpression.hasOrderby()) {
@@ -340,7 +330,7 @@
         selectExpression.getSelectSetOperation().accept(this, selectFreeVars);
 
         // Removed let binding variables.
-        selectFreeVars.removeAll(SqlppVariableUtil.getBindingVariables(selectExpression.getLetList()));
+        selectFreeVars.removeAll(SqlppVariableUtil.getLetBindingVariables(selectExpression.getLetList()));
         freeVars.addAll(letsFreeVars);
         freeVars.addAll(selectFreeVars);
         return null;
@@ -471,22 +461,24 @@
         return null;
     }
 
-    private void visitLetClauses(List<LetClause> letClauses, Collection<VariableExpr> freeVars)
+    private void visitLetWhereClauses(List<? extends AbstractClause> clauseList, Collection<VariableExpr> freeVars)
             throws CompilationException {
-        if (letClauses == null || letClauses.isEmpty()) {
+        if (clauseList == null || clauseList.isEmpty()) {
             return;
         }
         Collection<VariableExpr> bindingVars = new HashSet<>();
-        for (LetClause letClause : letClauses) {
-            Collection<VariableExpr> letFreeVars = new HashSet<>();
-            letClause.accept(this, letFreeVars);
+        for (AbstractClause clause : clauseList) {
+            Collection<VariableExpr> clauseFreeVars = new HashSet<>();
+            clause.accept(this, clauseFreeVars);
 
             // Removes previous binding variables.
-            letFreeVars.removeAll(bindingVars);
-            freeVars.addAll(letFreeVars);
+            clauseFreeVars.removeAll(bindingVars);
+            freeVars.addAll(clauseFreeVars);
 
             // Adds let binding variables into the binding variable collection.
-            bindingVars.add(letClause.getVarExpr());
+            if (clause.getClauseType() == ClauseType.LET_CLAUSE) {
+                bindingVars.add(((LetClause) clause).getVarExpr());
+            }
         }
     }
 
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
index d906a82..da3c5df 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
@@ -24,6 +24,7 @@
 
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
 import org.apache.asterix.lang.common.clause.LetClause;
@@ -141,24 +142,18 @@
         if (selectBlock.hasFromClause()) {
             selectBlock.getFromClause().accept(this, step);
         }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                letClause.accept(this, step);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                letWhereClause.accept(this, step);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, step);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, step);
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                    letClause.accept(this, step);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(this, step);
                 }
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, step);
         }
         return null;
     }
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 39e1883..dc3e565 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
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Clause.ClauseType;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
@@ -29,7 +30,6 @@
 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.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
@@ -215,13 +215,12 @@
     public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(SelectBlock selectBlock,
             VariableSubstitutionEnvironment env) throws CompilationException {
         Pair<ILangExpression, VariableSubstitutionEnvironment> newFrom = null;
-        Pair<ILangExpression, VariableSubstitutionEnvironment> newLet;
-        Pair<ILangExpression, VariableSubstitutionEnvironment> newWhere = null;
+        Pair<ILangExpression, VariableSubstitutionEnvironment> newLetWhere;
         Pair<ILangExpression, VariableSubstitutionEnvironment> newGroupby = null;
-        Pair<ILangExpression, VariableSubstitutionEnvironment> newHaving = null;
+        Pair<ILangExpression, VariableSubstitutionEnvironment> newLetHaving;
         Pair<ILangExpression, VariableSubstitutionEnvironment> newSelect;
-        List<LetClause> newLetClauses = new ArrayList<>();
-        List<LetClause> newLetClausesAfterGby = new ArrayList<>();
+        List<AbstractClause> newLetWhereClauses = new ArrayList<>();
+        List<AbstractClause> newLetHavingClausesAfterGby = new ArrayList<>();
         VariableSubstitutionEnvironment currentEnv = new VariableSubstitutionEnvironment(env);
 
         if (selectBlock.hasFromClause()) {
@@ -229,44 +228,32 @@
             currentEnv = newFrom.second;
         }
 
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                newLet = letClause.accept(this, currentEnv);
-                currentEnv = newLet.second;
-                newLetClauses.add((LetClause) newLet.first);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                newLetWhere = letWhereClause.accept(this, currentEnv);
+                currentEnv = newLetWhere.second;
+                newLetWhereClauses.add((AbstractClause) newLetWhere.first);
             }
-        }
-
-        if (selectBlock.hasWhereClause()) {
-            newWhere = selectBlock.getWhereClause().accept(this, currentEnv);
-            currentEnv = newWhere.second;
         }
 
         if (selectBlock.hasGroupbyClause()) {
             newGroupby = selectBlock.getGroupbyClause().accept(this, currentEnv);
             currentEnv = newGroupby.second;
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClauseAfterGby : selectBlock.getLetListAfterGroupby()) {
-                    newLet = letClauseAfterGby.accept(this, currentEnv);
-                    currentEnv = newLet.second;
-                    newLetClausesAfterGby.add(letClauseAfterGby);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClauseAfterGby : selectBlock.getLetHavingListAfterGroupby()) {
+                    newLetHaving = letHavingClauseAfterGby.accept(this, currentEnv);
+                    currentEnv = newLetHaving.second;
+                    newLetHavingClausesAfterGby.add((AbstractClause) newLetHaving.first);
                 }
             }
-        }
-
-        if (selectBlock.hasHavingClause()) {
-            newHaving = selectBlock.getHavingClause().accept(this, currentEnv);
-            currentEnv = newHaving.second;
         }
 
         newSelect = selectBlock.getSelectClause().accept(this, currentEnv);
         currentEnv = newSelect.second;
         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;
-        SelectBlock newSelectBlock = new SelectBlock((SelectClause) newSelect.first, fromClause, newLetClauses,
-                whereClause, groupbyClause, newLetClausesAfterGby, havingClause);
+        SelectBlock newSelectBlock = new SelectBlock((SelectClause) newSelect.first, fromClause, newLetWhereClauses,
+                groupbyClause, newLetHavingClausesAfterGby);
         newSelectBlock.setSourceLocation(selectBlock.getSourceLocation());
         return new Pair<>(newSelectBlock, currentEnv);
     }
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
index bf57184..8cfd04b 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppDeleteRewriteVisitor.java
@@ -86,7 +86,8 @@
         selectClause.setSourceLocation(deleteStmt.getSourceLocation());
 
         // Construct the select expression.
-        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, null, whereClause, null, null, null);
+        SelectBlock selectBlock = new SelectBlock(selectClause, fromClause,
+                whereClause != null ? Collections.singletonList(whereClause) : null, null, null);
         selectBlock.setSourceLocation(var.getSourceLocation());
         SelectSetOperation selectSetOperation = new SelectSetOperation(new SetOperationInput(selectBlock, null), null);
         selectSetOperation.setSourceLocation(var.getSourceLocation());
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 1ee3004..e541363 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
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
 import org.apache.asterix.lang.common.clause.LetClause;
@@ -144,24 +145,18 @@
         if (selectBlock.hasFromClause()) {
             selectBlock.getFromClause().accept(this, step);
         }
-        if (selectBlock.hasLetClauses()) {
-            for (LetClause letClause : selectBlock.getLetList()) {
-                letClause.accept(this, step);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause letWhereClause : selectBlock.getLetWhereList()) {
+                letWhereClause.accept(this, step);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, step);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, step);
-            if (selectBlock.hasLetClausesAfterGroupby()) {
-                for (LetClause letClause : selectBlock.getLetListAfterGroupby()) {
-                    letClause.accept(this, step);
+            if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+                for (AbstractClause letHavingClause : selectBlock.getLetHavingListAfterGroupby()) {
+                    letHavingClause.accept(this, step);
                 }
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, step);
         }
         return null;
     }
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 d1092b3..345d5a5 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
@@ -22,6 +22,7 @@
 import java.util.List;
 
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.clause.GroupbyClause;
@@ -120,31 +121,22 @@
 
     @Override
     public Expression visit(SelectBlock selectBlock, ILangExpression arg) throws CompilationException {
-        // Traverses the select block in the order of "from", "let"s, "where",
-        // "group by", "let"s, "having" and "select".
+        // Traverses the select block in the order of "from", "let/where"s, "group by", "let/having"s and "select".
         if (selectBlock.hasFromClause()) {
             selectBlock.getFromClause().accept(this, arg);
         }
-        if (selectBlock.hasLetClauses()) {
-            List<LetClause> letList = selectBlock.getLetList();
-            for (LetClause letClause : letList) {
-                letClause.accept(this, arg);
+        if (selectBlock.hasLetWhereClauses()) {
+            for (AbstractClause clause : selectBlock.getLetWhereList()) {
+                clause.accept(this, arg);
             }
-        }
-        if (selectBlock.hasWhereClause()) {
-            selectBlock.getWhereClause().accept(this, arg);
         }
         if (selectBlock.hasGroupbyClause()) {
             selectBlock.getGroupbyClause().accept(this, arg);
         }
-        if (selectBlock.hasLetClausesAfterGroupby()) {
-            List<LetClause> letListAfterGby = selectBlock.getLetListAfterGroupby();
-            for (LetClause letClauseAfterGby : letListAfterGby) {
-                letClauseAfterGby.accept(this, arg);
+        if (selectBlock.hasLetHavingClausesAfterGroupby()) {
+            for (AbstractClause clause : selectBlock.getLetHavingListAfterGroupby()) {
+                clause.accept(this, arg);
             }
-        }
-        if (selectBlock.hasHavingClause()) {
-            selectBlock.getHavingClause().accept(this, arg);
         }
         selectBlock.getSelectClause().accept(this, arg);
         return null;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index 4078389..45ba7c3 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -67,6 +67,7 @@
 import org.apache.asterix.common.exceptions.ErrorCode;
 import org.apache.asterix.common.functions.FunctionConstants;
 import org.apache.asterix.common.functions.FunctionSignature;
+import org.apache.asterix.lang.common.base.AbstractClause;
 import org.apache.asterix.lang.common.base.AbstractLangExpression;
 import org.apache.asterix.lang.common.base.AbstractStatement;
 import org.apache.asterix.lang.common.base.Expression;
@@ -3034,9 +3035,11 @@
   FromClause fromClause = null;
   List<LetClause> fromLetClauses = null;
   WhereClause whereClause = null;
+  List<AbstractClause> fromLetWhereClauses = new ArrayList<AbstractClause>();
   GroupbyClause groupbyClause = null;
   List<LetClause> gbyLetClauses = null;
   HavingClause havingClause = null;
+  List<AbstractClause> gbyLetHavingClauses = new ArrayList<AbstractClause>();
   SourceLocation startSrcLoc = null;
 }
 {
@@ -3076,8 +3079,20 @@
      selectClause = SelectClause()
   )
   {
-    SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetClauses, whereClause, groupbyClause,
-      gbyLetClauses, havingClause);
+    if (fromLetClauses != null) {
+      fromLetWhereClauses.addAll(fromLetClauses);
+    }
+    if (whereClause != null) {
+      fromLetWhereClauses.add(whereClause);
+    }
+    if (gbyLetClauses != null) {
+      gbyLetHavingClauses.addAll(gbyLetClauses);
+    }
+    if (havingClause != null) {
+      gbyLetHavingClauses.add(havingClause);
+    }
+    SelectBlock selectBlock = new SelectBlock(selectClause, fromClause, fromLetWhereClauses, groupbyClause,
+      gbyLetHavingClauses);
     selectBlock.setSourceLocation(startSrcLoc);
     return selectBlock;
   }

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 2
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Ali Alsuliman <al...@gmail.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-Reviewer: Till Westmann <ti...@apache.org>

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-ensure-ancestor/2956/ (11/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1: Integration-Tests-1

Integration Tests Failed

https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-integration-tests/7773/ : UNSTABLE

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Integration Tests Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-integration-tests/7771/

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-asterix-app-sql-execution/4954/ (13/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/hyracks-gerrit/4858/ (6/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

BAD Compatibility Tests Started https://asterix-jenkins.ics.uci.edu/job/asterixbad-compat/3902/

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-verify-no-installer-app/5285/ (14/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-notopic/10428/ (4/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1: -Integration-Tests

Integration Tests Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-integration-tests/7775/

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1: Integration-Tests+1

Integration Tests Successful

https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-integration-tests/7775/ : SUCCESS

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-verify-asterix-app/5330/ (5/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-stabilization-f69489-compat/356/ (1/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-asterix-app-openjdk11/351/ (12/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Anon. E. Moose (Code Review)" <do...@asterixdb.incubator.apache.org>.
Anon. E. Moose #1000171 has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1: Contrib-2

Analytics Compatibility Compilation Failed
https://goo.gl/uAppQS : UNSTABLE

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1: Contrib+1

BAD Compatibility Tests Successful

https://asterix-jenkins.ics.uci.edu/job/asterixbad-compat/3902/ : SUCCESS

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Ali Alsuliman (Code Review)" <do...@asterixdb.incubator.apache.org>.
Ali Alsuliman has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1: Code-Review+2

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Ali Alsuliman <al...@gmail.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-source-assemblies/5169/ (7/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-sonar/8895/ (2/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-source-format/4912/ (3/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1: Integration-Tests-1

Integration Tests Failed

https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-integration-tests/7771/ : UNSTABLE

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-asterix-app-sql-execution/4956/ (14/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Anon. E. Moose #1000171
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-verify-storage/5516/ (9/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-verify-txnlog/112/ (10/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No

Change in asterixdb[master]: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a sin...

Posted by "Jenkins (Code Review)" <do...@asterixdb.incubator.apache.org>.
Jenkins has posted comments on this change.

Change subject: [ASTERIXDB-2511][COMP] Refactor LET/WHERE clauses into a single list
......................................................................


Patch Set 1:

Build Started https://asterix-jenkins.ics.uci.edu/job/asterix-gerrit-cancellation-test/4946/ (8/14)

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/3118
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: I9265dfc3adb9ef4d5eb963b0aa4d39c2ad0cc068
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <dm...@couchbase.com>
Gerrit-Reviewer: Jenkins <je...@fulliautomatix.ics.uci.edu>
Gerrit-HasComments: No