Repository: asterixdb Updated Branches: refs/heads/master 5ff3230e7 -> aae5753a1
[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 <jenk...@fulliautomatix.ics.uci.edu> Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Contrib: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Reviewed-by: Till Westmann <ti...@apache.org> Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/aae5753a Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/aae5753a Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/aae5753a Branch: refs/heads/master Commit: aae5753a1d5e2fca767059f76a3444ce2f2147bd Parents: 5ff3230 Author: Till Westmann <ti...@apache.org> Authored: Tue Jul 3 18:13:16 2018 -0700 Committer: Till Westmann <ti...@apache.org> Committed: Wed Jul 4 08:39:28 2018 -0700 ---------------------------------------------------------------------- .../array_repeat/array_repeat.1.query.sqlpp | 33 +++++ .../array_fun/array_repeat/array_repeat.1.adm | 1 + .../resources/runtimets/testsuite_sqlpp.xml | 5 + .../asterix/om/functions/BuiltinFunctions.java | 4 + .../impl/ArrayRepeatTypeComputer.java | 38 ++++++ .../functions/ArrayRepeatDescriptor.java | 134 +++++++++++++++++++ .../runtime/functions/FunctionCollection.java | 2 + 7 files changed, 217 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/asterixdb/blob/aae5753a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_repeat/array_repeat.1.query.sqlpp ---------------------------------------------------------------------- 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)) +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/aae5753a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_repeat/array_repeat.1.adm ---------------------------------------------------------------------- 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 ] ] } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/aae5753a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml ---------------------------------------------------------------------- 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> http://git-wip-us.apache.org/repos/asf/asterixdb/blob/aae5753a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java ---------------------------------------------------------------------- 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.AUUIDTypeComputer; 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 @@ public class BuiltinFunctions { 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 @@ public class BuiltinFunctions { // 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); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/aae5753a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayRepeatTypeComputer.java ---------------------------------------------------------------------- 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); + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/aae5753a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRepeatDescriptor.java ---------------------------------------------------------------------- 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); + } + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/aae5753a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java ---------------------------------------------------------------------- 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.AnyCollectionMemberDescri 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 @@ public final class FunctionCollection implements IFunctionCollection { // array functions fc.addGenerated(ArrayAppendDescriptor.FACTORY); fc.addGenerated(ArrayPositionDescriptor.FACTORY); + fc.addGenerated(ArrayRepeatDescriptor.FACTORY); fc.addGenerated(ArrayReverseDescriptor.FACTORY); fc.addGenerated(ArrayContainsDescriptor.FACTORY);