You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by mb...@apache.org on 2021/06/30 00:11:22 UTC

[asterixdb] 02/23: [ASTERIXDB-2797][COMP] Fix casting elements of a list constructor

This is an automated email from the ASF dual-hosted git repository.

mblow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git

commit 4b66ee093cd45880db52913d2ac16bd07c7a895b
Author: Ali Alsuliman <al...@gmail.com>
AuthorDate: Thu Jun 3 17:28:29 2021 +0300

    [ASTERIXDB-2797][COMP] Fix casting elements of a list constructor
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    Currently, variable elements in a list constructor are always wrapped
    in cast() which would cast the variable to open type (when the variable
    type is a complex type, e.g. record). The required target type should
    be taken into account to decide whether to cast or not.
    
    Change-Id: If18467115e7e497af1b3bc1b76d8ff64adf14c4a
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/11743
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
    Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
---
 .../rules/IntroduceEnforcedListTypeRule.java       |  1 +
 .../rules/typecast/StaticTypeCastUtil.java         | 31 +++++++++++++---------
 .../list/var-in-list/var-in-list.01.ddl.sqlpp      | 30 +++++++++++++++++++++
 .../list/var-in-list/var-in-list.02.update.sqlpp   | 23 ++++++++++++++++
 .../list/var-in-list/var-in-list.03.query.sqlpp    | 22 +++++++++++++++
 .../list/var-in-list/var-in-list.04.query.sqlpp    | 22 +++++++++++++++
 .../list/var-in-list/var-in-list.05.query.sqlpp    | 22 +++++++++++++++
 .../list/var-in-list/var-in-list.06.query.sqlpp    | 22 +++++++++++++++
 .../results/list/var-in-list/var-in-list.03.adm    |  2 ++
 .../results/list/var-in-list/var-in-list.04.adm    |  2 ++
 .../results/list/var-in-list/var-in-list.05.adm    |  2 ++
 .../results/list/var-in-list/var-in-list.06.adm    |  2 ++
 .../test/resources/runtimets/testsuite_sqlpp.xml   |  5 ++++
 13 files changed, 174 insertions(+), 12 deletions(-)

diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceEnforcedListTypeRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceEnforcedListTypeRule.java
index 72f24b0..723fff2 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceEnforcedListTypeRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/IntroduceEnforcedListTypeRule.java
@@ -64,6 +64,7 @@ public class IntroduceEnforcedListTypeRule implements IAlgebraicRewriteRule {
          * rewrite list constructor types for list constructor functions
          */
         List<Mutable<ILogicalExpression>> expressions;
+        // TODO(ali): what about other operators that could have list expressions?
         switch (op.getOperatorTag()) {
             case ASSIGN:
                 AbstractAssignOperator assignOp = (AbstractAssignOperator) op;
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
index ac2460e..e96a192 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/typecast/StaticTypeCastUtil.java
@@ -69,7 +69,7 @@ import org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo;
  *
  * @author yingyib
  */
-public class StaticTypeCastUtil {
+public final class StaticTypeCastUtil {
 
     private StaticTypeCastUtil() {
     }
@@ -82,10 +82,11 @@ public class StaticTypeCastUtil {
      * rule: @ IntroduceEnforcedListTypeRule.
      *
      * @param funcExpr
-     *            record constructor function expression
+     *            a function expression
      * @param reqType
-     *            required record type
+     *            required (list) type (for when the funcExpr is a list constructor)
      * @param inputType
+     *            inferred (list) type (for when the funcExpr is a list constructor)
      * @param env
      *            type environment
      * @throws AlgebricksException
@@ -136,7 +137,7 @@ public class StaticTypeCastUtil {
      * @param reqType
      *            the required type inferred from parent operators/expressions
      * @param inputType
-     *            the current inferred
+     *            the current inferred type
      * @param env
      *            the type environment
      * @return true if the type is casted; otherwise, false.
@@ -162,6 +163,7 @@ public class StaticTypeCastUtil {
             return rewriteListFuncExpr(funcExpr, (AbstractCollectionType) reqType, (AbstractCollectionType) inputType,
                     env);
         } else if (inputType.getTypeTag().equals(ATypeTag.OBJECT)) {
+            // TODO(ali): inputType? shouldn't we check against the funcExpr whether it's a record constructor?
             if (reqType.equals(BuiltinType.ANY)) {
                 reqType = DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE;
             }
@@ -186,13 +188,14 @@ public class StaticTypeCastUtil {
     }
 
     /**
-     * only called when funcExpr is record constructor
+     * Only called when funcExpr's inferred type (the inputRecordType) is a record.
      *
      * @param funcExpr
-     *            record constructor function expression
+     *            a function expression that produces a record
      * @param requiredRecordType
      *            required record type
      * @param inputRecordType
+     *            inferred record type of funcExpr
      * @param env
      *            type environment
      * @throws AlgebricksException
@@ -213,13 +216,14 @@ public class StaticTypeCastUtil {
     }
 
     /**
-     * only called when funcExpr is list constructor
+     * Only called when funcExpr is list constructor.
      *
      * @param funcExpr
      *            list constructor function expression
      * @param requiredListType
      *            required list type
      * @param inputListType
+     *            inferred list type
      * @param env
      *            type environment
      * @throws AlgebricksException
@@ -247,19 +251,22 @@ public class StaticTypeCastUtil {
                 case FUNCTION_CALL:
                     ScalarFunctionCallExpression argFunc = (ScalarFunctionCallExpression) arg;
                     changed |= rewriteFuncExpr(argFunc, requiredItemType, currentItemType, env);
-                    changed |= castItem(argRef, argFunc, requiredItemType, env);
+                    changed |= castItem(argRef, requiredItemType, env);
                     break;
                 case VARIABLE:
-                    // TODO(ali): why are we always casting to an open type without considering "requiredItemType"?
-                    changed |= injectCastToRelaxType(argRef, currentItemType, env);
+                    changed |= castItem(argRef, requiredItemType, env);
+                    break;
+                case CONSTANT:
+                    // TODO(ali): should the constant be handled (i.e. constant array or record)?
                     break;
             }
         }
         return changed;
     }
 
-    private static boolean castItem(Mutable<ILogicalExpression> itemExprRef, ScalarFunctionCallExpression itemExpr,
-            IAType requiredItemType, IVariableTypeEnvironment env) throws AlgebricksException {
+    private static boolean castItem(Mutable<ILogicalExpression> itemExprRef, IAType requiredItemType,
+            IVariableTypeEnvironment env) throws AlgebricksException {
+        ILogicalExpression itemExpr = itemExprRef.getValue();
         IAType itemType = (IAType) env.getType(itemExpr);
         if (TypeResolverUtil.needsCast(requiredItemType, itemType) && !satisfied(requiredItemType, itemType)) {
             injectCastFunction(FunctionUtil.getFunctionInfo(BuiltinFunctions.CAST_TYPE), requiredItemType, itemType,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.01.ddl.sqlpp
new file mode 100644
index 0000000..5b2b740
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.01.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 t1 AS {id: int};
+CREATE DATASET ds1(t1) primary key id;
+
+CREATE FUNCTION fun1(r) {
+   (SELECT VALUE x FROM [r] AS x)[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.02.update.sqlpp
new file mode 100644
index 0000000..7535183
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.02.update.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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 ds1 {"id": 1, "f1": "foo"};
+INSERT INTO ds1 {"id": 2, "f1": "bar"};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.03.query.sqlpp
new file mode 100644
index 0000000..b9a79b6
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.03.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+FROM ds1 AS v SELECT [v] AS list ORDER BY list;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.04.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.04.query.sqlpp
new file mode 100644
index 0000000..d61e5be
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.04.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+FROM ds1 AS s SELECT fun1(s) AS list ORDER BY list;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.05.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.05.query.sqlpp
new file mode 100644
index 0000000..42c7031
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.05.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+FROM [{'a':5}, {'a':7}] AS s SELECT fun1(s) AS list ORDER BY list;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.06.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.06.query.sqlpp
new file mode 100644
index 0000000..924b4b8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/list/var-in-list/var-in-list.06.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * 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;
+
+FROM [{'a':5}, {'b':7}] AS s SELECT fun1(s) AS list ORDER BY list;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.03.adm
new file mode 100644
index 0000000..17ad9c9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.03.adm
@@ -0,0 +1,2 @@
+{ "list": [ { "id": 2, "f1": "bar" } ] }
+{ "list": [ { "id": 1, "f1": "foo" } ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.04.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.04.adm
new file mode 100644
index 0000000..b875625
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.04.adm
@@ -0,0 +1,2 @@
+{ "list": { "id": 2, "f1": "bar" } }
+{ "list": { "id": 1, "f1": "foo" } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.05.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.05.adm
new file mode 100644
index 0000000..4721f1c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.05.adm
@@ -0,0 +1,2 @@
+{ "list": { "a": 5 } }
+{ "list": { "a": 7 } }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.06.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.06.adm
new file mode 100644
index 0000000..ff72349
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/list/var-in-list/var-in-list.06.adm
@@ -0,0 +1,2 @@
+{ "list": { "a": 5 } }
+{ "list": { "b": 7 } }
\ 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 ce1303b..af6ca78 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -6140,6 +6140,11 @@
         <output-dir compare="Text">query-ASTERIXDB-159-3</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="list">
+      <compilation-unit name="var-in-list">
+        <output-dir compare="Text">var-in-list</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="misc">
     <test-case FilePath="misc">