Yingyi Bu has uploaded a new change for review.

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

Change subject: ASTERIXDB-1631: let TypeComputeUitls handle input type ANY 
properly.
......................................................................

ASTERIXDB-1631: let TypeComputeUitls handle input type ANY properly.

Change-Id: Ie6b3f0e9d9b4ddd9280e06f72a5ca30aa776315d
---
M asterixdb/asterix-om/pom.xml
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
D 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FlowRecordResultTypeComputer.java
R 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NotUnknownTypeComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NullableDoubleTypeComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/TypeComputeUtils.java
A 
asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
9 files changed, 142 insertions(+), 80 deletions(-)


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

diff --git a/asterixdb/asterix-om/pom.xml b/asterixdb/asterix-om/pom.xml
index 60fa26c..72bf65e 100644
--- a/asterixdb/asterix-om/pom.xml
+++ b/asterixdb/asterix-om/pom.xml
@@ -74,5 +74,11 @@
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <version>1.10.19</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
index 184dd84..a85d33b 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/AsterixBuiltinFunctions.java
@@ -68,7 +68,7 @@
 import org.apache.asterix.om.typecomputer.impl.LocalAvgTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.MinMaxAggTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NonTaggedGetItemResultType;
-import org.apache.asterix.om.typecomputer.impl.NotMissingTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.NotUnknownTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NullableDoubleTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NumericAddSubMulDivTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.NumericAggTypeComputer;
@@ -810,7 +810,7 @@
         addFunction(DEEP_EQUAL, BooleanFunctionTypeComputer.INSTANCE, true);
 
         // and then, Asterix builtin functions
-        addPrivateFunction(CHECK_UNKNOWN, NotMissingTypeComputer.INSTANCE, 
true);
+        addPrivateFunction(CHECK_UNKNOWN, NotUnknownTypeComputer.INSTANCE, 
true);
         addPrivateFunction(ANY_COLLECTION_MEMBER, 
CollectionMemberResultType.INSTANCE, true);
         addFunction(BOOLEAN_CONSTRUCTOR, StringBooleanTypeComputer.INSTANCE, 
true);
         addFunction(CARET, NumericAddSubMulDivTypeComputer.INSTANCE, true);
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FlowRecordResultTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FlowRecordResultTypeComputer.java
deleted file mode 100644
index 27e8a3d..0000000
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/FlowRecordResultTypeComputer.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.asterix.om.typecomputer.impl;
-
-import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
-import org.apache.asterix.om.typecomputer.base.TypeCastUtils;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import 
org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
-import 
org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression;
-import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
-
-public class FlowRecordResultTypeComputer implements IResultTypeComputer {
-
-    public static final FlowRecordResultTypeComputer INSTANCE = new 
FlowRecordResultTypeComputer();
-
-    @Override
-    public IAType computeType(ILogicalExpression expression, 
IVariableTypeEnvironment env,
-            IMetadataProvider<?, ?> metadataProvider) throws 
AlgebricksException {
-        ScalarFunctionCallExpression funcExpr = (ScalarFunctionCallExpression) 
expression;
-        IAType type = TypeCastUtils.getRequiredType(funcExpr);
-        if (type == null) {
-            type = (IAType) 
env.getType(funcExpr.getArguments().get(0).getValue());
-        }
-        return type;
-    }
-}
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NotMissingTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NotUnknownTypeComputer.java
similarity index 65%
rename from 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NotMissingTypeComputer.java
rename to 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NotUnknownTypeComputer.java
index 68444c4..163ff30 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NotMissingTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NotUnknownTypeComputer.java
@@ -19,9 +19,6 @@
 
 package org.apache.asterix.om.typecomputer.impl;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.AUnionType;
@@ -33,16 +30,13 @@
 import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
 
 /**
- * This class is the type computer for not-missing function.
+ * This class is the type computer for check-unknown function.
  * If the input type is not a union, we just return it.
- * If the input type is a union,
- * case 1: we return a new union without missing if the new union still has 
more than one types;
- * case 2: we return the non-missing item type in the original union if there 
are only missing
- * and it in the original union.
+ * If the input type is a union, we return the actual, non-null/non-missing 
type.
  */
