Merge branch 'gerrit/neo' into 'gerrit/trinity'

Ext-ref: MB-63443, MB-63466, MB-63044, MB-63356, MB-63207
Change-Id: I7675cf87467912d79297bd4d2e62275da866df8d
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
index 366da5a..93c4ea2 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/CancelUnnestWithNestedListifyRule.java
@@ -28,6 +28,7 @@
 import org.apache.commons.lang3.mutable.Mutable;
 import org.apache.commons.lang3.mutable.MutableObject;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.common.utils.ListSet;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
@@ -119,6 +120,10 @@
         AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
         VariableUtilities.getUsedVariables(op, varSet);
         if (op.hasNestedPlans()) {
+            // Variables used by the parent operators should be live at op.
+            Set<LogicalVariable> localLiveVars = new ListSet<>();
+            VariableUtilities.getLiveVariables(op, localLiveVars);
+            varSet.retainAll(localLiveVars);
             AbstractOperatorWithNestedPlans aonp = (AbstractOperatorWithNestedPlans) op;
             for (ILogicalPlan p : aonp.getNestedPlans()) {
                 for (Mutable<ILogicalOperator> r : p.getRoots()) {
@@ -198,8 +203,9 @@
             return false;
         }
 
-        if (OperatorManipulationUtil.ancestorOfOperators(agg, ImmutableSet.of(LogicalOperatorTag.LIMIT,
-                LogicalOperatorTag.ORDER, LogicalOperatorTag.GROUP, LogicalOperatorTag.DISTINCT))) {
+        if (OperatorManipulationUtil.ancestorOfOperatorsExcludeCurrent(agg,
+                ImmutableSet.of(LogicalOperatorTag.LIMIT, LogicalOperatorTag.ORDER, LogicalOperatorTag.GROUP,
+                        LogicalOperatorTag.DISTINCT, LogicalOperatorTag.AGGREGATE))) {
             return false;
         }
 
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/remove_listify.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/remove_listify.sqlpp
new file mode 100644
index 0000000..d6475f3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/remove_listify.sqlpp
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop  dataverse test if exists;
+create  dataverse test;
+
+use test;
+
+
+create type dt as
+{
+  uid : integer
+};
+
+create  dataset collection1(dt) primary key uid;
+
+SET `rewrite_or_as_join` "false";
+WITH table23 AS(
+  SELECT f1,
+         f2
+  FROM collection1 b),
+table22 AS(
+  SELECT f1,
+         (
+           SELECT COUNT(1) FILTER(WHERE b.f2>=a.f2-5 AND b.f2<=a.f2) AS counts
+           FROM table23 b
+           WHERE b.f1=a.f1
+          )[0] counts
+  FROM table23 a)
+SELECT
+     value a
+FROM table22 a;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/remove_listify.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/remove_listify.plan
new file mode 100644
index 0000000..96d4248
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/remove_listify.plan
@@ -0,0 +1,36 @@
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    -- STREAM_PROJECT  |PARTITIONED|
+      -- ASSIGN  |PARTITIONED|
+        -- STREAM_PROJECT  |PARTITIONED|
+          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+            -- PRE_CLUSTERED_GROUP_BY[$$141]  |PARTITIONED|
+                    {
+                      -- AGGREGATE  |LOCAL|
+                        -- AGGREGATE  |LOCAL|
+                          -- STREAM_SELECT  |LOCAL|
+                            -- ASSIGN  |LOCAL|
+                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                    }
+              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                -- STABLE_SORT [$$141(ASC)]  |PARTITIONED|
+                  -- HASH_PARTITION_EXCHANGE [$$141]  |PARTITIONED|
+                    -- STREAM_PROJECT  |PARTITIONED|
+                      -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                        -- HYBRID_HASH_JOIN [$$146][$$148]  |PARTITIONED|
+                          -- HASH_PARTITION_EXCHANGE [$$146]  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                  -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                          -- HASH_PARTITION_EXCHANGE [$$148]  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- ASSIGN  |PARTITIONED|
+                                -- ASSIGN  |PARTITIONED|
+                                  -- STREAM_PROJECT  |PARTITIONED|
+                                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                      -- DATASOURCE_SCAN (test.collection1)  |PARTITIONED|
+                                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                          -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated.plan
index 540e821..42c8f8f 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated.plan
@@ -12,20 +12,13 @@
                             {
                               -- AGGREGATE  |LOCAL|
                                 -- STREAM_SELECT  |LOCAL|
-                                  -- UNNEST  |LOCAL|
-                                    -- MICRO_PRE_CLUSTERED_GROUP_BY[]  |LOCAL|
-                                            {
-                                              -- AGGREGATE  |LOCAL|
-                                                -- STREAM_SELECT  |LOCAL|
-                                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                            }
-                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
                             }
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                         -- HYBRID_HASH_JOIN [$$49][$$48]  |PARTITIONED|
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            -- STREAM_SELECT  |PARTITIONED|
-                              -- ASSIGN  |PARTITIONED|
+                            -- STREAM_PROJECT  |PARTITIONED|
+                              -- STREAM_SELECT  |PARTITIONED|
                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                   -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -37,4 +30,4 @@
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                     -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated_ps.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated_ps.plan
index 6080780..85eb2da 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated_ps.plan
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/subquery/in_correlated_ps.plan
@@ -16,20 +16,13 @@
                                     {
                                       -- AGGREGATE  |LOCAL|
                                         -- STREAM_SELECT  |LOCAL|
-                                          -- UNNEST  |LOCAL|
-                                            -- MICRO_PRE_CLUSTERED_GROUP_BY[]  |LOCAL|
-                                                    {
-                                                      -- AGGREGATE  |LOCAL|
-                                                        -- STREAM_SELECT  |LOCAL|
-                                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                    }
-                                              -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                          -- NESTED_TUPLE_SOURCE  |LOCAL|
                                     }
                               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                 -- HYBRID_HASH_JOIN [$$49][$$48]  |PARTITIONED|
                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                    -- STREAM_SELECT  |PARTITIONED|
-                                      -- ASSIGN  |PARTITIONED|
+                                    -- STREAM_PROJECT  |PARTITIONED|
+                                      -- STREAM_SELECT  |PARTITIONED|
                                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                           -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
                                             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -56,20 +49,13 @@
                                             {
                                               -- AGGREGATE  |LOCAL|
                                                 -- STREAM_SELECT  |LOCAL|
-                                                  -- UNNEST  |LOCAL|
-                                                    -- MICRO_PRE_CLUSTERED_GROUP_BY[]  |LOCAL|
-                                                            {
-                                                              -- AGGREGATE  |LOCAL|
-                                                                -- STREAM_SELECT  |LOCAL|
-                                                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
-                                                            }
-                                                      -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                                  -- NESTED_TUPLE_SOURCE  |LOCAL|
                                             }
                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                         -- HYBRID_HASH_JOIN [$$49][$$48]  |PARTITIONED|
                                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                            -- STREAM_SELECT  |PARTITIONED|
-                                              -- ASSIGN  |PARTITIONED|
+                                            -- STREAM_PROJECT  |PARTITIONED|
+                                              -- STREAM_SELECT  |PARTITIONED|
                                                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                   -- DATASOURCE_SCAN (test.Customers)  |PARTITIONED|
                                                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
@@ -81,4 +67,4 @@
                                                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
                                                     -- DATASOURCE_SCAN (test.Orders)  |PARTITIONED|
                                                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
+                                                        -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.1.ddl.sqlpp
new file mode 100644
index 0000000..c240470
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.1.ddl.sqlpp
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description: This test case is to verify the fix for ASTERIXDB-3490
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type dt1 as {id: int};
+
+create dataset collection1(dt1) PRIMARY KEY id;
+create dataset collection2(dt1) PRIMARY KEY id;
+create dataset collection3(dt1) PRIMARY KEY id;
+create dataset collection4(dt1) PRIMARY KEY id;
+create dataset collection5(dt1) PRIMARY KEY id;
+create dataset collection6(dt1) PRIMARY KEY id;
+
+create dataset dataset0(dt1) PRIMARY KEY id;
+create dataset dataset1(dt1) PRIMARY KEY id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.2.update.sqlpp
new file mode 100644
index 0000000..8b127ab
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.2.update.sqlpp
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use test;
+
+upsert into collection1
+[
+    {
+        "id":1,
+        "t1":10,
+        "t2":10,
+        "t":10,
+        "p1":3,
+        "p2":3,
+        "p":3
+    }
+];
+
+upsert into collection2
+[
+    {
+        "id":1,
+        "t1":10,
+        "t2":10,
+        "t":10,
+        "p1":3,
+        "p2":3,
+        "p":3
+    }
+];
+
+upsert into collection3
+[
+    {
+        "id":1,
+        "t1":10,
+        "t2":10,
+        "t":10,
+        "p1":3,
+        "p2":3,
+        "p":3
+    }
+];
+
+upsert into collection4
+[
+    {
+        "id":1,
+        "t1":10,
+        "t2":10,
+        "t":10,
+        "p1":3,
+        "p2":3,
+        "p":3
+    }
+];
+
+upsert into collection5
+[
+    {
+        "id":1,
+        "t1":10,
+        "t2":10,
+        "t":10,
+        "p1":3,
+        "p2":3,
+        "p":3
+    }
+];
+
+upsert into collection6
+[
+    {
+        "id":1,
+        "t1":10,
+        "t2":10,
+        "t":10,
+        "p1":3,
+        "p2":3,
+        "p":3
+    }
+];
+
+
+upsert into dataset0
+    [{
+        "id":10,
+        "a":12,
+        "y_id":10,
+        "b":20,
+        "u": 101,
+        "x_id":10,
+        "p":3
+    }];
+
+upsert into dataset1
+    [{
+        "id":1,
+        "a":12,
+        "y_id":10,
+        "b":20,
+        "u": 101,
+        "x_id":10,
+        "p":3
+    }];
+
+
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.3.query.sqlpp
new file mode 100644
index 0000000..f319efc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.3.query.sqlpp
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description: This test case is to verify the fix for ASTERIXDB-3490
+ */
+
+use test;
+
+SELECT value a1
+FROM collection1 a1
+WHERE (
+    SELECT  value count(*)
+    FROM collection2 a2
+    WHERE a1.t=a2.t and a1.p=3 and (
+       SELECT value count(*)
+        FROM collection3 a3
+        WHERE a2.t1=a3.t1 and a2.p1=3 and (
+            SELECT value count(*)
+                FROM collection4 a4
+                WHERE a3.t2=a4.t2 and a3.p2=3 and (
+                    SELECT value count(*)
+                        FROM collection5 a5
+                        WHERE a4.t=a5.t and a4.p=3 and (
+                        SELECT value count(*)
+                            FROM collection6 a6
+                            WHERE a5.t1=a6.t1 and a5.p1=3
+                        )[0] >= 1
+                    )[0] >= 1
+                )[0] >= 1
+        )[0] >= 1
+    )[0] >= 1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.4.query.sqlpp
new file mode 100644
index 0000000..2313a6d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.4.query.sqlpp
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description: This test case is to verify the fix for ASTERIXDB-3490
+ */
+
+use test;
+
+SET `rewrite_or_as_join` "false";
+SELECT DISTINCT T1.*,
+                (SELECT VALUE H.u
+                  FROM dataset1 H
+                  WHERE H.y_id = to_string(T1.x_id)
+                    AND H.a IN [12, 66, 67, 13, 26]
+                    AND H.b IN
+                        (SELECT value MAX(L.b)
+                           FROM dataset1 L
+                          WHERE L.y_id = T1.x_id
+                            AND L.a IN [12, 66, 67, 13, 26]
+                            )
+                            LIMIT 1
+                )[0] AS sub_q1,
+                b_max
+FROM (SELECT ROW_NUMBER() OVER(ORDER BY sub_q2.b_max DESC NULLS LAST) AS ROW_NUMBER,
+             T0.x_id,
+             sub_q2.b_max
+      FROM dataset0 T0 INNER JOIN
+      (SELECT y_id, MAX(b) b_max
+       FROM dataset1 T2
+       GROUP BY y_id) AS sub_q2
+      ON sub_q2.y_id = T0.id
+) T1;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.1.ddl.sqlpp
new file mode 100644
index 0000000..498f374
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.1.ddl.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop  dataverse test if exists;
+create  dataverse test;
+
+use test;
+
+create type dt as
+{
+  uid : integer
+};
+
+create  dataset collection1(dt) primary key uid;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.2.update.sqlpp
new file mode 100644
index 0000000..ac2cc1b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.2.update.sqlpp
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use test;
+
+insert into collection1
+([
+
+    {
+        "uid":1,
+        "f1":101,
+        "f2": 24
+    },
+    {
+        "uid":2,
+        "f1":102,
+        "f2": 25
+    },
+    {
+        "uid":3,
+        "f1":102,
+        "f2": 25
+    },
+    {
+        "uid":4,
+        "f1":102,
+        "f2": 31
+    },
+    {
+        "uid":5,
+        "f1":103,
+        "f2": 24
+    },
+    {
+        "uid":6,
+        "f1":103,
+        "f2": 30
+    },
+    {
+        "uid":7,
+        "f1":103,
+        "f2": 31
+    },
+    {
+        "uid":8,
+        "f1":103,
+        "f2": 35
+    },
+    {
+        "uid":9,
+        "f1":103,
+        "f2": 41
+    },
+    {
+        "uid":10,
+        "f1":104,
+        "f2": 42
+    },
+    {
+        "uid":11,
+        "f1":104,
+        "f2": 24
+    },
+    {
+        "uid":12,
+        "f1":104,
+        "f2": 25
+    },
+    {
+        "uid":13,
+        "f1":105,
+        "f2": 24
+    },
+    {
+        "uid":14,
+        "f1":105,
+        "f2": 25
+    },
+    {
+        "uid":15,
+        "f1":105,
+        "f2": "40"
+    }
+])
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.3.query.sqlpp
new file mode 100644
index 0000000..8652bba
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/misc/remove_listify/remove_listify.3.query.sqlpp
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use test;
+
+SET `rewrite_or_as_join` "false";
+WITH table23 AS(
+  SELECT f1,
+         f2
+  FROM collection1 b),
+table22 AS(
+  SELECT f1,
+         (
+           SELECT COUNT(1) FILTER(WHERE b.f2>=a.f2-5 AND b.f2<=a.f2) AS counts
+           FROM table23 b
+           WHERE b.f1=a.f1
+          )[0] obj
+  FROM table23 a)
+SELECT
+     a.f1, a.obj.counts
+FROM table22 a
+order by a.f1, a.obj.counts;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.3.adm
new file mode 100644
index 0000000..22c03b0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.3.adm
@@ -0,0 +1 @@
+{ "id": 1, "t1": 10, "t2": 10, "t": 10, "p1": 3, "p2": 3, "p": 3 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.4.adm
new file mode 100644
index 0000000..a617f17
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-3490/query-ASTERIXDB-3490.4.adm
@@ -0,0 +1 @@
+{ "b_max": 20, "ROW_NUMBER": 1, "x_id": 10 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/remove_listify/remove_listify.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/remove_listify/remove_listify.3.adm
new file mode 100644
index 0000000..a4142d4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/remove_listify/remove_listify.3.adm
@@ -0,0 +1,15 @@
+{ "counts": 1, "f1": 101 }
+{ "counts": 1, "f1": 102 }
+{ "counts": 2, "f1": 102 }
+{ "counts": 2, "f1": 102 }
+{ "counts": 1, "f1": 103 }
+{ "counts": 1, "f1": 103 }
+{ "counts": 1, "f1": 103 }
+{ "counts": 2, "f1": 103 }
+{ "counts": 3, "f1": 103 }
+{ "counts": 1, "f1": 104 }
+{ "counts": 1, "f1": 104 }
+{ "counts": 2, "f1": 104 }
+{ "counts": 0, "f1": 105 }
+{ "counts": 1, "f1": 105 }
+{ "counts": 2, "f1": 105 }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index b8f6346..03bd819 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -7345,6 +7345,21 @@
           <output-dir compare="Text">query-ASTERIXDB-3481</output-dir>
       </compilation-unit>
     </test-case>
+      <test-case FilePath="misc">
+        <compilation-unit name="query-ASTERIXDB-3490">
+          <output-dir compare="Text">query-ASTERIXDB-3490</output-dir>
+        </compilation-unit>
+      </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="query-ASTERIXDB-3316">
+        <output-dir compare="Text">query-ASTERIXDB-3316</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="remove_listify">
+        <output-dir compare="Text">remove_listify</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="multipart-dataverse">
     <test-case FilePath="multipart-dataverse">
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java
index dc2d017..b820003 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java
@@ -963,7 +963,7 @@
     }
 
     public AlgebricksAbsolutePartitionConstraint getClusterLocations() {
-        return appCtx.getClusterStateManager().getClusterLocations();
+        return appCtx.getClusterStateManager().getSortedClusterLocations();
     }
 
     public Pair<IOperatorDescriptor, AlgebricksPartitionConstraint> buildExternalDataLookupRuntime(
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
index 38ccee5..c9f59c6 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/physical/AbstractHashJoinPOperator.java
@@ -168,7 +168,9 @@
                                         EquivalenceClass ecFst = eqmap.get(v2);
                                         for (LogicalVariable vset1 : set1) {
                                             if (vset1 == v2 || ecFst != null && eqmap.get(vset1) == ecFst) {
-                                                covered.add(vset1);
+                                                if (!covered.add(vset1)) {
+                                                    continue;
+                                                }
                                                 modifuppreq.add(r);
                                                 break;
                                             }
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
index 3457751..2413ed2 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/util/OperatorManipulationUtil.java
@@ -361,6 +361,15 @@
         return false;
     }
 
+    public static boolean ancestorOfOperatorsExcludeCurrent(ILogicalOperator op, Set<LogicalOperatorTag> tags) {
+        for (Mutable<ILogicalOperator> children : op.getInputs()) {
+            if (ancestorOfOperators(children.getValue(), tags)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Returns all descendants of an operator that are leaf operators
      *