Yingyi Bu has submitted this change and it was merged. Change subject: Added built-in functions: ifmissing(), ifnull(), ifmissingornull() ......................................................................
Added built-in functions: ifmissing(), ifnull(), ifmissingornull() Change-Id: Id114f6654b9814c5aeca07fffeea04daeb8dca19 Reviewed-on: https://asterix-gerrit.ics.uci.edu/1745 Reviewed-by: Yingyi Bu <[email protected]> Tested-by: Jenkins <[email protected]> BAD: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> --- 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-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java M asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties M asterixdb/asterix-doc/pom.xml M asterixdb/asterix-doc/src/main/markdown/builtins/0_toc.md A asterixdb/asterix-doc/src/main/markdown/builtins/13_conditional.md 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/dataflow/data/common/TypeResolverUtil.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/AbstractIfMissingOrNullTypeComputer.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingOrNullTypeComputer.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingTypeComputer.java A asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfNullTypeComputer.java M asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.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 24 files changed, 727 insertions(+), 5 deletions(-) Approvals: Yingyi Bu: Looks good to me, approved Jenkins: Verified; No violations found; Verified Objections: Jenkins: Violations found 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..2f0d837 --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissing/ifmissing.1.query.sqlpp @@ -0,0 +1,33 @@ +/* + * 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(ifmissing()), + "b": isnull(ifmissing(missing)), + "c": isnull(ifmissing(missing, missing)), + "d": ifmissing(missing, missing, true, 1), + "e": ifmissing(true, false, 1), + "f": isstring(ifmissing("true", true, 1)), + "g": if_missing(missing, true, 1), + "i": ifmissing( + missing, + case when get_year(current_datetime()) > 0 then missing else false end, + case when get_year(current_datetime()) > 0 then true else null end + ) +}; 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..32f040f --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifmissingornull/ifmissingornull.1.query.sqlpp @@ -0,0 +1,36 @@ +/* + * 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(ifmissingornull()), + "b": isnull(ifmissingornull(missing)), + "c": isnull(ifmissingornull(null)), + "d": isnull(ifmissingornull(null, missing)), + "e": ifmissingornull(null, true, 1), + "f": ifmissingornull(missing, true, 1), + "g": ifmissingornull(null, missing, true, 1), + "h": if_missing_or_null(null, missing, true, 1), + "i": ifmissingornull( + missing, + null, + case when get_year(current_datetime()) > 0 then missing else false end, + case when get_year(current_datetime()) > 0 then null else false end, + case when get_year(current_datetime()) > 0 then true else missing end + ) +}; \ 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..c0683bd --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/types/ifnull/ifnull.1.query.sqlpp @@ -0,0 +1,34 @@ +/* + * 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": isnull(ifnull()), + "c": isnull(ifnull(null)), + "d": ismissing(ifnull(missing)), + "e": ifnull(null, true, 1), + "f": ifnull(null, null, true, 1), + "g": ismissing(ifnull(missing, false, 1)), + "h": if_null(null, true), + "i": ifnull( + null, + case when get_year(current_datetime()) > 0 then null else false end, + case when get_year(current_datetime()) > 0 then true else missing end + ) +}; 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..0a2275f --- /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, "i": 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..633c503 --- /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, "i": 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..633c503 --- /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, "i": 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-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java index e59c379..8897dbf 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java @@ -98,6 +98,7 @@ public static final int INCOMPATIBLE_SEARCH_MODIFIER = 1035; public static final int UNKNOWN_SEARCH_MODIFIER = 1036; public static final int COMPILATION_BAD_QUERY_PARAMETER_VALUE = 1037; + public static final int COMPILATION_ILLEGAL_STATE = 1038; // Feed errors public static final int DATAFLOW_ILLEGAL_STATE = 3001; diff --git a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties index 487758c..1c93efe 100644 --- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties +++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties @@ -84,6 +84,7 @@ 1035 = Incompatible search modifier %1$s for index type %2$s 1036 = Unknown search modifier type %1$s 1037 = Invalid query parameter %1$s -- value has to be greater than or equal to %2$s bytes +1038 = Illegal state. %1$s # Feed Errors 3001 = Illegal state. diff --git a/asterixdb/asterix-doc/pom.xml b/asterixdb/asterix-doc/pom.xml index fed37b8..9b980e1 100644 --- a/asterixdb/asterix-doc/pom.xml +++ b/asterixdb/asterix-doc/pom.xml @@ -56,10 +56,10 @@ <filelist dir="${project.basedir}/src/main/markdown/sqlpp" files="0_toc.md,1_intro.md,2_expr_title.md,2_expr.md,3_query_title.md,3_query.md,4_error_title.md,4_error.md,5_ddl.md,appendix_1_title.md,appendix_1_keywords.md,appendix_2_title.md,appendix_2_parameters.md" /> </concat> <concat destfile="${project.build.directory}/generated-site/markdown/sqlpp/builtins.md"> - <filelist dir="${project.basedir}/src/main/markdown/builtins" files="0_toc.md,1_numeric.md,2_string.md,3_binary.md,4_spatial.md,5_similarity.md,6_tokenizing.md,7_temporal.md,7_allens.md,8_record.md,9_aggregate_sql.md,10_comparison.md,11_type.md,12_misc.md" /> + <filelist dir="${project.basedir}/src/main/markdown/builtins" files="0_toc.md,1_numeric.md,2_string.md,3_binary.md,4_spatial.md,5_similarity.md,6_tokenizing.md,7_temporal.md,7_allens.md,8_record.md,9_aggregate_sql.md,10_comparison.md,11_type.md,13_conditional.md,12_misc.md" /> </concat> <concat destfile="${project.build.directory}/generated-site/markdown/aql/builtins.md"> - <filelist dir="${project.basedir}/src/main/markdown/builtins" files="0_toc.md,1_numeric.md,2_string.md,3_binary.md,4_spatial.md,5_similarity.md,6_tokenizing.md,7_temporal.md,7_allens.md,8_record.md,9_aggregate_aql.md,10_comparison.md,11_type.md,12_misc.md" /> + <filelist dir="${project.basedir}/src/main/markdown/builtins" files="0_toc.md,1_numeric.md,2_string.md,3_binary.md,4_spatial.md,5_similarity.md,6_tokenizing.md,7_temporal.md,7_allens.md,8_record.md,9_aggregate_aql.md,10_comparison.md,11_type.md,13_conditional.md,12_misc.md" /> </concat> <concat destfile="${project.build.directory}/generated-site/markdown/ansible.md"> <filelist dir="${project.basedir}/src/main/installation/" files="ansible_title.md,ansible.md" /> diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/0_toc.md b/asterixdb/asterix-doc/src/main/markdown/builtins/0_toc.md index 911ee63..e0d23d4 100644 --- a/asterixdb/asterix-doc/src/main/markdown/builtins/0_toc.md +++ b/asterixdb/asterix-doc/src/main/markdown/builtins/0_toc.md @@ -32,6 +32,7 @@ * [Aggregate Functions (Array Functions)](#AggregateFunctions) * [Comparison Functions](#ComparisonFunctions) * [Type Functions](#TypeFunctions) +* [Conditional Functions](#ConditionalFunctions) * [Miscellaneous Functions](#MiscFunctions) The system provides various classes of functions to support operations on numeric, string, spatial, and temporal data. diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/13_conditional.md b/asterixdb/asterix-doc/src/main/markdown/builtins/13_conditional.md new file mode 100644 index 0000000..04fa943 --- /dev/null +++ b/asterixdb/asterix-doc/src/main/markdown/builtins/13_conditional.md @@ -0,0 +1,103 @@ +<!-- + ! 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 id="ConditionalFunctions">Conditional Functions</a> <font size="4"><a href="#toc">[Back to TOC]</a></font> ## + +### if_null (ifnull) ### + + * Syntax: + + if_null(expression1, expression2, ... expressionN) + + * Finds first argument which value is not `null` and returns that value + * Arguments: + * `expressionI` : an expression (any type is allowed). + * Return Value: + * a `null` if all arguments evaluate to `null` or no arguments specified + * a value of the first non-`null` argument otherwise + + * Example: + + { + "a": if_null(), + "b": if_null(null), + "c": if_null(null, "asterixdb"), + "d": is_missing(if_null(missing)) + }; + + * The expected result is: + + { "a": null, "b": null, "c": "asterixdb", "d": true } + + The function has an alias `ifnull`. + +### if_missing (ifmissing) ### + + * Syntax: + + if_missing(expression1, expression2, ... expressionN) + + * Finds first argument which value is not `missing` and returns that value + * Arguments: + * `expressionI` : an expression (any type is allowed). + * Return Value: + * a `null` if all arguments evaluate to `missing` or no arguments specified + * a value of the first non-`missing` argument otherwise + + * Example: + + { + "a": if_missing(), + "b": if_missing(missing), + "c": if_missing(missing, "asterixdb"), + "d": if_missing(null, "asterixdb") + }; + + * The expected result is: + + { "a": null, "b": null, "c": "asterixdb", "d": null } + + The function has an alias `ifmissing`. + +### if_missing_or_null (ifmissingornull) ### + + * Syntax: + + if_missing_or_null(expression1, expression2, ... expressionN) + + * Finds first argument which value is not `null` or `missing` and returns that value + * Arguments: + * `expressionI` : an expression (any type is allowed). + * Return Value: + * a `null` if all arguments evaluate to either `null` or `missing`, or no arguments specified + * a value of the first non-`null`, non-`missing` argument otherwise + +* Example: + + { + "a": if_missing_or_null(), + "b": if_missing_or_null(null, missing), + "c": if_missing_or_null(null, missing, "asterixdb") + }; + + * The expected result is: + + { "a": null, "b": null, "c": "asterixdb" } + + The function has an alias `ifmissingornull`. 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/dataflow/data/common/TypeResolverUtil.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/TypeResolverUtil.java index 415c1ae..561df5e 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/TypeResolverUtil.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/common/TypeResolverUtil.java @@ -58,6 +58,21 @@ } /** + * Returns a minimally generalized type that conforms to all input types. + * + * @param inputTypes, + * a list of input types + * @return a generalized type that conforms to all input types. + */ + public static IAType resolve(IAType... inputTypes) { + IAType currentType = null; + for (IAType type : inputTypes) { + currentType = currentType == null ? type : generalizeTypes(currentType, type); + } + return currentType; + } + + /** * Decides whether a type cast is needed to covert data instances from the input type to the required type. * * @param reqType, 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..6fc3ed9 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,9 @@ 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.IfMissingTypeComputer; +import org.apache.asterix.om.typecomputer.impl.IfNullTypeComputer; 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 +795,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 +890,9 @@ addPrivateFunction(GRAM_TOKENS, OrderedListOfAStringTypeComputer.INSTANCE, true); addPrivateFunction(HASHED_GRAM_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE, true); addPrivateFunction(HASHED_WORD_TOKENS, OrderedListOfAInt32TypeComputer.INSTANCE, true); + addFunction(IF_MISSING_OR_NULL, IfMissingOrNullTypeComputer.INSTANCE, true); + addFunction(IF_MISSING, IfMissingTypeComputer.INSTANCE, true); + addFunction(IF_NULL, IfNullTypeComputer.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/AbstractIfMissingOrNullTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractIfMissingOrNullTypeComputer.java new file mode 100644 index 0000000..2626c6b --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractIfMissingOrNullTypeComputer.java @@ -0,0 +1,112 @@ +/* + * 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.common.exceptions.CompilationException; +import org.apache.asterix.common.exceptions.ErrorCode; +import org.apache.asterix.dataflow.data.common.TypeResolverUtil; +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.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; + +abstract class AbstractIfMissingOrNullTypeComputer implements IResultTypeComputer { + @Override + public IAType computeType(ILogicalExpression expression, IVariableTypeEnvironment env, + IMetadataProvider<?, ?> metadataProvider) throws AlgebricksException { + AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expression; + IAType outPrimeType = null; + ATypeTag outQuantifier = null; // could be 'missing' or 'null' + + for (Mutable<ILogicalExpression> argRef : fce.getArguments()) { + ILogicalExpression arg = argRef.getValue(); + IAType argType = (IAType) env.getType(arg); + ATypeTag argTypeTag = argType.getTypeTag(); + + if (equalsIfType(argTypeTag)) { + continue; + } + + if (argTypeTag == ATypeTag.UNION) { + AUnionType unionType = (AUnionType) argType; + if (intersectsIfType(unionType)) { + IAType primeType = getOutputPrimeType(unionType); + outPrimeType = outPrimeType == null ? primeType : TypeResolverUtil.resolve(outPrimeType, primeType); + if (outQuantifier == null) { + outQuantifier = getOutputQuantifier(unionType); + } + } else { + // no intersection + if (outPrimeType == null) { + return argType; + } else { + IAType primeType = getOutputPrimeType(unionType); + ATypeTag quantifier = outQuantifier != null ? outQuantifier : getOutputQuantifier(unionType); + return createOutputType(TypeResolverUtil.resolve(outPrimeType, primeType), quantifier); + } + } + } else { + // ANY or no intersection + return outPrimeType == null ? argType + : createOutputType(TypeResolverUtil.resolve(outPrimeType, argType), outQuantifier); + } + } + + if (outPrimeType == null) { + return BuiltinType.ANULL; + } + IAType outType = createOutputType(outPrimeType, ATypeTag.NULL); + if (outQuantifier == ATypeTag.MISSING) { + outType = createOutputType(outType, ATypeTag.MISSING); + } + return outType; + } + + protected abstract boolean equalsIfType(ATypeTag typeTag); + + protected abstract boolean intersectsIfType(AUnionType type); + + protected abstract ATypeTag getOutputQuantifier(AUnionType type); + + private IAType getOutputPrimeType(AUnionType type) { + return type.getActualType(); + } + + private IAType createOutputType(IAType primeType, ATypeTag quantifier) throws AlgebricksException { + if (quantifier == null || primeType.getTypeTag() == ATypeTag.ANY) { + return primeType; + } + switch (quantifier) { + case MISSING: + return AUnionType.createMissableType(primeType); + case NULL: + return AUnionType.createNullableType(primeType, null); + default: + throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, String.valueOf(quantifier)); + } + } +} 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..fd35c79 --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingOrNullTypeComputer.java @@ -0,0 +1,45 @@ +/* + * 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.ATypeTag; +import org.apache.asterix.om.types.AUnionType; + +public class IfMissingOrNullTypeComputer extends AbstractIfMissingOrNullTypeComputer { + + public static final IResultTypeComputer INSTANCE = new IfMissingOrNullTypeComputer(); + + @Override + protected boolean equalsIfType(ATypeTag typeTag) { + return typeTag == ATypeTag.MISSING || typeTag == ATypeTag.NULL; + } + + @Override + protected boolean intersectsIfType(AUnionType type) { + return type.isUnknownableType(); + } + + @Override + protected ATypeTag getOutputQuantifier(AUnionType type) { + // 'missing' and 'null' cannot be in the output + return null; + } +} \ No newline at end of file diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingTypeComputer.java new file mode 100644 index 0000000..1742921 --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfMissingTypeComputer.java @@ -0,0 +1,45 @@ +/* + * 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.ATypeTag; +import org.apache.asterix.om.types.AUnionType; + +public class IfMissingTypeComputer extends AbstractIfMissingOrNullTypeComputer { + + public static final IResultTypeComputer INSTANCE = new IfMissingTypeComputer(); + + @Override + protected boolean equalsIfType(ATypeTag typeTag) { + return typeTag == ATypeTag.MISSING; + } + + @Override + protected boolean intersectsIfType(AUnionType type) { + return type.isMissableType(); + } + + @Override + protected ATypeTag getOutputQuantifier(AUnionType type) { + // 'null' may be in the output + return type.isNullableType() ? ATypeTag.NULL : null; + } +} diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfNullTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfNullTypeComputer.java new file mode 100644 index 0000000..149b35d --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/IfNullTypeComputer.java @@ -0,0 +1,45 @@ +/* + * 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.ATypeTag; +import org.apache.asterix.om.types.AUnionType; + +public class IfNullTypeComputer extends IfMissingOrNullTypeComputer { + + public static final IResultTypeComputer INSTANCE = new IfNullTypeComputer(); + + @Override + protected boolean equalsIfType(ATypeTag typeTag) { + return typeTag == ATypeTag.NULL; + } + + @Override + protected boolean intersectsIfType(AUnionType type) { + return type.isNullableType(); + } + + @Override + protected ATypeTag getOutputQuantifier(AUnionType type) { + // 'missing' may be in the output + return type.isMissableType() ? ATypeTag.MISSING : null; + } +} diff --git a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java index e1d4088..fc4646f 100644 --- a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java +++ b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/ExceptionTest.java @@ -59,8 +59,8 @@ testTypeComputer(c); ++numTypeComputers; } - // Currently, there are 78 type computers. - Assert.assertTrue(numTypeComputers >= 78); + // Currently, there are 83 type computers. + Assert.assertTrue(numTypeComputers >= 83); } private void testTypeComputer(Class<? extends IResultTypeComputer> c) throws Exception { 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..28db4d6 --- /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[] nullBytes = new byte[] { ATypeTag.SERIALIZED_NULL_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(nullBytes, 0, nullBytes.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: merged Gerrit-Change-Id: Id114f6654b9814c5aeca07fffeea04daeb8dca19 Gerrit-PatchSet: 6 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Dmitry Lychagin <[email protected]> Gerrit-Reviewer: Dmitry Lychagin <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]> Gerrit-Reviewer: Yingyi Bu <[email protected]>