-public class NotMissingTypeComputer implements IResultTypeComputer {
+public class NotUnknownTypeComputer implements IResultTypeComputer {
 
-    public static final NotMissingTypeComputer INSTANCE = new 
NotMissingTypeComputer();
+    public static final NotUnknownTypeComputer INSTANCE = new 
NotUnknownTypeComputer();
 
     @Override
     public IAType computeType(ILogicalExpression expression, 
IVariableTypeEnvironment env,
@@ -53,25 +47,7 @@
             // directly return the input type if it is not a union
             return type;
         }
-
         AUnionType unionType = (AUnionType) type;
-        List<IAType> items = new ArrayList<>();
-        // copy the item types
-        items.addAll(unionType.getUnionList());
-
-        // remove missing
-        for (int i = items.size() - 1; i >= 0; i--) {
-            IAType itemType = items.get(i);
-            if (itemType.getTypeTag() == ATypeTag.MISSING) {
-                items.remove(i);
-            }
-        }
-        if (items.size() == 1) {
-            //only one type is left
-            return items.get(0);
-        } else {
-            //more than two types are left
-            return new AUnionType(items, unionType.getTypeName());
-        }
+        return unionType.getActualType();
     }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NullableDoubleTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NullableDoubleTypeComputer.java
index 94c75d2..be3138d 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NullableDoubleTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/NullableDoubleTypeComputer.java
@@ -37,6 +37,6 @@
     @Override
     public IAType computeType(ILogicalExpression expression, 
IVariableTypeEnvironment env,
             IMetadataProvider<?, ?> metadataProvider) throws 
AlgebricksException {
-        return AUnionType.createMissableType(BuiltinType.ADOUBLE, 
"OptionalDouble");
+        return AUnionType.createNullableType(BuiltinType.ADOUBLE, 
"OptionalDouble");
     }
 }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java
index 289db7c..6d29c36 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddFieldsTypeComputer.java
@@ -40,7 +40,6 @@
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 import org.apache.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-import 
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractLogicalExpression;
 import 
org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
 import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
 
@@ -56,7 +55,6 @@
     @Override
     public IAType computeType(ILogicalExpression expression, 
IVariableTypeEnvironment env,
             IMetadataProvider<?, ?> metadataProvider) throws 
AlgebricksException {
-
         AbstractFunctionCallExpression funcExpr = 
(AbstractFunctionCallExpression) expression;
         IAType type0 = (IAType) 
env.getType(funcExpr.getArguments().get(0).getValue());
 
@@ -65,7 +63,7 @@
             throw new AlgebricksException("Input record cannot be null");
         }
 
-        AbstractLogicalExpression arg1 = (AbstractLogicalExpression) 
funcExpr.getArguments().get(1).getValue();
+        ILogicalExpression arg1 = funcExpr.getArguments().get(1).getValue();
         IAType type1 = (IAType) env.getType(arg1);
         AOrderedListType inputOrderedListType = 
TypeComputeUtils.extractOrderedListType(type1);
         if (inputOrderedListType == null) {
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java
index 40c57a4..3fcb9bb 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubsetCollectionTypeComputer.java
@@ -22,6 +22,7 @@
 import org.apache.asterix.om.types.ATypeTag;
 import org.apache.asterix.om.types.AUnionType;
 import org.apache.asterix.om.types.AbstractCollectionType;
+import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
@@ -65,6 +66,8 @@
                 }
                 throw new AlgebricksException("Expecting collection type. 
Found " + t);
             }
+            case ANY:
+                return BuiltinType.ANY;
             default: {
                 throw new AlgebricksException("Expecting collection type. 
Found " + t);
             }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/TypeComputeUtils.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/TypeComputeUtils.java
index 711b840..82311b3 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/TypeComputeUtils.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/TypeComputeUtils.java
@@ -124,6 +124,9 @@
                 return MISSING;
             } else if (inputTypeTag == ATypeTag.NULL) {
                 meetNull = true;
+            } else if (inputTypeTag == ATypeTag.ANY) {
+                category |= NULLABLE;
+                category |= MISSABLE;
             }
         }
         if (meetNull) {
@@ -133,6 +136,9 @@
     }
 
     private static IAType getResultType(IAType type, byte category) {
+        if (type.getTypeTag() == ATypeTag.ANY) {
+            return type;
+        }
         if (category == CERTAIN) {
             return type;
         }
@@ -185,6 +191,8 @@
                 } else {
                     return null;
                 }
+            case ANY:
+                return ARecordType.FULLY_OPEN_RECORD_TYPE;
             default:
                 return null;
         }
