You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by GitBox <gi...@apache.org> on 2022/12/29 10:16:57 UTC

[GitHub] [doris] github-actions[bot] commented on a diff in pull request #15474: [WIP](struct-type) support struct-type in vectorize storage engine

github-actions[bot] commented on code in PR #15474:
URL: https://github.com/apache/doris/pull/15474#discussion_r1058864184


##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@ class ScalarTypeInfo : public TypeInfo {
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {

Review Comment:
   warning: no member named 'has_null' in 'doris::StructValue' [clang-diagnostic-error]
   ```cpp
           if (!l_value->has_null() && !r_value->has_null()) {
                         ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {

Review Comment:
   warning: no member named 'has_null' in 'doris::StructValue' [clang-diagnostic-error]
   ```cpp
           if (!l_value->has_null() && !r_value->has_null()) {
                                                 ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {

Review Comment:
   warning: expected ')' [clang-diagnostic-error]
   ```cpp
                   if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
                                                                                                ^
   ```
   **be/src/olap/types.h:225:** to match this '('
   ```cpp
                   if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
                      ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {

Review Comment:
   warning: no member named 'has_null' in 'doris::StructValue' [clang-diagnostic-error]
   ```cpp
           if (!l_value->has_null() && !r_value->has_null()) {
                                                 ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {

Review Comment:
   warning: no member named 'has_null' in 'doris::StructValue' [clang-diagnostic-error]
   ```cpp
           if (!l_value->has_null() && !r_value->has_null()) {
                         ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            while (cur < l_size && cur < r_size) {
+                int result = _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));

Review Comment:
   warning: use of undeclared identifier 'i' [clang-diagnostic-error]
   ```cpp
                   int result = _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
                                            ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            while (cur < l_size && cur < r_size) {
+                int result = _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                if (result != 0) {
+                    return result;
+                }
+                ++cur;
+            }
+        } else {
+            while (cur < l_size && cur < r_size) {
+                if (l_value->is_null_at(cur)) {
+                    if (!r_value->is_null_at(cur)) { // left is null & right is not null
+                        return -1;
+                    }
+                } else if (r_value->is_null_at(cur)) { // left is not null & right is null
+                    return 1;
+                } else { // both are not null
+                    int result =
+                            _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                    if (result != 0) {
+                        return result;
+                    }
+                }
+                ++cur;
+            }
+        }
+
+        if (l_size < r_size) {
+            return -1;
+        } else if (l_size > r_size) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    void shallow_copy(void* dest, const void* src) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+        dest_value->shallow_copy(src_value);
+    }
+
+    void deep_copy(void* dest, const void* src, MemPool* mem_pool) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+
+        if (src_value->size() == 0) {
+            new (dest_value) StructValue(src_value->size());
+            return;
+        }
+
+        dest_value->set_size(src_value->size());
+
+        size_t allocate_size = src_value->size() * sizeof(void*);
+        dest_value->set_values((void**)(mem_pool->allocate(allocate_size));
+        dest_value->set_has_null(src_value->has_null());

Review Comment:
   warning: no member named 'has_null' in 'doris::StructValue' [clang-diagnostic-error]
   ```cpp
           dest_value->set_has_null(src_value->has_null());
                                               ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            while (cur < l_size && cur < r_size) {
+                int result = _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                if (result != 0) {
+                    return result;
+                }
+                ++cur;
+            }
+        } else {
+            while (cur < l_size && cur < r_size) {
+                if (l_value->is_null_at(cur)) {
+                    if (!r_value->is_null_at(cur)) { // left is null & right is not null
+                        return -1;
+                    }
+                } else if (r_value->is_null_at(cur)) { // left is not null & right is null
+                    return 1;
+                } else { // both are not null
+                    int result =
+                            _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                    if (result != 0) {
+                        return result;
+                    }
+                }
+                ++cur;
+            }
+        }
+
+        if (l_size < r_size) {
+            return -1;
+        } else if (l_size > r_size) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    void shallow_copy(void* dest, const void* src) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+        dest_value->shallow_copy(src_value);
+    }
+
+    void deep_copy(void* dest, const void* src, MemPool* mem_pool) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+
+        if (src_value->size() == 0) {
+            new (dest_value) StructValue(src_value->size());
+            return;
+        }
+
+        dest_value->set_size(src_value->size());
+
+        size_t allocate_size = src_value->size() * sizeof(void*);
+        dest_value->set_values((void**)(mem_pool->allocate(allocate_size));
+        dest_value->set_has_null(src_value->has_null());

Review Comment:
   warning: no member named 'set_has_null' in 'doris::StructValue' [clang-diagnostic-error]
   ```cpp
           dest_value->set_has_null(src_value->has_null());
                       ^
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}

Review Comment:
   warning: unknown type name 'uint32_t' [clang-diagnostic-error]
   ```cpp
       StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
                                  ^
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}

Review Comment:
   warning: unknown type name 'uint32_t' [clang-diagnostic-error]
   ```cpp
       StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}
                                  ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            while (cur < l_size && cur < r_size) {
+                int result = _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                if (result != 0) {
+                    return result;
+                }
+                ++cur;
+            }
+        } else {
+            while (cur < l_size && cur < r_size) {
+                if (l_value->is_null_at(cur)) {
+                    if (!r_value->is_null_at(cur)) { // left is null & right is not null
+                        return -1;
+                    }
+                } else if (r_value->is_null_at(cur)) { // left is not null & right is null
+                    return 1;
+                } else { // both are not null
+                    int result =
+                            _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                    if (result != 0) {
+                        return result;
+                    }
+                }
+                ++cur;
+            }
+        }
+
+        if (l_size < r_size) {
+            return -1;
+        } else if (l_size > r_size) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    void shallow_copy(void* dest, const void* src) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+        dest_value->shallow_copy(src_value);
+    }
+
+    void deep_copy(void* dest, const void* src, MemPool* mem_pool) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+
+        if (src_value->size() == 0) {
+            new (dest_value) StructValue(src_value->size());
+            return;
+        }
+
+        dest_value->set_size(src_value->size());
+
+        size_t allocate_size = src_value->size() * sizeof(void*);
+        dest_value->set_values((void**)(mem_pool->allocate(allocate_size));
+        dest_value->set_has_null(src_value->has_null());
+
+        // allocate memory for children value
+        for (size_t i = 0; i < src_value->size(); ++i) {
+            dest_value->set_child_value(nullptr);
+            if (src_value->is_null_at(i)) continue;

Review Comment:
   warning: statement should be inside braces [readability-braces-around-statements]
   
   ```suggestion
               if (src_value->is_null_at(i)) { continue;
   }
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}
+
+    void to_struct_val(StructVal* val) const;
+    static StructValue from_struct_val(const StructVal& val);
+
+    uint32_t size() const { return _size; }
+    void set_size(uint32_t size) { _size = size; }
+
+    bool is_null_at(uint32_t index) const { return this->_has_null && this->_values[index] == nullptr; }
+
+    void shallow_copy(const StructValue* other);
+
+    // size_t get_byte_size(const TypeDescriptor& type) const;
+
+    // Deep copy collection.
+    // NOTICE: The CollectionValue* shallow_copied_cv must be initialized by calling memcpy function first (
+    // copy data from origin collection value).
+//    static void deep_copy_collection(StructValue* shallow_copied_sv,
+//                                     const TypeDescriptor& item_type,
+//                                     const GenMemFootprintFunc& gen_mem_footprint,
+//                                     bool convert_ptrs);
+
+//    static void deserialize_collection(CollectionValue* cv, const char* tuple_data,
+//                                       const TypeDescriptor& item_type);
+
+    const void** values() const { return _values; }

Review Comment:
   warning: cannot initialize return object of type 'const void **' with an lvalue of type 'void **const' [clang-diagnostic-error]
   ```cpp
       const void** values() const { return _values; }
                                            ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {

Review Comment:
   warning: expected ')' [clang-diagnostic-error]
   ```cpp
                   if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
                                                                                                ^
   ```
   **be/src/olap/types.h:210:** to match this '('
   ```cpp
                   if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
                      ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }

Review Comment:
   warning: expected statement [clang-diagnostic-error]
   ```cpp
               }
               ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            while (cur < l_size && cur < r_size) {
+                int result = _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                if (result != 0) {
+                    return result;
+                }
+                ++cur;
+            }
+        } else {
+            while (cur < l_size && cur < r_size) {
+                if (l_value->is_null_at(cur)) {
+                    if (!r_value->is_null_at(cur)) { // left is null & right is not null
+                        return -1;
+                    }
+                } else if (r_value->is_null_at(cur)) { // left is not null & right is null
+                    return 1;
+                } else { // both are not null
+                    int result =
+                            _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));

Review Comment:
   warning: use of undeclared identifier 'i' [clang-diagnostic-error]
   ```cpp
                               _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
                                           ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            while (cur < l_size && cur < r_size) {
+                int result = _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                if (result != 0) {
+                    return result;
+                }
+                ++cur;
+            }
+        } else {
+            while (cur < l_size && cur < r_size) {
+                if (l_value->is_null_at(cur)) {
+                    if (!r_value->is_null_at(cur)) { // left is null & right is not null
+                        return -1;
+                    }
+                } else if (r_value->is_null_at(cur)) { // left is not null & right is null
+                    return 1;
+                } else { // both are not null
+                    int result =
+                            _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                    if (result != 0) {
+                        return result;
+                    }
+                }
+                ++cur;
+            }
+        }
+
+        if (l_size < r_size) {
+            return -1;
+        } else if (l_size > r_size) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    void shallow_copy(void* dest, const void* src) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+        dest_value->shallow_copy(src_value);
+    }
+
+    void deep_copy(void* dest, const void* src, MemPool* mem_pool) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+
+        if (src_value->size() == 0) {
+            new (dest_value) StructValue(src_value->size());
+            return;
+        }
+
+        dest_value->set_size(src_value->size());
+
+        size_t allocate_size = src_value->size() * sizeof(void*);
+        dest_value->set_values((void**)(mem_pool->allocate(allocate_size));

Review Comment:
   warning: expected ')' [clang-diagnostic-error]
   ```cpp
           dest_value->set_values((void**)(mem_pool->allocate(allocate_size));
                                                                             ^
   ```
   **be/src/olap/types.h:294:** to match this '('
   ```cpp
           dest_value->set_values((void**)(mem_pool->allocate(allocate_size));
                                 ^
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}

Review Comment:
   warning: unknown type name 'uint32_t' [clang-diagnostic-error]
   ```cpp
       explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
                            ^
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}
+
+    void to_struct_val(StructVal* val) const;
+    static StructValue from_struct_val(const StructVal& val);

Review Comment:
   warning: unknown type name 'StructVal'; did you mean 'StructValue'? [clang-diagnostic-error]
   
   ```suggestion
       static StructValue from_struct_val(const StructValue& val);
   ```
   **be/src/runtime/struct_value.h:31:** 'StructValue' declared here
   ```cpp
   class StructValue {
         ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    int cmp(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        uint32_t l_size = l_value->size();
+        uint32_t r_size = r_value->size();
+        size_t cur = 0;
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            while (cur < l_size && cur < r_size) {
+                int result = _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                if (result != 0) {
+                    return result;
+                }
+                ++cur;
+            }
+        } else {
+            while (cur < l_size && cur < r_size) {
+                if (l_value->is_null_at(cur)) {
+                    if (!r_value->is_null_at(cur)) { // left is null & right is not null
+                        return -1;
+                    }
+                } else if (r_value->is_null_at(cur)) { // left is not null & right is null
+                    return 1;
+                } else { // both are not null
+                    int result =
+                            _type_infos[i]->cmp(l_value->child_value(cur), r_value->child_value(cur));
+                    if (result != 0) {
+                        return result;
+                    }
+                }
+                ++cur;
+            }
+        }
+
+        if (l_size < r_size) {
+            return -1;
+        } else if (l_size > r_size) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    void shallow_copy(void* dest, const void* src) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+        dest_value->shallow_copy(src_value);
+    }
+
+    void deep_copy(void* dest, const void* src, MemPool* mem_pool) const override {
+        auto dest_value = reinterpret_cast<StructValue*>(dest);
+        auto src_value = reinterpret_cast<const StructValue*>(src);
+
+        if (src_value->size() == 0) {
+            new (dest_value) StructValue(src_value->size());
+            return;
+        }
+
+        dest_value->set_size(src_value->size());
+
+        size_t allocate_size = src_value->size() * sizeof(void*);
+        dest_value->set_values((void**)(mem_pool->allocate(allocate_size));
+        dest_value->set_has_null(src_value->has_null());
+
+        // allocate memory for children value
+        for (size_t i = 0; i < src_value->size(); ++i) {
+            dest_value->set_child_value(nullptr);
+            if (src_value->is_null_at(i)) continue;
+            size_t child_size = _type_infos[i]->size();
+            dest_value->set_child_value(mem_pool->allocate(child_size), i);
+        }
+
+        // copy children value
+        for (size_t i = 0; i < src_value->size(); ++i) {
+            if (src_value->is_null_at(i)) continue;

Review Comment:
   warning: statement should be inside braces [readability-braces-around-statements]
   
   ```suggestion
               if (src_value->is_null_at(i)) { continue;
   }
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}
+
+    void to_struct_val(StructVal* val) const;

Review Comment:
   warning: unknown type name 'StructVal'; did you mean 'StructValue'? [clang-diagnostic-error]
   
   ```suggestion
       void to_struct_val(StructValue* val) const;
   ```
   **be/src/runtime/struct_value.h:31:** 'StructValue' declared here
   ```cpp
   class StructValue {
         ^
   ```
   



##########
be/src/olap/types.h:
##########
@@ -188,6 +189,232 @@
     friend class ScalarTypeInfoResolver;
 };
 
+class StructTypeInfo: public TypeInfo {
+public:
+    explicit StructTypeInfo(std::vector<TypeInfoPtr>& type_infos) {
+        for (TypeInfoPtr& type_info : type_infos) {
+            _type_infos.push_back(std::move(type_info));
+        }
+    }
+    ~StructTypeInfo() override = default;
+
+    bool equal(const void* left, const void* right) const override {
+        auto l_value = reinterpret_cast<const StructValue*>(left);
+        auto r_value = reinterpret_cast<const StructValue*>(right);
+        if (l_value->size() != r_value->size()) {
+            return false;
+        }
+        uint32_t size = l_value->size();
+
+        if (!l_value->has_null() && !r_value->has_null()) {
+            for (size_t i = 0; i < size; ++i) {
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }
+        } else {
+            for (size_t i = 0; i < size; ++i) {
+                if (l_value->is_null_at(i)) {
+                    if (r_value->is_null_at(i)) { // both are null
+                        continue;
+                    } else { // left is null & right is not null
+                        return false;
+                    }
+                } else if (r_value->is_null_at(i)) { // left is not null & right is null
+                    return false;
+                }
+                if (!_type_infos[i]->equal(l_value->child_value(i), r_value->child_value(i)) {
+                    return false;
+                }
+            }

Review Comment:
   warning: expected statement [clang-diagnostic-error]
   ```cpp
               }
               ^
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}
+
+    void to_struct_val(StructVal* val) const;
+    static StructValue from_struct_val(const StructVal& val);
+
+    uint32_t size() const { return _size; }

Review Comment:
   warning: unknown type name 'uint32_t' [clang-diagnostic-error]
   ```cpp
       uint32_t size() const { return _size; }
       ^
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}
+
+    void to_struct_val(StructVal* val) const;
+    static StructValue from_struct_val(const StructVal& val);
+
+    uint32_t size() const { return _size; }
+    void set_size(uint32_t size) { _size = size; }
+
+    bool is_null_at(uint32_t index) const { return this->_has_null && this->_values[index] == nullptr; }
+
+    void shallow_copy(const StructValue* other);
+
+    // size_t get_byte_size(const TypeDescriptor& type) const;
+
+    // Deep copy collection.
+    // NOTICE: The CollectionValue* shallow_copied_cv must be initialized by calling memcpy function first (
+    // copy data from origin collection value).
+//    static void deep_copy_collection(StructValue* shallow_copied_sv,
+//                                     const TypeDescriptor& item_type,
+//                                     const GenMemFootprintFunc& gen_mem_footprint,
+//                                     bool convert_ptrs);
+
+//    static void deserialize_collection(CollectionValue* cv, const char* tuple_data,
+//                                       const TypeDescriptor& item_type);
+
+    const void** values() const { return _values; }
+    void** mutable_values() { return _values; }
+    void set_values(void** values) { _values = values; }
+    const void* child_value(uint32_t index) const { return _values[i]; }

Review Comment:
   warning: unknown type name 'uint32_t' [clang-diagnostic-error]
   ```cpp
       const void* child_value(uint32_t index) const { return _values[i]; }
                               ^
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}
+
+    void to_struct_val(StructVal* val) const;
+    static StructValue from_struct_val(const StructVal& val);
+
+    uint32_t size() const { return _size; }
+    void set_size(uint32_t size) { _size = size; }

Review Comment:
   warning: unknown type name 'uint32_t' [clang-diagnostic-error]
   ```cpp
       void set_size(uint32_t size) { _size = size; }
                     ^
   ```
   



##########
be/src/runtime/struct_value.h:
##########
@@ -0,0 +1,83 @@
+// 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.
+
+#pragma once
+
+#include <type_traits>
+
+namespace doris_udf {
+    class FunctionContext;
+    struct AnyVal;
+} // namespace doris_udf
+
+namespace doris {
+
+using doris_udf::FunctionContext;
+using doris_udf::AnyVal;
+
+class StructValue {
+public:
+    StructValue() = default;
+
+    explicit StructValue(uint32_t size) : _values(nullptr), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size) : _values(values), _size(size), _has_null(false) {}
+    StructValue(void** values, uint32_t size, bool has_null) : _values(values), _size(size), _has_null(has_null) {}
+
+    void to_struct_val(StructVal* val) const;
+    static StructValue from_struct_val(const StructVal& val);
+
+    uint32_t size() const { return _size; }
+    void set_size(uint32_t size) { _size = size; }
+
+    bool is_null_at(uint32_t index) const { return this->_has_null && this->_values[index] == nullptr; }

Review Comment:
   warning: unknown type name 'uint32_t' [clang-diagnostic-error]
   ```cpp
       bool is_null_at(uint32_t index) const { return this->_has_null && this->_values[index] == nullptr; }
                       ^
   ```
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org