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);
 

Reply via email to