diff --git 
a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
 
b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
new file mode 100644
index 0000000..760fd18
--- /dev/null
+++ 
b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.om.typecomputer;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.commons.lang3.mutable.Mutable;
+import org.apache.commons.lang3.mutable.MutableObject;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+import org.junit.Assert;
+import org.junit.Test;
+import org.reflections.Reflections;
+import org.reflections.scanners.SubTypesScanner;
+
+// Tests if all type computers can handle input type ANY properly.
+public class TypeComputerTest {
+
+    @Test
+    public void test() throws Exception {
+        // Several exceptional type computers.
+        Set<String> exceptionalTypeComputers = new HashSet<>();
+        exceptionalTypeComputers.add("InjectFailureTypeComputer");
+        exceptionalTypeComputers.add("RecordAddFieldsTypeComputer");
+        exceptionalTypeComputers.add("OpenRecordConstructorResultType");
+        exceptionalTypeComputers.add("RecordRemoveFieldsTypeComputer");
+        exceptionalTypeComputers.add("ClosedRecordConstructorResultType");
+        exceptionalTypeComputers.add("LocalAvgTypeComputer");
+        exceptionalTypeComputers.add("BooleanOnlyTypeComputer");
+        exceptionalTypeComputers.add("AMissingTypeComputer");
+        exceptionalTypeComputers.add("NullableDoubleTypeComputer");
+        exceptionalTypeComputers.add("RecordMergeTypeComputer");
+
+        // Tests all usual type computers.
+        Reflections reflections = new 
Reflections("org.apache.asterix.om.typecomputer", new SubTypesScanner(false));
+        Set<Class<? extends IResultTypeComputer>> classes = 
reflections.getSubTypesOf(IResultTypeComputer.class);
+        for (Class<? extends IResultTypeComputer> c : classes) {
+            if (exceptionalTypeComputers.contains(c.getSimpleName()) || 
Modifier.isAbstract(c.getModifiers())) {
+                continue;
+            }
+            System.out.println("Test type computer: " + c.getName());
+            Assert.assertTrue(testTypeComputer(c));
+        }
+    }
+
+    private boolean testTypeComputer(Class<? extends IResultTypeComputer> c) 
throws Exception {
+        // Mocks the type environment.
+        IVariableTypeEnvironment mockTypeEnv = 
mock(IVariableTypeEnvironment.class);
+        // Mocks the metadata provider.
+        IMetadataProvider<?, ?> mockMetadataProvider = 
mock(IMetadataProvider.class);
+
+        // Mocks function expression.
+        AbstractFunctionCallExpression mockExpr = 
mock(AbstractFunctionCallExpression.class);
+
+        // A function at most has six argument.
+        List<Mutable<ILogicalExpression>> argRefs = new ArrayList<>();
+        for (int argIndex = 0; argIndex < 6; ++argIndex) {
+            ILogicalExpression mockArg = mock(ILogicalExpression.class);
+            argRefs.add(new MutableObject<>(mockArg));
+            when(mockTypeEnv.getType(mockArg)).thenReturn(BuiltinType.ANY);
+        }
+
+        // Sets up arguments for the mocked expression.
+        when(mockExpr.getArguments()).thenReturn(argRefs);
+
+        // Sets up required/actual types of the mocked expression.
+        Object[] opaqueParameters = new Object[2];
+        opaqueParameters[0] = BuiltinType.ANY;
+        opaqueParameters[1] = BuiltinType.ANY;
+        when(mockExpr.getOpaqueParameters()).thenReturn(opaqueParameters);
+
+        // Tests the return type. It should be either ANY or NULLABLE/MISSABLE.
+        IResultTypeComputer instance = (IResultTypeComputer) 
c.getField("INSTANCE").get(null);
+        IAType resultType = instance.computeType(mockExpr, mockTypeEnv, 
mockMetadataProvider);
+        ATypeTag typeTag = resultType.getTypeTag();
+        if (typeTag == ATypeTag.ANY) {
+            return true;
+        }
+        if (typeTag == ATypeTag.UNION) {
+            AUnionType unionType = (AUnionType) resultType;
+            return unionType.isMissableType() && unionType.isNullableType();
+        }
+        return false;
+    }
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie6b3f0e9d9b4ddd9280e06f72a5ca30aa776315d
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Yingyi Bu <buyin...@gmail.com>

Reply via email to