[NO ISSUE][COMP] Fix type computers of some array functions
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
Fix the type computer of some array functions to return a nullable
type if the function might return NULL.
Change-Id: I21b747f3116e78f4dcbec079a38972c1f1abc2ce
Reviewed-on: https://asterix-gerrit.ics.uci.edu/3570
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
Contrib: Till Westmann <tillw@apache.org>
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
index 417fa13..eba5100 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
@@ -24,7 +24,6 @@
import static org.apache.asterix.om.functions.BuiltinFunctions.WindowFunctionProperty.INJECT_ORDER_ARGS;
import static org.apache.asterix.om.functions.BuiltinFunctions.WindowFunctionProperty.MATERIALIZE_PARTITION;
import static org.apache.asterix.om.functions.BuiltinFunctions.WindowFunctionProperty.NO_FRAME_CLAUSE;
-import static org.apache.asterix.om.functions.BuiltinFunctions.WindowFunctionProperty.NO_ORDER_CLAUSE;
import java.util.Collections;
import java.util.EnumSet;
@@ -38,6 +37,7 @@
import org.apache.asterix.common.functions.FunctionSignature;
import org.apache.asterix.om.typecomputer.base.IResultTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ABinaryTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.ABooleanArrayContainsTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ABooleanTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ACircleTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ADateTimeTypeComputer;
@@ -48,6 +48,7 @@
import org.apache.asterix.om.typecomputer.impl.AFloatTypeComputer;
import org.apache.asterix.om.typecomputer.impl.AGeometryTypeComputer;
import org.apache.asterix.om.typecomputer.impl.AInt16TypeComputer;
+import org.apache.asterix.om.typecomputer.impl.AInt32ArrayPositionTypeComputer;
import org.apache.asterix.om.typecomputer.impl.AInt32TypeComputer;
import org.apache.asterix.om.typecomputer.impl.AInt64TypeComputer;
import org.apache.asterix.om.typecomputer.impl.AInt8TypeComputer;
@@ -2165,10 +2166,10 @@
addFunction(ARRAY_PREPEND, AListTypeComputer.INSTANCE_PREPEND, true);
addFunction(ARRAY_APPEND, AListTypeComputer.INSTANCE_APPEND, true);
addFunction(ARRAY_INSERT, AListTypeComputer.INSTANCE_INSERT, true);
- addFunction(ARRAY_POSITION, AInt32TypeComputer.INSTANCE, true);
+ addFunction(ARRAY_POSITION, AInt32ArrayPositionTypeComputer.INSTANCE, true);
addFunction(ARRAY_REPEAT, ArrayRepeatTypeComputer.INSTANCE, true);
addFunction(ARRAY_REVERSE, AListFirstTypeComputer.INSTANCE, true);
- addFunction(ARRAY_CONTAINS, ABooleanTypeComputer.INSTANCE, true);
+ addFunction(ARRAY_CONTAINS, ABooleanArrayContainsTypeComputer.INSTANCE, true);
addFunction(ARRAY_SORT, AListFirstTypeComputer.INSTANCE, true);
addFunction(ARRAY_DISTINCT, AListFirstTypeComputer.INSTANCE, true);
addFunction(ARRAY_UNION, AListMultiListArgsTypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ABooleanArrayContainsTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ABooleanArrayContainsTypeComputer.java
new file mode 100644
index 0000000..9f99b0c
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ABooleanArrayContainsTypeComputer.java
@@ -0,0 +1,40 @@
+/*
+ * 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.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.AUnionType;
+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;
+
+public class ABooleanArrayContainsTypeComputer extends AbstractResultTypeComputer {
+
+ public static final ABooleanArrayContainsTypeComputer INSTANCE = new ABooleanArrayContainsTypeComputer();
+
+ private ABooleanArrayContainsTypeComputer() {
+ }
+
+ @Override
+ protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+ return strippedInputTypes[0].getTypeTag().isListType() ? BuiltinType.ABOOLEAN
+ : AUnionType.createNullableType(BuiltinType.ABOOLEAN);
+ }
+}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AInt32ArrayPositionTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AInt32ArrayPositionTypeComputer.java
new file mode 100644
index 0000000..2a6e406
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AInt32ArrayPositionTypeComputer.java
@@ -0,0 +1,40 @@
+/*
+ * 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.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.AUnionType;
+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;
+
+public class AInt32ArrayPositionTypeComputer extends AbstractResultTypeComputer {
+
+ public static final AInt32ArrayPositionTypeComputer INSTANCE = new AInt32ArrayPositionTypeComputer();
+
+ private AInt32ArrayPositionTypeComputer() {
+ }
+
+ @Override
+ protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+ return strippedInputTypes[0].getTypeTag().isListType() ? BuiltinType.AINT32
+ : AUnionType.createNullableType(BuiltinType.AINT32);
+ }
+}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRangeTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRangeTypeComputer.java
index cfd7340..9fba3d2 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRangeTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRangeTypeComputer.java
@@ -22,6 +22,7 @@
import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
import org.apache.asterix.om.types.AOrderedListType;
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.asterix.om.types.hierachy.ATypeHierarchy;
@@ -49,7 +50,8 @@
} else if (ATypeHierarchy.canPromote(startNum.getTypeTag(), ATypeTag.DOUBLE)
&& ATypeHierarchy.canPromote(endNum.getTypeTag(), ATypeTag.DOUBLE)
&& (step == null || ATypeHierarchy.canPromote(step.getTypeTag(), ATypeTag.DOUBLE))) {
- return DOUBLE_LIST;
+ // even if the args types are valid, range function might return NULL if the doubles turn out to be Nan/Inf
+ return AUnionType.createNullableType(DOUBLE_LIST);
} else {
return BuiltinType.ANY;
}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRepeatTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRepeatTypeComputer.java
index 28c61bb..7dc00a4 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRepeatTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRepeatTypeComputer.java
@@ -20,6 +20,7 @@
import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.AUnionType;
import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
@@ -33,6 +34,8 @@
@Override
protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
- return new AOrderedListType(strippedInputTypes[0], null);
+ // return type is always nullable since even if the args are valid, array repeat might return null if the 2nd
+ // arg turns out to be NaN/Inf at runtime (2nd arg is number of times to repeat the value (1st arg))
+ return AUnionType.createNullableType(new AOrderedListType(strippedInputTypes[0], null));
}
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayContainsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayContainsDescriptor.java
index 683de8e..69eed4f 100755
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayContainsDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayContainsDescriptor.java
@@ -23,13 +23,12 @@
import org.apache.asterix.om.base.ABoolean;
import org.apache.asterix.om.base.AMutableInt32;
import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.functions.IFunctionTypeInferer;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.asterix.runtime.utils.DescriptorFactoryUtil;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
@@ -57,20 +56,12 @@
@MissingNullInOutFunction
public class ArrayContainsDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
private static final long serialVersionUID = 1L;
private IAType[] argTypes;
- public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
- @Override
- public IFunctionDescriptor createFunctionDescriptor() {
- return new ArrayContainsDescriptor();
- }
-
- @Override
- public IFunctionTypeInferer createFunctionTypeInferer() {
- return FunctionTypeInferers.SET_ARGUMENTS_TYPE;
- }
- };
+ public static final IFunctionDescriptorFactory FACTORY =
+ DescriptorFactoryUtil.createFactory(ArrayContainsDescriptor::new, FunctionTypeInferers.SET_ARGUMENTS_TYPE);
@Override
public FunctionIdentifier getIdentifier() {
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPositionDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPositionDescriptor.java
index f590d88..ed3949c 100755
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPositionDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPositionDescriptor.java
@@ -22,13 +22,12 @@
import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
import org.apache.asterix.om.base.AMutableInt32;
import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
-import org.apache.asterix.om.functions.IFunctionTypeInferer;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.asterix.runtime.utils.DescriptorFactoryUtil;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
@@ -56,20 +55,12 @@
@MissingNullInOutFunction
public class ArrayPositionDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
private static final long serialVersionUID = 1L;
private IAType[] argTypes;
- public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
- @Override
- public IFunctionDescriptor createFunctionDescriptor() {
- return new ArrayPositionDescriptor();
- }
-
- @Override
- public IFunctionTypeInferer createFunctionTypeInferer() {
- return FunctionTypeInferers.SET_ARGUMENTS_TYPE;
- }
- };
+ public static final IFunctionDescriptorFactory FACTORY =
+ DescriptorFactoryUtil.createFactory(ArrayPositionDescriptor::new, FunctionTypeInferers.SET_ARGUMENTS_TYPE);
@Override
public FunctionIdentifier getIdentifier() {