Dmitry Lychagin has uploaded a new change for review.

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

Change subject: PLEASE EDIT to provide a meaningful commit message!
......................................................................

PLEASE EDIT to provide a meaningful commit message!

commit dd5a69be93472bc8a78d10ca7b0f8b8be9412bf4
Author: Dmitry Lychagin <[email protected]>
Date:   Fri May 12 13:16:01 2017 -0700

    Added built-in functions: ifmissing(), ifnull(), ifmissingornull()

Change-Id: Id114f6654b9814c5aeca07fffeea04daeb8dca19
---
M 
asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissing/ifmissing.1.query.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissingornull/ifmissingornull.1.query.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifnull/ifnull.1.query.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifmissing/ifmissing.1.adm
A 
asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifmissingornull/ifmissingornull.1.adm
A 
asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifnull/ifnull.1.adm
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
M 
asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
A 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingOrNullTypeComputer.java
A 
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfMissingDescriptor.java
A 
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfMissingOrNullDescriptor.java
A 
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfNullDescriptor.java
14 files changed, 396 insertions(+), 1 deletion(-)


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

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
index 6f24fc5..7431218 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/util/FunctionCollection.java
@@ -158,6 +158,9 @@
 import org.apache.asterix.runtime.evaluators.functions.GramTokensDescriptor;
 import 
org.apache.asterix.runtime.evaluators.functions.HashedGramTokensDescriptor;
 import 
org.apache.asterix.runtime.evaluators.functions.HashedWordTokensDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.IfMissingDescriptor;
+import 
org.apache.asterix.runtime.evaluators.functions.IfMissingOrNullDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.IfNullDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.InjectFailureDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.IsArrayDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.IsBooleanDescriptor;
@@ -428,6 +431,9 @@
         temp.add(IsUnknownDescriptor.FACTORY);
         temp.add(IsSystemNullDescriptor.FACTORY);
         temp.add(CheckUnknownDescriptor.FACTORY);
+        temp.add(IfMissingDescriptor.FACTORY);
+        temp.add(IfNullDescriptor.FACTORY);
+        temp.add(IfMissingOrNullDescriptor.FACTORY);
 
         // uuid generators (zero independent functions)
         temp.add(CreateUUIDDescriptor.FACTORY);
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissing/ifmissing.1.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissing/ifmissing.1.query.sqlpp
new file mode 100644
index 0000000..db99c32
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissing/ifmissing.1.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+{
+   "a": ismissing(ifmissing()),
+   "b": ismissing(ifmissing(ifmissing())),
+   "c": ismissing(ifmissing(ifmissing(), ifmissing())),
+   "d": ifmissing(ifmissing(), ifmissing(), true),
+   "e": ifmissing(true, false),
+   "f": isstring(ifmissing("true", true)),
+   "g": if_missing(if_missing(), true)
+};
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissingornull/ifmissingornull.1.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissingornull/ifmissingornull.1.query.sqlpp
new file mode 100644
index 0000000..298fa13
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissingornull/ifmissingornull.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.
+ */
+
+{
+   "a": ismissing(ifmissingornull()),
+   "b": ismissing(ifmissingornull(ifmissing())),
+   "c": ismissing(ifmissingornull(null)),
+   "d": ismissing(ifmissingornull(null, ifmissing())),
+   "e": ifmissingornull(null, true),
+   "f": ifmissingornull(ifmissing(), true),
+   "g": ifmissingornull(null, ifmissing(), true),
+   "h": if_missing_or_null(null, ifmissing(), true)
+};
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifnull/ifnull.1.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifnull/ifnull.1.query.sqlpp
new file mode 100644
index 0000000..633fefd
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifnull/ifnull.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.
+ */
+
+{
+   "a": isnull(null),
+   "b": ismissing(ifnull()),
+   "c": ismissing(ifnull(null)),
+   "d": ismissing(ifnull(ifmissing())),
+   "e": ifnull(null, true),
+   "f": ifnull(null, null, true),
+   "g": ismissing(ifnull(ifmissing(), false)),
+   "h": if_null(null, true)
+};
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifmissing/ifmissing.1.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifmissing/ifmissing.1.adm
new file mode 100644
index 0000000..d10567b
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifmissing/ifmissing.1.adm
@@ -0,0 +1 @@
+{ "a": true, "b": true, "c": true, "d": true, "e": true, "f": true, "g": true }
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifmissingornull/ifmissingornull.1.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifmissingornull/ifmissingornull.1.adm
new file mode 100644
index 0000000..df35f3a
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifmissingornull/ifmissingornull.1.adm
@@ -0,0 +1 @@
+{ "a": true, "b": true, "c": true, "d": true, "e": true, "f": true, "g": true, 
"h": true }
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifnull/ifnull.1.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifnull/ifnull.1.adm
new file mode 100644
index 0000000..df35f3a
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/types/ifnull/ifnull.1.adm
@@ -0,0 +1 @@
+{ "a": true, "b": true, "c": true, "d": true, "e": true, "f": true, "g": true, 
"h": true }
\ 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 d5716d1..29917d4 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -8410,6 +8410,21 @@
         <output-dir 
