This is an automated email from the ASF dual-hosted git repository. mblow pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
commit fa43d861c0ed9c6905aeb29516638d10e2cf11bf Author: Ali Alsuliman <[email protected]> AuthorDate: Wed Jun 21 18:40:41 2023 -0700 [ASTERIXDB-3215][RT] Avoid unnecessary fields sort in ARecordCaster - user model changes: no - storage format changes: no - interface changes: no Details: Do not sort fields when the input record is already open. - Change OBJECT_VALUES() so that it avoids casting the input record if it is already open. - Fix getting the open field value from ARecordPointable to include the tag when writing the value to the output stream. Change-Id: I3fb928fe725ab7b6beb4abfc477b190d835138bb Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17610 Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Reviewed-by: Ali Alsuliman <[email protected]> Reviewed-by: Wail Alkowaileet <[email protected]> --- .../asterix/om/pointables/cast/ARecordCaster.java | 6 ++- .../om/pointables/nonvisitor/ARecordPointable.java | 4 +- .../functions/records/RecordValuesEvaluator.java | 43 ++++++++++++++++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ARecordCaster.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ARecordCaster.java index 56bdfc5fd4..7354c1e420 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ARecordCaster.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/cast/ARecordCaster.java @@ -194,10 +194,12 @@ class ARecordCaster { private void matchClosedPart(List<IVisitablePointable> fieldNames, List<IVisitablePointable> fieldTypeTags) throws HyracksDataException { - // sort-merge based match - quickSort(fieldNamesSortedIndex, fieldNames, 0, numInputFields - 1); int fnStart = 0; int reqFnStart = 0; + if (fnStart < numInputFields && reqFnStart < reqFieldNames.size()) { + // sort-merge based match + quickSort(fieldNamesSortedIndex, fieldNames, 0, numInputFields - 1); + } while (fnStart < numInputFields && reqFnStart < reqFieldNames.size()) { int fnPos = fieldNamesSortedIndex[fnStart]; int reqFnPos = reqFieldNamesSortedIndex[reqFnStart]; diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/nonvisitor/ARecordPointable.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/nonvisitor/ARecordPointable.java index cc3816c7d2..ab86c1d454 100644 --- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/nonvisitor/ARecordPointable.java +++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/pointables/nonvisitor/ARecordPointable.java @@ -244,7 +244,9 @@ public class ARecordPointable extends AbstractPointable { // ----------------------- public final void getOpenFieldValue(ARecordType recordType, int fieldId, DataOutput dOut) throws IOException { - dOut.write(bytes, getOpenFieldValueOffset(recordType, fieldId), getOpenFieldValueSize(recordType, fieldId)); + // + 1 to include the tag + int len = getOpenFieldValueSize(recordType, fieldId) + 1; + dOut.write(bytes, getOpenFieldValueOffset(recordType, fieldId), len); } public final int getOpenFieldValueOffset(ARecordType recordType, int fieldId) { diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesEvaluator.java index 783f4e6c47..106a899939 100644 --- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesEvaluator.java +++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordValuesEvaluator.java @@ -20,16 +20,19 @@ package org.apache.asterix.runtime.evaluators.functions.records; import java.io.DataOutput; +import java.io.IOException; import java.util.List; import org.apache.asterix.builders.OrderedListBuilder; import org.apache.asterix.om.pointables.ARecordVisitablePointable; import org.apache.asterix.om.pointables.base.DefaultOpenFieldType; import org.apache.asterix.om.pointables.base.IVisitablePointable; +import org.apache.asterix.om.pointables.nonvisitor.ARecordPointable; import org.apache.asterix.om.types.AOrderedListType; import org.apache.asterix.om.types.ARecordType; import org.apache.asterix.om.types.ATypeTag; import org.apache.asterix.om.types.BuiltinType; +import org.apache.asterix.om.utils.RecordUtil; import org.apache.asterix.runtime.evaluators.functions.CastTypeEvaluator; import org.apache.asterix.runtime.evaluators.functions.PointableHelper; import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator; @@ -45,6 +48,9 @@ class RecordValuesEvaluator implements IScalarEvaluator { private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage(); private final DataOutput resultOutput = resultStorage.getDataOutput(); private final IScalarEvaluator eval0; + private final boolean inputRecordOpen; + private final ARecordPointable recordPointable; + private final ArrayBackedValueStorage fieldValueStorage; private OrderedListBuilder listBuilder; private ARecordVisitablePointable openRecordPointable; private CastTypeEvaluator inputRecordCaster; @@ -52,9 +58,19 @@ class RecordValuesEvaluator implements IScalarEvaluator { RecordValuesEvaluator(IScalarEvaluator eval0, ARecordType recordType) { this.eval0 = eval0; if (recordType != null) { + inputRecordOpen = recordType.isOpen() && recordType.getFieldTypes().length == 0; openRecordPointable = new ARecordVisitablePointable(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE); inputRecordCaster = new CastTypeEvaluator(BuiltinType.ANY, recordType, eval0); listBuilder = new OrderedListBuilder(); + } else { + inputRecordOpen = true; + } + if (inputRecordOpen) { + recordPointable = new ARecordPointable(); + fieldValueStorage = new ArrayBackedValueStorage(); + } else { + recordPointable = null; + fieldValueStorage = null; } } @@ -72,14 +88,18 @@ class RecordValuesEvaluator implements IScalarEvaluator { PointableHelper.setNull(result); return; } - inputRecordCaster.evaluate(tuple, inputRecordPointable); resultStorage.reset(); - buildOutputList(); + if (inputRecordOpen) { + buildOutputList(); + } else { + buildOutputList(tuple); + } result.set(resultStorage); } - private void buildOutputList() throws HyracksDataException { + private void buildOutputList(IFrameTupleReference tuple) throws HyracksDataException { listBuilder.reset(AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE); + inputRecordCaster.evaluate(tuple, inputRecordPointable); openRecordPointable.set(inputRecordPointable); final List<IVisitablePointable> fieldValues = openRecordPointable.getFieldValues(); for (int i = 0, valuesCount = fieldValues.size(); i < valuesCount; i++) { @@ -87,4 +107,21 @@ class RecordValuesEvaluator implements IScalarEvaluator { } listBuilder.write(resultOutput, true); } + + private void buildOutputList() throws HyracksDataException { + listBuilder.reset(AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE); + recordPointable.set(inputRecordPointable); + int openFieldCount = recordPointable.getOpenFieldCount(RecordUtil.FULLY_OPEN_RECORD_TYPE); + for (int i = 0; i < openFieldCount; i++) { + fieldValueStorage.reset(); + try { + recordPointable.getOpenFieldValue(RecordUtil.FULLY_OPEN_RECORD_TYPE, i, + fieldValueStorage.getDataOutput()); + listBuilder.addItem(fieldValueStorage); + } catch (IOException e) { + throw HyracksDataException.create(e); + } + } + listBuilder.write(resultOutput, true); + } }
