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]>
