Ali Alsuliman has uploaded a new change for review.

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

Change subject: [NO ISSUE][FUN] Implement array_position function
......................................................................

[NO ISSUE][FUN] Implement array_position function

- user model changes: no
- storage format changes: no
- interface changes: no

details:
This is part of implementing array functions.
The array_position takes an input list and a value
and returns the index of the value in the array or
-1 if the value is not found.
array_position(list, val).

Change-Id: I4604d347a22f98071a68abee43693fca9096b361
---
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/ArrayPositionDescriptor.java
M 
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
3 files changed, 141 insertions(+), 0 deletions(-)


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

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 f17bc47..81fb24c 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
@@ -185,6 +185,8 @@
     // array functions
     public static final FunctionIdentifier ARRAY_APPEND =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, 
"array-append", FunctionIdentifier.VARARGS);
+    public static final FunctionIdentifier ARRAY_POSITION =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, 
"array-position", 2);
 
     // objects
     public static final FunctionIdentifier RECORD_MERGE =
@@ -1455,6 +1457,7 @@
 
         // array functions
         addFunction(ARRAY_APPEND, ArrayAppendTypeComputer.INSTANCE, true);
+        addFunction(ARRAY_POSITION, AInt32TypeComputer.INSTANCE, true);
 
         // objects
         addFunction(RECORD_MERGE, RecordMergeTypeComputer.INSTANCE, true);
diff --git 
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPositionDescriptor.java
 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPositionDescriptor.java
new file mode 100755
index 0000000..bd8f679
--- /dev/null
+++ 
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPositionDescriptor.java
@@ -0,0 +1,136 @@
+/*
+ * 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 java.io.IOException;
+
+import 
org.apache.asterix.dataflow.data.nontagged.comparators.AObjectAscBinaryComparatorFactory;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt32;
+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.BuiltinType;
+import 
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.common.ListAccessor;
+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.dataflow.value.IBinaryComparator;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+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.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ArrayPositionDescriptor extends 
AbstractScalarFunctionDynamicDescriptor {
+    private static final long serialVersionUID = 1L;
+
+    public static final IFunctionDescriptorFactory FACTORY = new 
IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new ArrayPositionDescriptor();
+        }
+    };
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.ARRAY_POSITION;
+    }
+
+    @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 ArrayPositionFunction(args, ctx);
+            }
+        };
+    }
+
+    public class ArrayPositionFunction implements IScalarEvaluator {
+        private final ArrayBackedValueStorage storage;
+        private final IPointable listArg;
+        private final IPointable searchedValueArg;
+        private final IScalarEvaluator listEval;
+        private final IScalarEvaluator searchedValueEval;
+
+        public ArrayPositionFunction(IScalarEvaluatorFactory[] args, 
IHyracksTaskContext ctx)
+                throws HyracksDataException {
+            storage = new ArrayBackedValueStorage();
+            listArg = new VoidPointable();
+            searchedValueArg = new VoidPointable();
+            listEval = args[0].createScalarEvaluator(ctx);
+            searchedValueEval = args[1].createScalarEvaluator(ctx);
+        }
+
+        @Override
+        public void evaluate(IFrameTupleReference tuple, IPointable result) 
throws HyracksDataException {
+            // 1st arg: list
+            listEval.evaluate(tuple, listArg);
+            byte[] listBytes = listArg.getByteArray();
+            int listOffset = listArg.getStartOffset();
+
+            // 2nd arg: value to search for
+            searchedValueEval.evaluate(tuple, searchedValueArg);
+            byte[] valueBytes = searchedValueArg.getByteArray();
+            int valueOffset = searchedValueArg.getStartOffset();
+            int valueLength = searchedValueArg.getLength();
+
+            byte listArgType = listBytes[listOffset];
+            if (listArgType != ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG
+                    && listArgType != 
ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG) {
+                PointableHelper.setNull(result);
+                return;
+            }
+
+            IBinaryComparator comp = 
AObjectAscBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+            ListAccessor listAccessor = new ListAccessor();
+            listAccessor.reset(listBytes, listOffset);
+            int numItems = listAccessor.size();
+            AMutableInt32 intValue = new AMutableInt32(-1);
+            try {
+                for (int i = 0; i < numItems; i++) {
+                    storage.reset();
+                    listAccessor.writeItem(i, storage.getDataOutput());
+                    if (comp.compare(storage.getByteArray(), 
storage.getStartOffset(), storage.getLength(), valueBytes,
+                            valueOffset, valueLength) == 0) {
+                        intValue.setValue(i);
+                        break;
+                    }
+                }
+            } catch (IOException e) {
+                throw HyracksDataException.create(e);
+            }
+
+            storage.reset();
+            ISerializerDeserializer intSerde =
+                    
SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT32);
+            intSerde.serialize(intValue, storage.getDataOutput());
+            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 7663f19..f143983 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
@@ -144,6 +144,7 @@
 import org.apache.asterix.runtime.evaluators.functions.AndDescriptor;
 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.CastTypeDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.CastTypeLaxDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.CheckUnknownDescriptor;
@@ -369,6 +370,7 @@
 
         // array functions
         fc.addGenerated(ArrayAppendDescriptor.FACTORY);
+        fc.addGenerated(ArrayPositionDescriptor.FACTORY);
 
         // unnesting functions
         fc.add(TidRunningAggregateDescriptor.FACTORY);

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4604d347a22f98071a68abee43693fca9096b361
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Ali Alsuliman <[email protected]>

Reply via email to