Till Westmann has submitted this change and it was merged. Change subject: [NO ISSUE] add function array_repeat ......................................................................
[NO ISSUE] add function array_repeat - user model changes: no - storage format changes: no - interface changes: no Change-Id: Ic5f9e503a81ba86dd873ad61fd35a2f695905dad Reviewed-on: https://asterix-gerrit.ics.uci.edu/2724 Sonar-Qube: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Contrib: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> Reviewed-by: Till Westmann <[email protected]> --- A asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_repeat/array_repeat.1.query.sqlpp A asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_repeat/array_repeat.1.adm M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml 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/ArrayRepeatTypeComputer.java A asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRepeatDescriptor.java M asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java 7 files changed, 217 insertions(+), 0 deletions(-) Approvals: Anon. E. Moose #1000171: Till Westmann: Looks good to me, approved Jenkins: Verified; No violations found; ; Verified diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_repeat/array_repeat.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_repeat/array_repeat.1.query.sqlpp new file mode 100644 index 0000000..50a0d7b --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_repeat/array_repeat.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. + */ + +{ + "t1": (select value array_repeat("a", 3)), + "t2": (array_repeat("a", 3)), + "t3": (array_repeat("a", 0)), + "t4": (array_repeat("a", -3)), + "t5": (array_repeat("a", "a")), + "t6": (array_repeat("a", missing)), + "t7": (array_repeat(missing, 3)), + "t8": (array_repeat("a", null)), + "t9": (array_repeat(null, 3)), + "t10": (array_repeat({ "a": 1 }, 3)), + "t11": (array_repeat([1, 2], 3)) +} diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_repeat/array_repeat.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_repeat/array_repeat.1.adm new file mode 100644 index 0000000..183211f --- /dev/null +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_repeat/array_repeat.1.adm @@ -0,0 +1 @@ +{ "t1": [ [ "a", "a", "a" ] ], "t2": [ "a", "a", "a" ], "t3": [ ], "t4": [ ], "t5": null, "t8": null, "t9": null, "t10": [ { "a": 1 }, { "a": 1 }, { "a": 1 } ], "t11": [ [ 1, 2 ], [ 1, 2 ], [ 1, 2 ] ] } 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 9622376..a806bf6 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml +++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml @@ -996,6 +996,11 @@ </compilation-unit> </test-case> <test-case FilePath="array_fun"> + <compilation-unit name="array_repeat"> + <output-dir compare="Text">array_repeat</output-dir> + </compilation-unit> + </test-case> + <test-case FilePath="array_fun"> <compilation-unit name="array_reverse"> <output-dir compare="Text">array_reverse</output-dir> </compilation-unit> 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 c2b0c02..10e5a9a 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 @@ -55,6 +55,7 @@ import org.apache.asterix.om.typecomputer.impl.AYearMonthDurationTypeComputer; import org.apache.asterix.om.typecomputer.impl.AnyTypeComputer; import org.apache.asterix.om.typecomputer.impl.ArrayAppendTypeComputer; +import org.apache.asterix.om.typecomputer.impl.ArrayRepeatTypeComputer; import org.apache.asterix.om.typecomputer.impl.BooleanFunctionTypeComputer; import org.apache.asterix.om.typecomputer.impl.BooleanOnlyTypeComputer; import org.apache.asterix.om.typecomputer.impl.BooleanOrMissingTypeComputer; @@ -188,6 +189,8 @@ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "array-append", FunctionIdentifier.VARARGS); public static final FunctionIdentifier ARRAY_POSITION = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "array-position", 2); + public static final FunctionIdentifier ARRAY_REPEAT = + new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "array-repeat", 2); public static final FunctionIdentifier ARRAY_REVERSE = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "array-reverse", 1); public static final FunctionIdentifier ARRAY_CONTAINS = @@ -1469,6 +1472,7 @@ // array functions addFunction(ARRAY_APPEND, ArrayAppendTypeComputer.INSTANCE, true); addFunction(ARRAY_POSITION, AInt32TypeComputer.INSTANCE, true); + addFunction(ARRAY_REPEAT, ArrayRepeatTypeComputer.INSTANCE, true); addFunction(ARRAY_REVERSE, AListTypeComputer.INSTANCE, true); addFunction(ARRAY_CONTAINS, ABooleanTypeComputer.INSTANCE, true); diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRepeatTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRepeatTypeComputer.java new file mode 100644 index 0000000..28c61bb --- /dev/null +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRepeatTypeComputer.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.asterix.om.typecomputer.impl; + +import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer; +import org.apache.asterix.om.types.AOrderedListType; +import org.apache.asterix.om.types.IAType; +import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException; +import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression; + +public class ArrayRepeatTypeComputer extends AbstractResultTypeComputer { + + public static final ArrayRepeatTypeComputer INSTANCE = new ArrayRepeatTypeComputer(); + + private ArrayRepeatTypeComputer() { + } + + @Override + protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException { + return new AOrderedListType(strippedInputTypes[0], null); + } +} diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRepeatDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRepeatDescriptor.java new file mode 100644 index 0000000..3a0280d --- /dev/null +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRepeatDescriptor.java @@ -0,0 +1,134 @@ +/* + * 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 static org.apache.asterix.om.types.AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE; + +import org.apache.asterix.builders.IAsterixListBuilder; +import org.apache.asterix.builders.OrderedListBuilder; +import org.apache.asterix.om.functions.BuiltinFunctions; +import org.apache.asterix.om.functions.IFunctionDescriptor; +import org.apache.asterix.om.functions.IFunctionDescriptorFactory; +import org.apache.asterix.om.functions.IFunctionTypeInferer; +import org.apache.asterix.om.types.AOrderedListType; +import org.apache.asterix.om.types.ATypeTag; +import org.apache.asterix.om.types.AbstractCollectionType; +import org.apache.asterix.om.types.IAType; +import org.apache.asterix.om.types.hierachy.ATypeHierarchy; +import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor; +import org.apache.asterix.runtime.functions.FunctionTypeInferers; +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.TaggedValuePointable; +import org.apache.hyracks.data.std.primitive.VoidPointable; +import org.apache.hyracks.data.std.util.ArrayBackedValueStorage; +import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference; + +public class ArrayRepeatDescriptor extends AbstractScalarFunctionDynamicDescriptor { + private static final long serialVersionUID = 1L; + + AbstractCollectionType repeatedValueListType; + + public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() { + @Override + public IFunctionDescriptor createFunctionDescriptor() { + return new ArrayRepeatDescriptor(); + } + + @Override + public IFunctionTypeInferer createFunctionTypeInferer() { + return FunctionTypeInferers.SET_ARGUMENTS_TYPE; + } + }; + + @Override + public void setImmutableStates(Object... states) { + repeatedValueListType = new AOrderedListType((IAType) states[0], null); + } + + @Override + public FunctionIdentifier getIdentifier() { + return BuiltinFunctions.ARRAY_REPEAT; + } + + @Override + public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) + throws AlgebricksException { + return new IScalarEvaluatorFactory() { + private static final long serialVersionUID = 1L; + + @Override + public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException { + return new ArrayRepeatFunction(args, ctx); + } + }; + } + + public class ArrayRepeatFunction implements IScalarEvaluator { + private final ArrayBackedValueStorage storage; + private final IScalarEvaluator repeatedValueEval; + private final IScalarEvaluator repeatEval; + private final IPointable repeatedValueArg; + private final IPointable repeatArg; + private final TaggedValuePointable repeatArgValue; + private final IAsterixListBuilder listBuilder; + + public ArrayRepeatFunction(IScalarEvaluatorFactory[] args, IHyracksTaskContext ctx) + throws HyracksDataException { + storage = new ArrayBackedValueStorage(); + repeatedValueEval = args[0].createScalarEvaluator(ctx); + repeatEval = args[1].createScalarEvaluator(ctx); + repeatedValueArg = new VoidPointable(); + repeatArg = new VoidPointable(); + repeatArgValue = new TaggedValuePointable(); + listBuilder = new OrderedListBuilder(); + } + + @Override + public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException { + // 1st arg: value to repeat + repeatedValueEval.evaluate(tuple, repeatedValueArg); + + // 2nd arg: number of repetitions + repeatEval.evaluate(tuple, repeatArg); + repeatArgValue.set(repeatArg); + if (!ATypeHierarchy.isCompatible(ATypeTag.INTEGER, ATypeTag.VALUE_TYPE_MAPPING[repeatArgValue.getTag()])) { + PointableHelper.setNull(result); + return; + } + final String name = getIdentifier().getName(); + final int repetitions = + ATypeHierarchy.getIntegerValue(name, 1, repeatArg.getByteArray(), repeatArg.getStartOffset()); + + // create list + listBuilder.reset(repeatedValueListType); + for (int i = 0; i < repetitions; ++i) { + listBuilder.addItem(repeatedValueArg); + } + storage.reset(); + listBuilder.write(storage.getDataOutput(), true); + result.set(storage); + } + } +} diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java index f89e67b..61a158e 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java @@ -146,6 +146,7 @@ import org.apache.asterix.runtime.evaluators.functions.ArrayAppendDescriptor; import org.apache.asterix.runtime.evaluators.functions.ArrayContainsDescriptor; import org.apache.asterix.runtime.evaluators.functions.ArrayPositionDescriptor; +import org.apache.asterix.runtime.evaluators.functions.ArrayRepeatDescriptor; import org.apache.asterix.runtime.evaluators.functions.ArrayReverseDescriptor; import org.apache.asterix.runtime.evaluators.functions.CastTypeDescriptor; import org.apache.asterix.runtime.evaluators.functions.CastTypeLaxDescriptor; @@ -376,6 +377,7 @@ // array functions fc.addGenerated(ArrayAppendDescriptor.FACTORY); fc.addGenerated(ArrayPositionDescriptor.FACTORY); + fc.addGenerated(ArrayRepeatDescriptor.FACTORY); fc.addGenerated(ArrayReverseDescriptor.FACTORY); fc.addGenerated(ArrayContainsDescriptor.FACTORY); -- To view, visit https://asterix-gerrit.ics.uci.edu/2724 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ic5f9e503a81ba86dd873ad61fd35a2f695905dad Gerrit-PatchSet: 9 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: Till Westmann <[email protected]> Gerrit-Reviewer: Ali Alsuliman <[email protected]> Gerrit-Reviewer: Anon. E. Moose #1000171 Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Murtadha Hubail <[email protected]> Gerrit-Reviewer: Till Westmann <[email protected]> Gerrit-Reviewer: abdullah alamoudi <[email protected]>
