presto-connector/src/main/java/com/facebook/presto/maxcompute/utils/ArrowUtils.java [161:296]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            case STRING:
            case VARCHAR:
            case JSON:
                return Slices.wrappedBuffer(((ArrowVarCharAccessor) dataAccessor).getBytes(rowId));
            // char type need to trim tail spaces
            case CHAR:
                String str = new String(((ArrowVarCharAccessor) dataAccessor).getBytes(rowId),
                        StandardCharsets.UTF_8).replaceAll("\\s+$", "");
                return Slices.wrappedBuffer(str.getBytes(StandardCharsets.UTF_8));
            case BINARY:
                return Slices.wrappedBuffer(((ArrowVarBinaryAccessor) dataAccessor).getBinary(rowId));
            case DATE:
                // return epoch days
                return ((Number) ((ArrowDateDayAccessor) dataAccessor).getEpochDay(rowId)).longValue();
            case DATETIME:
            case TIMESTAMP:
            case TIMESTAMP_NTZ:
                // return epoch millis
                return convertToEpochMillis(((ArrowTimestampAccessor) dataAccessor).getType(),
                        ((ArrowTimestampAccessor) dataAccessor).getEpochTime(rowId));
            case ARRAY:
                return ((ArrowArrayAccessorForBlock) dataAccessor).getArray(rowId);
            case MAP:
                return ((ArrowMapAccessorForRecord) dataAccessor).getMap(rowId);
            case STRUCT:
                return ((ArrowStructAccessorForRecord) dataAccessor).getStruct(rowId);
            case UNKNOWN:
                return ((SimpleDataAccessor) dataAccessor).get(rowId);
            default:
                throw new UnsupportedOperationException(
                        "Datatype not supported: " + typeInfo.getTypeName());
        }
    }

    private static long convertToEpochMillis(ArrowType.Timestamp timestampType, long epochTime)
    {
        switch (timestampType.getUnit()) {
            case SECOND:
                return epochTime * NANOS_PER_MILLI;
            case MILLISECOND:
                return epochTime;
            case MICROSECOND:
                return epochTime / MICROS_PER_MILLI;
            case NANOSECOND:
                return epochTime / NANOS_PER_MILLI;
            default:
                throw new UnsupportedOperationException("Unit not supported: " + timestampType.getUnit());
        }
    }

    public static class ArrowArrayAccessorForBlock
            extends ArrowArrayAccessor<List<Object>>
    {
        private final TypeInfo elementTypeInfo;
        private final ArrowVectorAccessor dataAccessor;

        public ArrowArrayAccessorForBlock(ListVector vector, TypeInfo typeInfo)
        {
            super(vector);
            this.elementTypeInfo = ((ArrayTypeInfo) typeInfo).getElementTypeInfo();

            this.dataAccessor =
                    createColumnVectorAccessor(vector.getDataVector(), elementTypeInfo);
        }

        @Override
        protected List<Object> getArrayData(int offset, int length)
        {
            List<Object> list = new ArrayList<>();
            for (int i = 0; i < length; i++) {
                list.add(getData(dataAccessor, elementTypeInfo, offset + i));
            }
            return list;
        }
    }

    public static class ArrowMapAccessorForRecord
            extends ArrowMapAccessor<Map<Object, Object>>
    {
        private final TypeInfo keyTypeInfo;
        private final TypeInfo valueTypeInfo;
        private final ArrowVectorAccessor keyAccessor;
        private final ArrowVectorAccessor valueAccessor;

        public ArrowMapAccessorForRecord(MapVector mapVector, TypeInfo typeInfo)
        {
            super(mapVector);
            this.keyTypeInfo = ((MapTypeInfo) typeInfo).getKeyTypeInfo();
            this.valueTypeInfo = ((MapTypeInfo) typeInfo).getValueTypeInfo();
            StructVector entries = (StructVector) mapVector.getDataVector();
            this.keyAccessor = createColumnVectorAccessor(
                    entries.getChild(MapVector.KEY_NAME), keyTypeInfo);
            this.valueAccessor = createColumnVectorAccessor(
                    entries.getChild(MapVector.VALUE_NAME), valueTypeInfo);
        }

        @Override
        protected Map<Object, Object> getMapData(int offset, int numElements)
        {
            Map<Object, Object> map = new HashMap<>();
            for (int i = 0; i < numElements; i++) {
                map.put(getData(keyAccessor, keyTypeInfo, offset + i),
                        getData(valueAccessor, valueTypeInfo, offset + i));
            }
            return map;
        }
    }

    public static class ArrowStructAccessorForRecord
            extends ArrowStructAccessor<Struct>
    {
        private final ArrowVectorAccessor[] childAccessors;
        private final TypeInfo structTypeInfo;
        private final List<TypeInfo> childTypeInfos;

        public ArrowStructAccessorForRecord(StructVector structVector,
                TypeInfo typeInfo)
        {
            super(structVector);
            this.structTypeInfo = typeInfo;
            this.childTypeInfos = ((StructTypeInfo) typeInfo).getFieldTypeInfos();
            this.childAccessors = new ArrowVectorAccessor[structVector.size()];
            for (int i = 0; i < childAccessors.length; i++) {
                this.childAccessors[i] = createColumnVectorAccessor(
                        structVector.getVectorById(i), childTypeInfos.get(i));
            }
        }

        @Override
        public Struct getStruct(int rowId)
        {
            List<Object> values = new ArrayList<>();
            for (int i = 0; i < childAccessors.length; i++) {
                values.add(getData(childAccessors[i], childTypeInfos.get(i), rowId));
            }
            return new SimpleStruct((StructTypeInfo) structTypeInfo, values);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



trino-connector/src/main/java/io/trino/plugin/maxcompute/utils/ArrowUtils.java [161:296]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            case STRING:
            case VARCHAR:
            case JSON:
                return Slices.wrappedBuffer(((ArrowVarCharAccessor) dataAccessor).getBytes(rowId));
            // char type need to trim tail spaces
            case CHAR:
                String str = new String(((ArrowVarCharAccessor) dataAccessor).getBytes(rowId),
                        StandardCharsets.UTF_8).replaceAll("\\s+$", "");
                return Slices.wrappedBuffer(str.getBytes(StandardCharsets.UTF_8));
            case BINARY:
                return Slices.wrappedBuffer(((ArrowVarBinaryAccessor) dataAccessor).getBinary(rowId));
            case DATE:
                // return epoch days
                return ((Number) ((ArrowDateDayAccessor) dataAccessor).getEpochDay(rowId)).longValue();
            case DATETIME:
            case TIMESTAMP:
            case TIMESTAMP_NTZ:
                // return epoch millis
                return convertToEpochMillis(((ArrowTimestampAccessor) dataAccessor).getType(),
                        ((ArrowTimestampAccessor) dataAccessor).getEpochTime(rowId));
            case ARRAY:
                return ((ArrowArrayAccessorForBlock) dataAccessor).getArray(rowId);
            case MAP:
                return ((ArrowMapAccessorForRecord) dataAccessor).getMap(rowId);
            case STRUCT:
                return ((ArrowStructAccessorForRecord) dataAccessor).getStruct(rowId);
            case UNKNOWN:
                return ((SimpleDataAccessor) dataAccessor).get(rowId);
            default:
                throw new UnsupportedOperationException(
                        "Datatype not supported: " + typeInfo.getTypeName());
        }
    }

    private static long convertToEpochMillis(ArrowType.Timestamp timestampType, long epochTime)
    {
        switch (timestampType.getUnit()) {
            case SECOND:
                return epochTime * NANOS_PER_MILLI;
            case MILLISECOND:
                return epochTime;
            case MICROSECOND:
                return epochTime / MICROS_PER_MILLI;
            case NANOSECOND:
                return epochTime / NANOS_PER_MILLI;
            default:
                throw new UnsupportedOperationException("Unit not supported: " + timestampType.getUnit());
        }
    }

    public static class ArrowArrayAccessorForBlock
            extends ArrowArrayAccessor<List<Object>>
    {
        private final TypeInfo elementTypeInfo;
        private final ArrowVectorAccessor dataAccessor;

        public ArrowArrayAccessorForBlock(ListVector vector, TypeInfo typeInfo)
        {
            super(vector);
            this.elementTypeInfo = ((ArrayTypeInfo) typeInfo).getElementTypeInfo();

            this.dataAccessor =
                    createColumnVectorAccessor(vector.getDataVector(), elementTypeInfo);
        }

        @Override
        protected List<Object> getArrayData(int offset, int length)
        {
            List<Object> list = new ArrayList<>();
            for (int i = 0; i < length; i++) {
                list.add(getData(dataAccessor, elementTypeInfo, offset + i));
            }
            return list;
        }
    }

    public static class ArrowMapAccessorForRecord
            extends ArrowMapAccessor<Map<Object, Object>>
    {
        private final TypeInfo keyTypeInfo;
        private final TypeInfo valueTypeInfo;
        private final ArrowVectorAccessor keyAccessor;
        private final ArrowVectorAccessor valueAccessor;

        public ArrowMapAccessorForRecord(MapVector mapVector, TypeInfo typeInfo)
        {
            super(mapVector);
            this.keyTypeInfo = ((MapTypeInfo) typeInfo).getKeyTypeInfo();
            this.valueTypeInfo = ((MapTypeInfo) typeInfo).getValueTypeInfo();
            StructVector entries = (StructVector) mapVector.getDataVector();
            this.keyAccessor = createColumnVectorAccessor(
                    entries.getChild(MapVector.KEY_NAME), keyTypeInfo);
            this.valueAccessor = createColumnVectorAccessor(
                    entries.getChild(MapVector.VALUE_NAME), valueTypeInfo);
        }

        @Override
        protected Map<Object, Object> getMapData(int offset, int numElements)
        {
            Map<Object, Object> map = new HashMap<>();
            for (int i = 0; i < numElements; i++) {
                map.put(getData(keyAccessor, keyTypeInfo, offset + i),
                        getData(valueAccessor, valueTypeInfo, offset + i));
            }
            return map;
        }
    }

    public static class ArrowStructAccessorForRecord
            extends ArrowStructAccessor<Struct>
    {
        private final ArrowVectorAccessor[] childAccessors;
        private final TypeInfo structTypeInfo;
        private final List<TypeInfo> childTypeInfos;

        public ArrowStructAccessorForRecord(StructVector structVector,
                TypeInfo typeInfo)
        {
            super(structVector);
            this.structTypeInfo = typeInfo;
            this.childTypeInfos = ((StructTypeInfo) typeInfo).getFieldTypeInfos();
            this.childAccessors = new ArrowVectorAccessor[structVector.size()];
            for (int i = 0; i < childAccessors.length; i++) {
                this.childAccessors[i] = createColumnVectorAccessor(
                        structVector.getVectorById(i), childTypeInfos.get(i));
            }
        }

        @Override
        public Struct getStruct(int rowId)
        {
            List<Object> values = new ArrayList<>();
            for (int i = 0; i < childAccessors.length; i++) {
                values.add(getData(childAccessors[i], childTypeInfos.get(i), rowId));
            }
            return new SimpleStruct((StructTypeInfo) structTypeInfo, values);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



