Till Westmann has uploaded a new change for review.

  https://asterix-gerrit.ics.uci.edu/2724

Change subject: [NO ISSUE] add function array_repeat
......................................................................

[NO ISSUE] add function array_repeat

Change-Id: Ic5f9e503a81ba86dd873ad61fd35a2f695905dad
---
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-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
6 files changed, 142 insertions(+), 0 deletions(-)


  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/24/2724/1

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..301e972
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_repeat/array_repeat.1.query.sqlpp
@@ -0,0 +1,14 @@
+{
+  "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)),
+  -- TODO (tillw) fix this "t10": (array_repeat({ "a": 1 }, 3)),
+  "t11": (array_repeat([1, 2], 3)),
+  "t12": 1
+}
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..ff5c63c
--- /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, "t11": [ [ 1, 2 ], [ 1, 2 ], [ 1, 2 ] ], 
"t12": 1 }
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 0934e56..5a225e4 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -995,6 +995,11 @@
         <expected-error>HYR0115: Cannot compare non-primitive values (in line 
22, at column 8)</expected-error>
       </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-group>
   <test-group name="boolean">
     <test-case FilePath="boolean">
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 f73533c..4cceaf3 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
@@ -187,6 +187,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);
 
     // objects
     public static final FunctionIdentifier RECORD_MERGE =
@@ -1464,6 +1466,7 @@
         // array functions
         addFunction(ARRAY_APPEND, ArrayAppendTypeComputer.INSTANCE, true);
         addFunction(ARRAY_POSITION, AInt32TypeComputer.INSTANCE, true);
+        addFunction(ARRAY_REPEAT, OrderedListOfAnyTypeComputer.INSTANCE, true);
 
         // objects
         addFunction(RECORD_MERGE, RecordMergeTypeComputer.INSTANCE, true);
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..ea6c327
--- /dev/null
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRepeatDescriptor.java
@@ -0,0 +1,117 @@
+/*
+ * 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.types.ATypeTag;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+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.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;
+
+    public static final IFunctionDescriptorFactory FACTORY = new 
IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new ArrayRepeatDescriptor();
+        }
+    };
+
+    @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(FULL_OPEN_ORDEREDLIST_TYPE);
+            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 f64df0a..993faeb 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
@@ -145,6 +145,7 @@
 import 
org.apache.asterix.runtime.evaluators.functions.AnyCollectionMemberDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.ArrayAppendDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.ArrayPositionDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ArrayRepeatDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.CastTypeDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.CastTypeLaxDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.CheckUnknownDescriptor;
@@ -374,6 +375,7 @@
         // array functions
         fc.addGenerated(ArrayAppendDescriptor.FACTORY);
         fc.addGenerated(ArrayPositionDescriptor.FACTORY);
+        fc.addGenerated(ArrayRepeatDescriptor.FACTORY);
 
         // unnesting functions
         fc.add(TidRunningAggregateDescriptor.FACTORY);

-- 
To view, visit https://asterix-gerrit.ics.uci.edu/2724
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic5f9e503a81ba86dd873ad61fd35a2f695905dad
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Till Westmann <[email protected]>

Reply via email to