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

Reply via email to