>From Ali Alsuliman <[email protected]>:
Ali Alsuliman has uploaded this change for review. (
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20590?usp=email )
Change subject: [NO ISSUE][FUN] Add array-star-field()
......................................................................
[NO ISSUE][FUN] Add array-star-field()
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
array-star-field(input_array, field_name) is similar to
array-star(input_array) except that it only constructs the array
values for the desired field name.
Change-Id: I6859e392aa934b4327cd04489f234a6210938d0a
---
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/ArrayStarFieldDescriptor.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
3 files changed, 246 insertions(+), 0 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/90/20590/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 f631b32..13eace7 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
@@ -235,6 +235,7 @@
public static final FunctionIdentifier ARRAY_SYMDIFFN =
FunctionConstants.newAsterix("array-symdiffn",
FunctionIdentifier.VARARGS);
public static final FunctionIdentifier ARRAY_STAR =
FunctionConstants.newAsterix("array-star", 1);
+ public static final FunctionIdentifier ARRAY_STAR_FIELD =
FunctionConstants.newAsterix("array-star-field", 2);
public static final FunctionIdentifier ARRAY_SLICE_WITHOUT_END_POSITION =
FunctionConstants.newAsterix("array-slice", 2);
public static final FunctionIdentifier ARRAY_SLICE_WITH_END_POSITION =
@@ -2038,6 +2039,7 @@
addFunction(ARRAY_SYMDIFF, AListMultiListArgsTypeComputer.INSTANCE,
true);
addFunction(ARRAY_SYMDIFFN, AListMultiListArgsTypeComputer.INSTANCE,
true);
addFunction(ARRAY_STAR, OpenARecordTypeComputer.INSTANCE, true);
+ addFunction(ARRAY_STAR_FIELD, OrderedListOfAnyTypeComputer.INSTANCE,
true);
addFunction(ARRAY_SLICE_WITH_END_POSITION,
AListTypeComputer.INSTANCE_SLICE, true);
addFunction(ARRAY_SLICE_WITHOUT_END_POSITION,
AListTypeComputer.INSTANCE_SLICE, true);
addFunction(ARRAY_EXCEPT, ArrayExceptTypeComputer.INSTANCE, true);
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayStarFieldDescriptor.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayStarFieldDescriptor.java
new file mode 100755
index 0000000..3cabf4f
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayStarFieldDescriptor.java
@@ -0,0 +1,242 @@
+/*
+ * 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.EnumDeserializer.ATYPETAGDESERIALIZER;
+
+import java.io.IOException;
+
+import org.apache.asterix.builders.IAsterixListBuilder;
+import org.apache.asterix.builders.OrderedListBuilder;
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import
org.apache.asterix.dataflow.data.nontagged.serde.ARecordSerializerDeserializer;
+import org.apache.asterix.formats.nontagged.BinaryComparatorFactoryProvider;
+import org.apache.asterix.formats.nontagged.BinaryHashFunctionFactoryProvider;
+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.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.utils.NonTaggedFormatUtil;
+import
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.common.ListAccessor;
+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.IEvaluatorContext;
+import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
+import org.apache.hyracks.api.dataflow.value.IBinaryHashFunction;
+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;
+
+@MissingNullInOutFunction
+public class ArrayStarFieldDescriptor extends
AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+
+ public static final IFunctionDescriptorFactory FACTORY = new
IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ArrayStarFieldDescriptor();
+ }
+
+ @Override
+ public IFunctionTypeInferer createFunctionTypeInferer() {
+ return FunctionTypeInferers.SET_ARGUMENT_TYPE;
+ }
+ };
+
+ private IAType inputListType;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.ARRAY_STAR_FIELD;
+ }
+
+ @Override
+ public void setImmutableStates(Object... states) {
+ inputListType = (IAType) states[0];
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final
IScalarEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final
IEvaluatorContext ctx) throws HyracksDataException {
+ return new ArrayStarEval(args, ctx);
+ }
+ };
+ }
+
+ public class ArrayStarEval implements IScalarEvaluator {
+ private final IBinaryHashFunction fieldNameHashFunction =
+
BinaryHashFunctionFactoryProvider.UTF8STRING_POINTABLE_INSTANCE.createBinaryHashFunction();
+ private final IBinaryComparator fieldNameComparator =
+
BinaryComparatorFactoryProvider.UTF8STRING_POINTABLE_INSTANCE.createBinaryComparator();
+ private final ArrayBackedValueStorage storage;
+ private final IScalarEvaluator listEval;
+ private final IPointable tempList;
+ private final IPointable object;
+ private final IPointable castedObject;
+ private final ListAccessor listAccessor;
+ private final IAsterixListBuilder listBuilder;
+ private final IPointable fieldName;
+ private final IPointable fieldVal;
+ private final IScalarEvaluator fieldNameEval;
+ private final TypeCaster caster;
+ private final IAType itemType;
+ private final boolean openList;
+ private boolean addedValue;
+
+ public ArrayStarEval(IScalarEvaluatorFactory[] args, IEvaluatorContext
ctx) throws HyracksDataException {
+ storage = new ArrayBackedValueStorage();
+ castedObject = new VoidPointable();
+ object = new VoidPointable();
+ tempList = new VoidPointable();
+ listEval = args[0].createScalarEvaluator(ctx);
+ fieldNameEval = args[1].createScalarEvaluator(ctx);
+ caster = new TypeCaster(sourceLoc);
+ listAccessor = new ListAccessor();
+ listBuilder = new OrderedListBuilder();
+ fieldName = new VoidPointable();
+ fieldVal = new VoidPointable();
+ if (inputListType.getTypeTag() == ATypeTag.ARRAY) {
+ AOrderedListType listType = (AOrderedListType) inputListType;
+ if (listType.isTyped()) {
+ itemType = listType.getItemType();
+ openList = itemType.getTypeTag() == ATypeTag.ANY;
+ } else {
+ itemType = null;
+ openList = true;
+ }
+ } else {
+ itemType = null;
+ openList = true; // should be ANY type; if the arg is found to
be ARRAY at runtime, then it must be open
+ }
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result)
throws HyracksDataException {
+ listEval.evaluate(tuple, tempList);
+ fieldNameEval.evaluate(tuple, fieldName);
+ if (PointableHelper.checkAndSetMissingOrNull(result, tempList,
fieldName)) {
+ return;
+ }
+ ATypeTag listTag =
ATYPETAGDESERIALIZER.deserialize(tempList.getByteArray()[tempList.getStartOffset()]);
+ ATypeTag fieldTag =
ATYPETAGDESERIALIZER.deserialize(fieldName.getByteArray()[fieldName.getStartOffset()]);
+ if (listTag != ATypeTag.ARRAY || fieldTag != ATypeTag.STRING) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ addedValue = false;
+ storage.reset();
+
listBuilder.reset(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+ try {
+ listAccessor.reset(tempList.getByteArray(),
tempList.getStartOffset());
+ if (openList) {
+ processOpenList();
+ } else {
+ processTypedList();
+ }
+ if (!addedValue) {
+ PointableHelper.setMissing(result);
+ return;
+ }
+
+ storage.reset();
+ listBuilder.write(storage.getDataOutput(), true);
+ result.set(storage);
+ } catch (IOException e) {
+ throw HyracksDataException.create(e);
+ }
+ }
+
+ private void processOpenList() throws IOException {
+ int numObjects = listAccessor.size();
+ for (int objectIndex = 0; objectIndex < numObjects; objectIndex++)
{
+ listAccessor.getOrWriteItem(objectIndex, object, storage);
+ processOpenObject(object);
+ }
+ }
+
+ private void processTypedList() throws IOException {
+ int numObjects = listAccessor.size();
+ for (int objectIndex = 0; objectIndex < numObjects; objectIndex++)
{
+ listAccessor.getOrWriteItem(objectIndex, object, storage);
+ processTypedObject(object);
+ }
+ }
+
+ private void processOpenObject(IPointable object) throws
HyracksDataException {
+ int serRecordOffset = object.getStartOffset();
+ byte[] serRecord = object.getByteArray();
+ int serRecordLen = object.getLength();
+ if (serRecord[serRecordOffset] !=
ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
+ listBuilder.addItem(PointableHelper.NULL_REF);
+ return;
+ }
+ addValue(serRecord, serRecordOffset, serRecordLen);
+ }
+
+ private void processTypedObject(IPointable object) throws
HyracksDataException {
+ int serRecordOffset = object.getStartOffset();
+ byte[] serRecord = object.getByteArray();
+ if (serRecord[serRecordOffset] !=
ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
+ listBuilder.addItem(PointableHelper.NULL_REF);
+ return;
+ }
+ try {
+ caster.allocateAndCast(object, itemType, castedObject,
DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+ serRecordOffset = castedObject.getStartOffset();
+ serRecord = castedObject.getByteArray();
+ addValue(serRecord, serRecordOffset, castedObject.getLength());
+ } finally {
+ caster.deallocatePointables();
+ }
+ }
+
+ private void addValue(byte[] serRecord, int serRecordOffset, int
serRecordLen) throws HyracksDataException {
+ byte[] serFldName = fieldName.getByteArray();
+ int serFldNameOffset = fieldName.getStartOffset();
+ int subFieldOffset =
ARecordSerializerDeserializer.getFieldOffsetByName(serRecord, serRecordOffset,
+ serRecordLen, serFldName, serFldNameOffset,
fieldNameHashFunction, fieldNameComparator);
+ if (subFieldOffset < 0) {
+ listBuilder.addItem(PointableHelper.NULL_REF);
+ return;
+ }
+ ATypeTag fieldValueTypeTag =
ATYPETAGDESERIALIZER.deserialize(serRecord[subFieldOffset]);
+ int subFieldLength =
+ NonTaggedFormatUtil.getFieldValueLength(serRecord,
subFieldOffset, fieldValueTypeTag, true) + 1;
+ fieldVal.set(serRecord, subFieldOffset, subFieldLength);
+ listBuilder.addItem(fieldVal);
+ addedValue = true;
+ }
+ }
+}
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 166352c..0a544a8 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
@@ -364,6 +364,7 @@
import
org.apache.asterix.runtime.evaluators.functions.ArraySliceWithoutEndPositionDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArraySortDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArrayStarDescriptor;
+import
org.apache.asterix.runtime.evaluators.functions.ArrayStarFieldDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArraySwapDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArraySymDiffDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArraySymDiffnDescriptor;
@@ -697,6 +698,7 @@
fc.add(ArraySymDiffDescriptor.FACTORY);
fc.add(ArraySymDiffnDescriptor.FACTORY);
fc.add(ArrayStarDescriptor.FACTORY);
+ fc.add(ArrayStarFieldDescriptor.FACTORY);
fc.add(ArrayExceptDescriptor.FACTORY);
fc.add(ArrayMoveDescriptor.FACTORY);
fc.add(ArraySwapDescriptor.FACTORY);
--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20590?usp=email
To unsubscribe, or for help writing mail filters, visit
https://asterix-gerrit.ics.uci.edu/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: phoenix
Gerrit-Change-Id: I6859e392aa934b4327cd04489f234a6210938d0a
Gerrit-Change-Number: 20590
Gerrit-PatchSet: 1
Gerrit-Owner: Ali Alsuliman <[email protected]>