compare="Text">promotion_opentype_field_vs_opentype_field_02</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="types">
+      <compilation-unit name="ifmissing">
+        <output-dir compare="Text">ifmissing</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="types">
+      <compilation-unit name="ifnull">
+        <output-dir compare="Text">ifnull</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="types">
+      <compilation-unit name="ifmissingornull">
+        <output-dir compare="Text">ifmissingornull</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="materialization">
     <test-case FilePath="materialization">
diff --git 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
index 33e0c52..6a0c05e 100644
--- 
a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
+++ 
b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/CommonFunctionMapUtil.java
@@ -62,6 +62,9 @@
         FUNCTION_NAME_MAP.put("isarray", "is-array"); // isarray, internal: 
is-array
         FUNCTION_NAME_MAP.put("isobject", "is-object"); // isobject, internal: 
is-object
         FUNCTION_NAME_MAP.put("isobj", "is-object"); // isobj, internal: 
is-object
+        FUNCTION_NAME_MAP.put("ifmissing", "if-missing"); // ifmissing, 
internal: if-missing
+        FUNCTION_NAME_MAP.put("ifnull", "if-null"); // ifnull, internal: 
if-null
+        FUNCTION_NAME_MAP.put("ifmissingornull", "if-missing-or-null"); // 
ifmissingornull, internal: is-missing-or-null
 
         // Object functions
         FUNCTION_NAME_MAP.put("record-merge", "object-merge"); // 
record-merge, internal: object-merge
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 0769596..e3ac41a 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
@@ -66,6 +66,7 @@
 import org.apache.asterix.om.typecomputer.impl.FieldAccessNestedResultType;
 import 
org.apache.asterix.om.typecomputer.impl.FullTextContainsResultTypeComputer;
 import 
org.apache.asterix.om.typecomputer.impl.GetOverlappingInvervalTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.IfMissingOrNullTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.InjectFailureTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.LocalAvgTypeComputer;
 import org.apache.asterix.om.typecomputer.impl.MinMaxAggTypeComputer;
@@ -792,7 +793,14 @@
     public static final FunctionIdentifier CHECK_UNKNOWN = new 
FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "check-unknown", 1);
     public static final FunctionIdentifier COLLECTION_TO_SEQUENCE = new 
FunctionIdentifier(FunctionConstants.ASTERIX_NS,
-            "" + "collection-to-sequence", 1);
+            "collection-to-sequence", 1);
+
+    public static final FunctionIdentifier IF_MISSING = new 
FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "if-missing", FunctionIdentifier.VARARGS);
+    public static final FunctionIdentifier IF_NULL = new 
FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "if-null", FunctionIdentifier.VARARGS);
+    public static final FunctionIdentifier IF_MISSING_OR_NULL = new 
FunctionIdentifier(FunctionConstants.ASTERIX_NS,
+            "if-missing-or-null", FunctionIdentifier.VARARGS);
 
     public static final FunctionIdentifier EXTERNAL_LOOKUP = new 
FunctionIdentifier(FunctionConstants.ASTERIX_NS,
             "external-lookup", FunctionIdentifier.VARARGS);
