[ASTERIXDB-2696][COMP] Incorrect result with nested subplans

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

Details:
- EliminateSubplanWithInputCardinalityOneRule was
  incorrectly inlining subplan inside another subplan

Change-Id: I232da4acc36e0389bfb61f728e8f2b00974053be
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/4964
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/quantifiers/query-ASTERIXDB-2696.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/quantifiers/query-ASTERIXDB-2696.sqlpp
new file mode 100644
index 0000000..3f2988a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/quantifiers/query-ASTERIXDB-2696.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+from [
+   { "a": 1, "b": [ 10, 20, 30] },
+   { "a": 1, "b": [ 40, 50, 60] },
+   { "a": 1, "b": [ 70, 80, 90] },
+   { "a": 2, "b": [ 100, 200, 300] },
+   { "a": 2, "b": [ 400, 500, 600] },
+   { "a": 2, "b": [ 700, 800, 900] }
+] t
+group by a
+select a, sum( case when some x in b satisfies x >= 50 then 1 else 0 end) as s;
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/results/quantifiers/query-ASTERIXDB-2696.plan b/asterixdb/asterix-app/src/test/resources/optimizerts/results/quantifiers/query-ASTERIXDB-2696.plan
new file mode 100644
index 0000000..26b18be
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/results/quantifiers/query-ASTERIXDB-2696.plan
@@ -0,0 +1,25 @@
+-- DISTRIBUTE_RESULT  |LOCAL|
+  -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+    -- STREAM_PROJECT  |LOCAL|
+      -- ASSIGN  |LOCAL|
+        -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+          -- PRE_CLUSTERED_GROUP_BY[$$67]  |LOCAL|
+                  {
+                    -- AGGREGATE  |LOCAL|
+                      -- AGGREGATE  |LOCAL|
+                        -- SUBPLAN  |LOCAL|
+                                {
+                                  -- AGGREGATE  |LOCAL|
+                                    -- STREAM_SELECT  |LOCAL|
+                                      -- UNNEST  |LOCAL|
+                                        -- NESTED_TUPLE_SOURCE  |LOCAL|
+                                }
+                          -- NESTED_TUPLE_SOURCE  |LOCAL|
+                  }
+            -- ONE_TO_ONE_EXCHANGE  |LOCAL|
+              -- STABLE_SORT [$$67(ASC)]  |LOCAL|
+                -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+                  -- STREAM_PROJECT  |UNPARTITIONED|
+                    -- ASSIGN  |UNPARTITIONED|
+                      -- UNNEST  |UNPARTITIONED|
+                        -- EMPTY_TUPLE_SOURCE  |UNPARTITIONED|
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-2696/query-ASTERIXDB-2696.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-2696/query-ASTERIXDB-2696.1.query.sqlpp
new file mode 100644
index 0000000..3f2988a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/quantifiers/query-ASTERIXDB-2696/query-ASTERIXDB-2696.1.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+from [
+   { "a": 1, "b": [ 10, 20, 30] },
+   { "a": 1, "b": [ 40, 50, 60] },
+   { "a": 1, "b": [ 70, 80, 90] },
+   { "a": 2, "b": [ 100, 200, 300] },
+   { "a": 2, "b": [ 400, 500, 600] },
+   { "a": 2, "b": [ 700, 800, 900] }
+] t
+group by a
+select a, sum( case when some x in b satisfies x >= 50 then 1 else 0 end) as s;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/quantifiers/query-ASTERIXDB-2696/query-ASTERIXDB-2696.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/quantifiers/query-ASTERIXDB-2696/query-ASTERIXDB-2696.1.adm
new file mode 100644
index 0000000..fcf5cee
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/quantifiers/query-ASTERIXDB-2696/query-ASTERIXDB-2696.1.adm
@@ -0,0 +1,2 @@
+{ "a": 1, "s": 2 }
+{ "a": 2, "s": 3 }
\ 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 206474a..6b5da4d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -7955,6 +7955,11 @@
         <output-dir compare="Text">query-ASTERIXDB-2307</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="quantifiers">
+      <compilation-unit name="query-ASTERIXDB-2696">
+        <output-dir compare="Text">query-ASTERIXDB-2696</output-dir>
+      </compilation-unit>
+    </test-case>
     <!--
         <test-case FilePath="quantifiers">
           <compilation-unit name="everysat_02">
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java
index 64d1b61..54cbcd0 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/algebra/operators/logical/visitors/CardinalityInferenceVisitor.java
@@ -26,6 +26,7 @@
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 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.LogicalOperatorTag;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable;
 import org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression;
 import org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator;
@@ -147,7 +148,7 @@
 
     @Override
     public Long visitNestedTupleSourceOperator(NestedTupleSourceOperator op, Void arg) throws AlgebricksException {
-        return ONE;
+        return op.getDataSourceReference().getValue().getOperatorTag() == LogicalOperatorTag.SUBPLAN ? ONE : UNKNOWN;
     }
 
     @Override