@@ -880,6 +888,9 @@
         addPrivateFunction(GRAM_TOKENS, 
OrderedListOfAStringTypeComputer.INSTANCE, true);
         addPrivateFunction(HASHED_GRAM_TOKENS, 
OrderedListOfAInt32TypeComputer.INSTANCE, true);
         addPrivateFunction(HASHED_WORD_TOKENS, 
OrderedListOfAInt32TypeComputer.INSTANCE, true);
+        addFunction(IF_MISSING, IfMissingOrNullTypeComputer.INSTANCE,  true);
+        addFunction(IF_NULL, IfMissingOrNullTypeComputer.INSTANCE,  true);
+        addFunction(IF_MISSING_OR_NULL, IfMissingOrNullTypeComputer.INSTANCE,  
true);
         addPrivateFunction(INDEX_SEARCH, AnyTypeComputer.INSTANCE, true);
         addFunction(INT8_CONSTRUCTOR, AInt8TypeComputer.INSTANCE, true);
         addFunction(INT16_CONSTRUCTOR, AInt16TypeComputer.INSTANCE, true);
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingOrNullTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingOrNullTypeComputer.java
new file mode 100644
index 0000000..dbae20a
--- /dev/null
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingOrNullTypeComputer.java
@@ -0,0 +1,60 @@
+/*
+ * 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.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.commons.lang3.mutable.Mutable;
+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.AbstractFunctionCallExpression;
+import 
org.apache.hyracks.algebricks.core.algebra.expressions.IVariableTypeEnvironment;
+import org.apache.hyracks.algebricks.core.algebra.metadata.IMetadataProvider;
+
+public final class IfMissingOrNullTypeComputer implements IResultTypeComputer {
+
+    public static final IResultTypeComputer INSTANCE = new 
IfMissingOrNullTypeComputer();
+
+    @Override
+    public IAType computeType(ILogicalExpression expression, 
IVariableTypeEnvironment env,
+            IMetadataProvider<?, ?> metadataProvider) throws 
AlgebricksException {
+        AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) 
expression;
+        IAType resultType = null;
+        boolean any = false;
+        for (Mutable<ILogicalExpression> argRef : fce.getArguments()) {
+            ILogicalExpression arg = argRef.getValue();
+            IAType argType = (IAType) env.getType(arg);
+            if (resultType == null) {
+                resultType = argType;
+            } else if (!resultType.equals(argType)) {
+                any = true;
+                break;
+            }
+        }
+        if (resultType == null) {
+            return BuiltinType.AMISSING;
+        }
+        if (any) {
+            return BuiltinType.ANY;
+        }
+        return resultType;
+    }
+}
\ No newline at end of file
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfMissingDescriptor.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfMissingDescriptor.java
new file mode 100644
index 0000000..984b692
--- /dev/null
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfMissingDescriptor.java
@@ -0,0 +1,57 @@
+/*
+ * 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.runtime.evaluators.functions;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.ATypeTag;
+import 
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class IfMissingDescriptor extends 
AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = 
IfMissingDescriptor::new;
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final 
IScalarEvaluatorFactory[] args) {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final 
IHyracksTaskContext ctx) throws HyracksDataException {
+                return new IfMissingOrNullDescriptor.AbstractIfEvaluator(ctx, 
args) {
+                    @Override
+                    protected boolean skip(byte argTypeTag) {
+                        return argTypeTag == 
ATypeTag.SERIALIZED_MISSING_TYPE_TAG;
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.IF_MISSING;
+    }
+}
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfMissingOrNullDescriptor.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfMissingOrNullDescriptor.java
new file mode 100644
index 0000000..eb844f4
--- /dev/null
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfMissingOrNullDescriptor.java
@@ -0,0 +1,96 @@
+/*
+ * 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.runtime.evaluators.functions;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.ATypeTag;
+import 
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public final class IfMissingOrNullDescriptor extends 
AbstractScalarFunctionDynamicDescriptor {
+
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = 
IfMissingOrNullDescriptor::new;
+
+    @Override
+    public IScalarEvaluatorFactory 
createEvaluatorFactory(IScalarEvaluatorFactory[] args) throws 
AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final 
IHyracksTaskContext ctx) throws HyracksDataException {
+                return new AbstractIfEvaluator(ctx, args) {
+                    @Override
+                    protected boolean skip(byte argTypeTag) {
+                        return argTypeTag == 
ATypeTag.SERIALIZED_MISSING_TYPE_TAG
+                                || argTypeTag == 
ATypeTag.SERIALIZED_NULL_TYPE_TAG;
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.IF_MISSING_OR_NULL;
+    }
+
+    public static abstract class AbstractIfEvaluator implements 
IScalarEvaluator {
+
+        private static final byte[] missingBytes = new byte[] { 
ATypeTag.SERIALIZED_MISSING_TYPE_TAG };
+
+        private final IScalarEvaluator[] argEvals;
+
+        private final IPointable argPtr;
+
+        AbstractIfEvaluator(IHyracksTaskContext ctx, IScalarEvaluatorFactory[] 
args) throws HyracksDataException {
+            argEvals = new IScalarEvaluator[args.length];
+            for (int i = 0; i < argEvals.length; i++) {
+                argEvals[i] = args[i].createScalarEvaluator(ctx);
+            }
+            argPtr = new VoidPointable();
+        }
+
+        @Override
+        public void evaluate(IFrameTupleReference tuple, IPointable result) 
throws HyracksDataException {
+            for (IScalarEvaluator argEval : argEvals) {
+                argEval.evaluate(tuple, argPtr);
+                byte[] bytes = argPtr.getByteArray();
+                int offset = argPtr.getStartOffset();
+                if (!skip(bytes[offset])) {
+                    result.set(argPtr);
+                    return;
+                }
+            }
+            result.set(missingBytes, 0, missingBytes.length);
+        }
+
+        protected abstract boolean skip(byte argTypeTag);
+    }
+}
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfNullDescriptor.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfNullDescriptor.java
new file mode 100644
index 0000000..11e464a
--- /dev/null
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/IfNullDescriptor.java
@@ -0,0 +1,58 @@
+/*
+ * 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.runtime.evaluators.functions;
+
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.ATypeTag;
+import 
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public final class IfNullDescriptor extends 
AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+    public static final IFunctionDescriptorFactory FACTORY = 
IfNullDescriptor::new;
+
+    @Override
+    public IScalarEvaluatorFactory 
createEvaluatorFactory(IScalarEvaluatorFactory[] args) throws 
AlgebricksException {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final 
IHyracksTaskContext ctx) throws HyracksDataException {
+                return new IfMissingOrNullDescriptor.AbstractIfEvaluator(ctx, 
args) {
+                    @Override
+                    protected boolean skip(byte argTypeTag) {
+                        return argTypeTag == ATypeTag.SERIALIZED_NULL_TYPE_TAG;
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.IF_NULL;
+    }
+}

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id114f6654b9814c5aeca07fffeea04daeb8dca19
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Dmitry Lychagin <[email protected]>

Reply via email to