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


##########
be/src/runtime/types.cpp:
##########
@@ -240,64 +251,67 @@ TypeDescriptor::TypeDescriptor(const 
google::protobuf::RepeatedPtrField<PTypeNod
     default:
         DCHECK(false) << node.type();
     }
-}
-
-std::string TypeDescriptor::debug_string() const {
-    std::stringstream ss;
-    switch (type) {
-    case TYPE_CHAR:
-        ss << "CHAR(" << len << ")";
-        return ss.str();
-    case TYPE_DECIMALV2:
-        ss << "DECIMALV2(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL32:
-        ss << "DECIMAL32(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL64:
-        ss << "DECIMAL64(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL128I:
-        ss << "DECIMAL128(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_ARRAY: {
-        ss << "ARRAY<" << children[0].debug_string() << ">";
-        return ss.str();
     }
-    case TYPE_STRUCT: {
-        ss << "STRUCT<";
-        for (size_t i = 0; i < children.size(); i++) {
-            ss << field_names[i];
-            ss << ":";
-            ss << children[i].debug_string();
-            if (i != children.size() - 1) {
-                ss << ",";
+
+    std::string TypeDescriptor::debug_string() const {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       std::string TypeDescriptor::debug_string() const {
                                                        ^
   ```
   



##########
be/src/runtime/types.cpp:
##########
@@ -240,64 +251,67 @@
     default:
         DCHECK(false) << node.type();
     }
-}
-
-std::string TypeDescriptor::debug_string() const {
-    std::stringstream ss;
-    switch (type) {
-    case TYPE_CHAR:
-        ss << "CHAR(" << len << ")";
-        return ss.str();
-    case TYPE_DECIMALV2:
-        ss << "DECIMALV2(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL32:
-        ss << "DECIMAL32(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL64:
-        ss << "DECIMAL64(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL128I:
-        ss << "DECIMAL128(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_ARRAY: {
-        ss << "ARRAY<" << children[0].debug_string() << ">";
-        return ss.str();
     }
-    case TYPE_STRUCT: {
-        ss << "STRUCT<";
-        for (size_t i = 0; i < children.size(); i++) {
-            ss << field_names[i];
-            ss << ":";
-            ss << children[i].debug_string();
-            if (i != children.size() - 1) {
-                ss << ",";
+
+    std::string TypeDescriptor::debug_string() const {
+        std::stringstream ss;
+        switch (type) {
+        case TYPE_CHAR:
+            ss << "CHAR(" << len << ")";
+            return ss.str();
+        case TYPE_DECIMALV2:
+            ss << "DECIMALV2(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL32:
+            ss << "DECIMAL32(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL64:
+            ss << "DECIMAL64(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL128I:
+            ss << "DECIMAL128(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_ARRAY: {
+            ss << "ARRAY<" << children[0].debug_string() << ">";
+            return ss.str();
+        }
+        case TYPE_MAP:
+            ss << "MAP<" << children[0].debug_string() << ", " << 
children[1].debug_string() << ">";
+            return ss.str();
+        case TYPE_STRUCT: {
+            ss << "STRUCT<";
+            for (size_t i = 0; i < children.size(); i++) {
+                ss << field_names[i];
+                ss << ":";
+                ss << children[i].debug_string();
+                if (i != children.size() - 1) {
+                    ss << ",";
+                }
             }
+            ss << ">";
+            return ss.str();
+        }
+        default:
+            return type_to_string(type);
         }
-        ss << ">";
-        return ss.str();
-    }
-    default:
-        return type_to_string(type);
     }
-}
 
-std::ostream& operator<<(std::ostream& os, const TypeDescriptor& type) {
-    os << type.debug_string();
-    return os;
-}
+    std::ostream& operator<<(std::ostream& os, const TypeDescriptor& type) {
+        os << type.debug_string();
+        return os;
+    }
 
-TTypeDesc create_type_desc(PrimitiveType type, int precision, int scale) {
-    TTypeDesc type_desc;
-    std::vector<TTypeNode> node_type;
-    node_type.emplace_back();
-    TScalarType scalarType;
-    scalarType.__set_type(to_thrift(type));
-    scalarType.__set_len(-1);
-    scalarType.__set_precision(precision);
-    scalarType.__set_scale(scale);
-    node_type.back().__set_scalar_type(scalarType);
-    type_desc.__set_types(node_type);
-    return type_desc;
-}
+    TTypeDesc create_type_desc(PrimitiveType type, int precision, int scale) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       TTypeDesc create_type_desc(PrimitiveType type, int precision, int scale) 
{
                                                                                
^
   ```
   



##########
be/src/vec/data_types/data_type_factory.cpp:
##########
@@ -169,17 +179,23 @@ DataTypePtr DataTypeFactory::create_data_type(const 
TypeDescriptor& col_desc, bo
         }
         nested = std::make_shared<DataTypeStruct>(dataTypes, names);
         break;
-    }
-    case INVALID_TYPE:
-    default:
-        DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    case TYPE_MAP:
+        DCHECK(col_desc.children.size() == 2);
+        nested = std::make_shared<vectorized::DataTypeMap>(
+                create_data_type(col_desc.children[0], 
col_desc.contains_nulls[0]),
+                create_data_type(col_desc.children[1], 
col_desc.contains_nulls[1]));
         break;
     }
+case INVALID_TYPE:

Review Comment:
   warning: 'case' statement not in switch statement [clang-diagnostic-error]
   ```cpp
   case INVALID_TYPE:
   ^
   ```
   



##########
be/src/vec/data_types/data_type_factory.cpp:
##########
@@ -169,17 +179,23 @@
         }
         nested = std::make_shared<DataTypeStruct>(dataTypes, names);
         break;
-    }
-    case INVALID_TYPE:
-    default:
-        DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    case TYPE_MAP:
+        DCHECK(col_desc.children.size() == 2);
+        nested = std::make_shared<vectorized::DataTypeMap>(
+                create_data_type(col_desc.children[0], 
col_desc.contains_nulls[0]),
+                create_data_type(col_desc.children[1], 
col_desc.contains_nulls[1]));
         break;
     }
+case INVALID_TYPE:
+default:
+    DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    break;
+}
 
-    if (nested && is_nullable) {
-        return std::make_shared<vectorized::DataTypeNullable>(nested);
-    }
-    return nested;
+if (nested && is_nullable) {

Review Comment:
   warning: expected unqualified-id [clang-diagnostic-error]
   ```cpp
   if (nested && is_nullable) {
   ^
   ```
   



##########
be/src/vec/data_types/data_type_factory.cpp:
##########
@@ -169,17 +179,23 @@
         }
         nested = std::make_shared<DataTypeStruct>(dataTypes, names);
         break;
-    }
-    case INVALID_TYPE:
-    default:
-        DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    case TYPE_MAP:
+        DCHECK(col_desc.children.size() == 2);
+        nested = std::make_shared<vectorized::DataTypeMap>(
+                create_data_type(col_desc.children[0], 
col_desc.contains_nulls[0]),
+                create_data_type(col_desc.children[1], 
col_desc.contains_nulls[1]));
         break;
     }
+case INVALID_TYPE:
+default:
+    DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    break;
+}
 
-    if (nested && is_nullable) {
-        return std::make_shared<vectorized::DataTypeNullable>(nested);
-    }
-    return nested;
+if (nested && is_nullable) {
+    return std::make_shared<vectorized::DataTypeNullable>(nested);
+}
+return nested;
 }
 
 DataTypePtr DataTypeFactory::_create_primitive_data_type(const FieldType& 
type, int precision,

Review Comment:
   warning: use of undeclared identifier 'DataTypeFactory'; did you mean 
'doris::vectorized::DataTypeFactory'? [clang-diagnostic-error]
   
   ```suggestion
   DataTypePtr 
doris::vectorized::DataTypeFactory::_create_primitive_data_type(const 
FieldType& type, int precision,
   ```
   **be/src/vec/data_types/data_type_factory.hpp:48:** 
'doris::vectorized::DataTypeFactory' declared here
   ```cpp
   class DataTypeFactory {
         ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
                                                                                
      ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@ Status VExpr::create_expr(doris::ObjectPool* pool, 
const doris::TExprNode& texpr
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
                                             int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
                                                                                
                   ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->open(state));
         }
         return Status::OK();
     }
-    new_ctxs->resize(ctxs.size());
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
-    }
-    return Status::OK();
-}
-std::string VExpr::debug_string() const {
-    // TODO: implement partial debug string for member vars
-    std::stringstream out;
-    out << " type=" << _type.debug_string();
-    out << " codegen="
-        << "false";
 
-    if (!_children.empty()) {
-        out << " children=" << debug_string(_children);
+    Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                                      std::vector<VExprContext*>* new_ctxs) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
                                         std::vector<VExprContext*>* new_ctxs) {
                                                                               ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->open(state));
         }
         return Status::OK();
     }
-    new_ctxs->resize(ctxs.size());
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
-    }
-    return Status::OK();
-}
-std::string VExpr::debug_string() const {
-    // TODO: implement partial debug string for member vars
-    std::stringstream out;
-    out << " type=" << _type.debug_string();
-    out << " codegen="
-        << "false";
 
-    if (!_children.empty()) {
-        out << " children=" << debug_string(_children);
+    Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                                      std::vector<VExprContext*>* new_ctxs) {
+        DCHECK(new_ctxs != nullptr);
+        if (!new_ctxs->empty()) {
+            // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
+            DCHECK_EQ(new_ctxs->size(), ctxs.size());
+            for (int i = 0; i < new_ctxs->size(); ++i) {
+                DCHECK((*new_ctxs)[i]->_is_clone);
+            }
+            return Status::OK();
+        }
+        new_ctxs->resize(ctxs.size());
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
+        }
+        return Status::OK();
     }
+    std::string VExpr::debug_string() const {
+        // TODO: implement partial debug string for member vars
+        std::stringstream out;
+        out << " type=" << _type.debug_string();
+        out << " codegen="
+            << "false";
 
-    return out.str();
-}
-
-std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
-    std::stringstream out;
-    out << "[";
+        if (!_children.empty()) {
+            out << " children=" << debug_string(_children);
+        }
 
-    for (int i = 0; i < exprs.size(); ++i) {
-        out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        return out.str();
     }
 
-    out << "]";
-    return out.str();
-}
+    std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
+        std::stringstream out;
+        out << "[";
 
-std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
-    std::vector<VExpr*> exprs;
-    for (int i = 0; i < ctxs.size(); ++i) {
-        exprs.push_back(ctxs[i]->root());
+        for (int i = 0; i < exprs.size(); ++i) {
+            out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        }
+
+        out << "]";
+        return out.str();
     }
-    return debug_string(exprs);
-}
 
-bool VExpr::is_constant() const {
-    for (int i = 0; i < _children.size(); ++i) {
-        if (!_children[i]->is_constant()) {
-            return false;
+    std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
                                                                               ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->open(state));
         }
         return Status::OK();
     }
-    new_ctxs->resize(ctxs.size());
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
-    }
-    return Status::OK();
-}
-std::string VExpr::debug_string() const {
-    // TODO: implement partial debug string for member vars
-    std::stringstream out;
-    out << " type=" << _type.debug_string();
-    out << " codegen="
-        << "false";
 
-    if (!_children.empty()) {
-        out << " children=" << debug_string(_children);
+    Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                                      std::vector<VExprContext*>* new_ctxs) {
+        DCHECK(new_ctxs != nullptr);
+        if (!new_ctxs->empty()) {
+            // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
+            DCHECK_EQ(new_ctxs->size(), ctxs.size());
+            for (int i = 0; i < new_ctxs->size(); ++i) {
+                DCHECK((*new_ctxs)[i]->_is_clone);
+            }
+            return Status::OK();
+        }
+        new_ctxs->resize(ctxs.size());
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
+        }
+        return Status::OK();
     }
+    std::string VExpr::debug_string() const {
+        // TODO: implement partial debug string for member vars
+        std::stringstream out;
+        out << " type=" << _type.debug_string();
+        out << " codegen="
+            << "false";
 
-    return out.str();
-}
-
-std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
-    std::stringstream out;
-    out << "[";
+        if (!_children.empty()) {
+            out << " children=" << debug_string(_children);
+        }
 
-    for (int i = 0; i < exprs.size(); ++i) {
-        out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        return out.str();
     }
 
-    out << "]";
-    return out.str();
-}
+    std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
+        std::stringstream out;
+        out << "[";
 
-std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
-    std::vector<VExpr*> exprs;
-    for (int i = 0; i < ctxs.size(); ++i) {
-        exprs.push_back(ctxs[i]->root());
+        for (int i = 0; i < exprs.size(); ++i) {
+            out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        }
+
+        out << "]";
+        return out.str();
     }
-    return debug_string(exprs);
-}
 
-bool VExpr::is_constant() const {
-    for (int i = 0; i < _children.size(); ++i) {
-        if (!_children[i]->is_constant()) {
-            return false;
+    std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
+        std::vector<VExpr*> exprs;
+        for (int i = 0; i < ctxs.size(); ++i) {
+            exprs.push_back(ctxs[i]->root());
         }
+        return debug_string(exprs);
     }
 
-    return true;
-}
+    bool VExpr::is_constant() const {
+        for (int i = 0; i < _children.size(); ++i) {
+            if (!_children[i]->is_constant()) {
+                return false;
+            }
+        }
 
-Status VExpr::get_const_col(VExprContext* context, ColumnPtrWrapper** output) {
-    *output = nullptr;
-    if (!is_constant()) {
-        return Status::OK();
+        return true;
     }
 
-    if (_constant_col != nullptr) {
+    Status VExpr::get_const_col(VExprContext * context, ColumnPtrWrapper * 
*output) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       Status VExpr::get_const_col(VExprContext * context, ColumnPtrWrapper * 
*output) {
                                                                                
       ^
   ```
   



##########
be/src/runtime/types.cpp:
##########
@@ -240,64 +251,67 @@
     default:
         DCHECK(false) << node.type();
     }
-}
-
-std::string TypeDescriptor::debug_string() const {
-    std::stringstream ss;
-    switch (type) {
-    case TYPE_CHAR:
-        ss << "CHAR(" << len << ")";
-        return ss.str();
-    case TYPE_DECIMALV2:
-        ss << "DECIMALV2(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL32:
-        ss << "DECIMAL32(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL64:
-        ss << "DECIMAL64(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL128I:
-        ss << "DECIMAL128(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_ARRAY: {
-        ss << "ARRAY<" << children[0].debug_string() << ">";
-        return ss.str();
     }
-    case TYPE_STRUCT: {
-        ss << "STRUCT<";
-        for (size_t i = 0; i < children.size(); i++) {
-            ss << field_names[i];
-            ss << ":";
-            ss << children[i].debug_string();
-            if (i != children.size() - 1) {
-                ss << ",";
+
+    std::string TypeDescriptor::debug_string() const {
+        std::stringstream ss;
+        switch (type) {
+        case TYPE_CHAR:
+            ss << "CHAR(" << len << ")";
+            return ss.str();
+        case TYPE_DECIMALV2:
+            ss << "DECIMALV2(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL32:
+            ss << "DECIMAL32(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL64:
+            ss << "DECIMAL64(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL128I:
+            ss << "DECIMAL128(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_ARRAY: {
+            ss << "ARRAY<" << children[0].debug_string() << ">";
+            return ss.str();
+        }
+        case TYPE_MAP:
+            ss << "MAP<" << children[0].debug_string() << ", " << 
children[1].debug_string() << ">";
+            return ss.str();
+        case TYPE_STRUCT: {
+            ss << "STRUCT<";
+            for (size_t i = 0; i < children.size(); i++) {
+                ss << field_names[i];
+                ss << ":";
+                ss << children[i].debug_string();
+                if (i != children.size() - 1) {
+                    ss << ",";
+                }
             }
+            ss << ">";
+            return ss.str();
+        }
+        default:
+            return type_to_string(type);
         }
-        ss << ">";
-        return ss.str();
-    }
-    default:
-        return type_to_string(type);
     }
-}
 
-std::ostream& operator<<(std::ostream& os, const TypeDescriptor& type) {
-    os << type.debug_string();
-    return os;
-}
+    std::ostream& operator<<(std::ostream& os, const TypeDescriptor& type) {
+        os << type.debug_string();
+        return os;
+    }
 
-TTypeDesc create_type_desc(PrimitiveType type, int precision, int scale) {
-    TTypeDesc type_desc;
-    std::vector<TTypeNode> node_type;
-    node_type.emplace_back();
-    TScalarType scalarType;
-    scalarType.__set_type(to_thrift(type));
-    scalarType.__set_len(-1);
-    scalarType.__set_precision(precision);
-    scalarType.__set_scale(scale);
-    node_type.back().__set_scalar_type(scalarType);
-    type_desc.__set_types(node_type);
-    return type_desc;
-}
+    TTypeDesc create_type_desc(PrimitiveType type, int precision, int scale) {
+        TTypeDesc type_desc;
+        std::vector<TTypeNode> node_type;
+        node_type.emplace_back();
+        TScalarType scalarType;
+        scalarType.__set_type(to_thrift(type));
+        scalarType.__set_len(-1);
+        scalarType.__set_precision(precision);
+        scalarType.__set_scale(scale);
+        node_type.back().__set_scalar_type(scalarType);
+        type_desc.__set_types(node_type);
+        return type_desc;
+    }
 } // namespace doris

Review Comment:
   warning: expected '}' [clang-diagnostic-error]
   ```cpp
   } // namespace doris
                       ^
   ```
   **be/src/runtime/types.cpp:24:** to match this '{'
   ```cpp
   namespace doris {
                   ^
   ```
   



##########
be/src/runtime/types.cpp:
##########
@@ -240,64 +251,67 @@
     default:
         DCHECK(false) << node.type();
     }
-}
-
-std::string TypeDescriptor::debug_string() const {
-    std::stringstream ss;
-    switch (type) {
-    case TYPE_CHAR:
-        ss << "CHAR(" << len << ")";
-        return ss.str();
-    case TYPE_DECIMALV2:
-        ss << "DECIMALV2(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL32:
-        ss << "DECIMAL32(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL64:
-        ss << "DECIMAL64(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_DECIMAL128I:
-        ss << "DECIMAL128(" << precision << ", " << scale << ")";
-        return ss.str();
-    case TYPE_ARRAY: {
-        ss << "ARRAY<" << children[0].debug_string() << ">";
-        return ss.str();
     }
-    case TYPE_STRUCT: {
-        ss << "STRUCT<";
-        for (size_t i = 0; i < children.size(); i++) {
-            ss << field_names[i];
-            ss << ":";
-            ss << children[i].debug_string();
-            if (i != children.size() - 1) {
-                ss << ",";
+
+    std::string TypeDescriptor::debug_string() const {
+        std::stringstream ss;
+        switch (type) {
+        case TYPE_CHAR:
+            ss << "CHAR(" << len << ")";
+            return ss.str();
+        case TYPE_DECIMALV2:
+            ss << "DECIMALV2(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL32:
+            ss << "DECIMAL32(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL64:
+            ss << "DECIMAL64(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_DECIMAL128I:
+            ss << "DECIMAL128(" << precision << ", " << scale << ")";
+            return ss.str();
+        case TYPE_ARRAY: {
+            ss << "ARRAY<" << children[0].debug_string() << ">";
+            return ss.str();
+        }
+        case TYPE_MAP:
+            ss << "MAP<" << children[0].debug_string() << ", " << 
children[1].debug_string() << ">";
+            return ss.str();
+        case TYPE_STRUCT: {
+            ss << "STRUCT<";
+            for (size_t i = 0; i < children.size(); i++) {
+                ss << field_names[i];
+                ss << ":";
+                ss << children[i].debug_string();
+                if (i != children.size() - 1) {
+                    ss << ",";
+                }
             }
+            ss << ">";
+            return ss.str();
+        }
+        default:
+            return type_to_string(type);
         }
-        ss << ">";
-        return ss.str();
-    }
-    default:
-        return type_to_string(type);
     }
-}
 
-std::ostream& operator<<(std::ostream& os, const TypeDescriptor& type) {
-    os << type.debug_string();
-    return os;
-}
+    std::ostream& operator<<(std::ostream& os, const TypeDescriptor& type) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       std::ostream& operator<<(std::ostream& os, const TypeDescriptor& type) {
                                                                              ^
   ```
   



##########
be/src/vec/data_types/data_type_factory.cpp:
##########
@@ -169,17 +179,23 @@
         }
         nested = std::make_shared<DataTypeStruct>(dataTypes, names);
         break;
-    }
-    case INVALID_TYPE:
-    default:
-        DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    case TYPE_MAP:
+        DCHECK(col_desc.children.size() == 2);
+        nested = std::make_shared<vectorized::DataTypeMap>(
+                create_data_type(col_desc.children[0], 
col_desc.contains_nulls[0]),
+                create_data_type(col_desc.children[1], 
col_desc.contains_nulls[1]));
         break;
     }
+case INVALID_TYPE:
+default:

Review Comment:
   warning: 'default' statement not in switch statement [clang-diagnostic-error]
   ```cpp
   default:
   ^
   ```
   



##########
be/src/vec/data_types/data_type_factory.cpp:
##########
@@ -169,17 +179,23 @@
         }
         nested = std::make_shared<DataTypeStruct>(dataTypes, names);
         break;
-    }
-    case INVALID_TYPE:
-    default:
-        DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    case TYPE_MAP:
+        DCHECK(col_desc.children.size() == 2);
+        nested = std::make_shared<vectorized::DataTypeMap>(
+                create_data_type(col_desc.children[0], 
col_desc.contains_nulls[0]),
+                create_data_type(col_desc.children[1], 
col_desc.contains_nulls[1]));
         break;
     }
+case INVALID_TYPE:
+default:
+    DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    break;

Review Comment:
   warning: 'break' statement not in loop or switch statement 
[clang-diagnostic-error]
   ```cpp
       break;
       ^
   ```
   



##########
be/src/vec/data_types/data_type_factory.cpp:
##########
@@ -169,17 +179,23 @@
         }
         nested = std::make_shared<DataTypeStruct>(dataTypes, names);
         break;
-    }
-    case INVALID_TYPE:
-    default:
-        DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    case TYPE_MAP:
+        DCHECK(col_desc.children.size() == 2);
+        nested = std::make_shared<vectorized::DataTypeMap>(
+                create_data_type(col_desc.children[0], 
col_desc.contains_nulls[0]),
+                create_data_type(col_desc.children[1], 
col_desc.contains_nulls[1]));
         break;
     }
+case INVALID_TYPE:
+default:
+    DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    break;
+}
 
-    if (nested && is_nullable) {
-        return std::make_shared<vectorized::DataTypeNullable>(nested);
-    }
-    return nested;
+if (nested && is_nullable) {
+    return std::make_shared<vectorized::DataTypeNullable>(nested);
+}
+return nested;
 }
 
 DataTypePtr DataTypeFactory::_create_primitive_data_type(const FieldType& 
type, int precision,

Review Comment:
   warning: unknown type name 'DataTypePtr'; did you mean 
'doris::vectorized::DataTypePtr'? [clang-diagnostic-error]
   
   ```suggestion
   doris::vectorized::DataTypePtr 
DataTypeFactory::_create_primitive_data_type(const FieldType& type, int 
precision,
   ```
   **be/src/vec/aggregate_functions/aggregate_function.h:44:** 
'doris::vectorized::DataTypePtr' declared here
   ```cpp
   using DataTypePtr = std::shared_ptr<const IDataType>;
         ^
   ```
   



##########
be/src/vec/data_types/data_type_factory.cpp:
##########
@@ -169,17 +179,23 @@
         }
         nested = std::make_shared<DataTypeStruct>(dataTypes, names);
         break;
-    }
-    case INVALID_TYPE:
-    default:
-        DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    case TYPE_MAP:
+        DCHECK(col_desc.children.size() == 2);
+        nested = std::make_shared<vectorized::DataTypeMap>(
+                create_data_type(col_desc.children[0], 
col_desc.contains_nulls[0]),
+                create_data_type(col_desc.children[1], 
col_desc.contains_nulls[1]));
         break;
     }
+case INVALID_TYPE:
+default:
+    DCHECK(false) << "invalid PrimitiveType:" << (int)col_desc.type;
+    break;
+}
 
-    if (nested && is_nullable) {
-        return std::make_shared<vectorized::DataTypeNullable>(nested);
-    }
-    return nested;
+if (nested && is_nullable) {
+    return std::make_shared<vectorized::DataTypeNullable>(nested);
+}
+return nested;

Review Comment:
   warning: expected unqualified-id [clang-diagnostic-error]
   ```cpp
   return nested;
   ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
                             const RowDescriptor& row_desc) {
                                                            ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
                                       std::vector<VExprContext*>* ctxs) {
                                                                         ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
                                      VExprContext** ctx) {
                                                          ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
                                                                                
       ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->open(state));
         }
         return Status::OK();
     }
-    new_ctxs->resize(ctxs.size());
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
-    }
-    return Status::OK();
-}
-std::string VExpr::debug_string() const {
-    // TODO: implement partial debug string for member vars
-    std::stringstream out;
-    out << " type=" << _type.debug_string();
-    out << " codegen="
-        << "false";
 
-    if (!_children.empty()) {
-        out << " children=" << debug_string(_children);
+    Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                                      std::vector<VExprContext*>* new_ctxs) {
+        DCHECK(new_ctxs != nullptr);
+        if (!new_ctxs->empty()) {
+            // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
+            DCHECK_EQ(new_ctxs->size(), ctxs.size());
+            for (int i = 0; i < new_ctxs->size(); ++i) {
+                DCHECK((*new_ctxs)[i]->_is_clone);
+            }
+            return Status::OK();
+        }
+        new_ctxs->resize(ctxs.size());
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
+        }
+        return Status::OK();
     }
+    std::string VExpr::debug_string() const {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       std::string VExpr::debug_string() const {
                                               ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->open(state));
         }
         return Status::OK();
     }
-    new_ctxs->resize(ctxs.size());
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
-    }
-    return Status::OK();
-}
-std::string VExpr::debug_string() const {
-    // TODO: implement partial debug string for member vars
-    std::stringstream out;
-    out << " type=" << _type.debug_string();
-    out << " codegen="
-        << "false";
 
-    if (!_children.empty()) {
-        out << " children=" << debug_string(_children);
+    Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                                      std::vector<VExprContext*>* new_ctxs) {
+        DCHECK(new_ctxs != nullptr);
+        if (!new_ctxs->empty()) {
+            // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
+            DCHECK_EQ(new_ctxs->size(), ctxs.size());
+            for (int i = 0; i < new_ctxs->size(); ++i) {
+                DCHECK((*new_ctxs)[i]->_is_clone);
+            }
+            return Status::OK();
+        }
+        new_ctxs->resize(ctxs.size());
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
+        }
+        return Status::OK();
     }
+    std::string VExpr::debug_string() const {
+        // TODO: implement partial debug string for member vars
+        std::stringstream out;
+        out << " type=" << _type.debug_string();
+        out << " codegen="
+            << "false";
 
-    return out.str();
-}
-
-std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
-    std::stringstream out;
-    out << "[";
+        if (!_children.empty()) {
+            out << " children=" << debug_string(_children);
+        }
 
-    for (int i = 0; i < exprs.size(); ++i) {
-        out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        return out.str();
     }
 
-    out << "]";
-    return out.str();
-}
+    std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
                                                                         ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->open(state));
         }
         return Status::OK();
     }
-    new_ctxs->resize(ctxs.size());
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
-    }
-    return Status::OK();
-}
-std::string VExpr::debug_string() const {
-    // TODO: implement partial debug string for member vars
-    std::stringstream out;
-    out << " type=" << _type.debug_string();
-    out << " codegen="
-        << "false";
 
-    if (!_children.empty()) {
-        out << " children=" << debug_string(_children);
+    Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                                      std::vector<VExprContext*>* new_ctxs) {
+        DCHECK(new_ctxs != nullptr);
+        if (!new_ctxs->empty()) {
+            // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
+            DCHECK_EQ(new_ctxs->size(), ctxs.size());
+            for (int i = 0; i < new_ctxs->size(); ++i) {
+                DCHECK((*new_ctxs)[i]->_is_clone);
+            }
+            return Status::OK();
+        }
+        new_ctxs->resize(ctxs.size());
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
+        }
+        return Status::OK();
     }
+    std::string VExpr::debug_string() const {
+        // TODO: implement partial debug string for member vars
+        std::stringstream out;
+        out << " type=" << _type.debug_string();
+        out << " codegen="
+            << "false";
 
-    return out.str();
-}
-
-std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
-    std::stringstream out;
-    out << "[";
+        if (!_children.empty()) {
+            out << " children=" << debug_string(_children);
+        }
 
-    for (int i = 0; i < exprs.size(); ++i) {
-        out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        return out.str();
     }
 
-    out << "]";
-    return out.str();
-}
+    std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
+        std::stringstream out;
+        out << "[";
 
-std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
-    std::vector<VExpr*> exprs;
-    for (int i = 0; i < ctxs.size(); ++i) {
-        exprs.push_back(ctxs[i]->root());
+        for (int i = 0; i < exprs.size(); ++i) {
+            out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        }
+
+        out << "]";
+        return out.str();
     }
-    return debug_string(exprs);
-}
 
-bool VExpr::is_constant() const {
-    for (int i = 0; i < _children.size(); ++i) {
-        if (!_children[i]->is_constant()) {
-            return false;
+    std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
+        std::vector<VExpr*> exprs;
+        for (int i = 0; i < ctxs.size(); ++i) {
+            exprs.push_back(ctxs[i]->root());
         }
+        return debug_string(exprs);
     }
 
-    return true;
-}
+    bool VExpr::is_constant() const {
+        for (int i = 0; i < _children.size(); ++i) {
+            if (!_children[i]->is_constant()) {
+                return false;
+            }
+        }
 
-Status VExpr::get_const_col(VExprContext* context, ColumnPtrWrapper** output) {
-    *output = nullptr;
-    if (!is_constant()) {
-        return Status::OK();
+        return true;
     }
 
-    if (_constant_col != nullptr) {
+    Status VExpr::get_const_col(VExprContext * context, ColumnPtrWrapper * 
*output) {
+        *output = nullptr;
+        if (!is_constant()) {
+            return Status::OK();
+        }
+
+        if (_constant_col != nullptr) {
+            *output = _constant_col.get();
+            return Status::OK();
+        }
+
+        int result = -1;
+        Block block;
+        // If block is empty, some functions will produce no result. So we 
insert a column with
+        // single value here.
+        block.insert({ColumnUInt8::create(1), 
std::make_shared<DataTypeUInt8>(), ""});
+        RETURN_IF_ERROR(execute(context, &block, &result));
+        DCHECK(result != -1);
+        const auto& column = block.get_by_position(result).column;
+        _constant_col = std::make_shared<ColumnPtrWrapper>(column);
         *output = _constant_col.get();
         return Status::OK();
     }
 
-    int result = -1;
-    Block block;
-    // If block is empty, some functions will produce no result. So we insert 
a column with
-    // single value here.
-    block.insert({ColumnUInt8::create(1), std::make_shared<DataTypeUInt8>(), 
""});
-    RETURN_IF_ERROR(execute(context, &block, &result));
-    DCHECK(result != -1);
-    const auto& column = block.get_by_position(result).column;
-    _constant_col = std::make_shared<ColumnPtrWrapper>(column);
-    *output = _constant_col.get();
-    return Status::OK();
-}
+    void VExpr::register_function_context(doris::RuntimeState * state, 
VExprContext * context) {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       void VExpr::register_function_context(doris::RuntimeState * state, 
VExprContext * context) {
                                                                                
                  ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->open(state));
         }
         return Status::OK();
     }
-    new_ctxs->resize(ctxs.size());
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
-    }
-    return Status::OK();
-}
-std::string VExpr::debug_string() const {
-    // TODO: implement partial debug string for member vars
-    std::stringstream out;
-    out << " type=" << _type.debug_string();
-    out << " codegen="
-        << "false";
 
-    if (!_children.empty()) {
-        out << " children=" << debug_string(_children);
+    Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                                      std::vector<VExprContext*>* new_ctxs) {
+        DCHECK(new_ctxs != nullptr);
+        if (!new_ctxs->empty()) {
+            // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
+            DCHECK_EQ(new_ctxs->size(), ctxs.size());
+            for (int i = 0; i < new_ctxs->size(); ++i) {
+                DCHECK((*new_ctxs)[i]->_is_clone);
+            }
+            return Status::OK();
+        }
+        new_ctxs->resize(ctxs.size());
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
+        }
+        return Status::OK();
     }
+    std::string VExpr::debug_string() const {
+        // TODO: implement partial debug string for member vars
+        std::stringstream out;
+        out << " type=" << _type.debug_string();
+        out << " codegen="
+            << "false";
 
-    return out.str();
-}
-
-std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
-    std::stringstream out;
-    out << "[";
+        if (!_children.empty()) {
+            out << " children=" << debug_string(_children);
+        }
 
-    for (int i = 0; i < exprs.size(); ++i) {
-        out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        return out.str();
     }
 
-    out << "]";
-    return out.str();
-}
+    std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
+        std::stringstream out;
+        out << "[";
 
-std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
-    std::vector<VExpr*> exprs;
-    for (int i = 0; i < ctxs.size(); ++i) {
-        exprs.push_back(ctxs[i]->root());
+        for (int i = 0; i < exprs.size(); ++i) {
+            out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        }
+
+        out << "]";
+        return out.str();
     }
-    return debug_string(exprs);
-}
 
-bool VExpr::is_constant() const {
-    for (int i = 0; i < _children.size(); ++i) {
-        if (!_children[i]->is_constant()) {
-            return false;
+    std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
+        std::vector<VExpr*> exprs;
+        for (int i = 0; i < ctxs.size(); ++i) {
+            exprs.push_back(ctxs[i]->root());
         }
+        return debug_string(exprs);
     }
 
-    return true;
-}
+    bool VExpr::is_constant() const {

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
       bool VExpr::is_constant() const {
                                       ^
   ```
   



##########
be/src/vec/exprs/vexpr.cpp:
##########
@@ -171,218 +174,220 @@
     default:
         return Status::InternalError("Unknown expr node type: {}", 
texpr_node.node_type);
     }
-    return Status::OK();
-}
+        return Status::OK();
+    }
 
-Status VExpr::create_tree_from_thrift(doris::ObjectPool* pool,
-                                      const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
-                                      int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
-    // propagate error case
-    if (*node_idx >= nodes.size()) {
-        return Status::InternalError("Failed to reconstruct expression tree 
from thrift.");
-    }
-    int num_children = nodes[*node_idx].num_children;
-    VExpr* expr = nullptr;
-    RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
-    DCHECK(expr != nullptr);
-    if (parent != nullptr) {
-        parent->add_child(expr);
-    } else {
-        DCHECK(root_expr != nullptr);
-        DCHECK(ctx != nullptr);
-        *root_expr = expr;
-        *ctx = pool->add(new VExprContext(expr));
-    }
-    for (int i = 0; i < num_children; i++) {
-        *node_idx += 1;
-        RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, node_idx, 
nullptr, nullptr));
-        // we are expecting a child, but have used all nodes
-        // this means we have been given a bad tree and must fail
+    Status VExpr::create_tree_from_thrift(doris::ObjectPool * pool,
+                                          const std::vector<doris::TExprNode>& 
nodes, VExpr* parent,
+                                          int* node_idx, VExpr** root_expr, 
VExprContext** ctx) {
+        // propagate error case
         if (*node_idx >= nodes.size()) {
             return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
         }
-    }
-    return Status::OK();
-}
-
-Status VExpr::create_expr_tree(doris::ObjectPool* pool, const doris::TExpr& 
texpr,
-                               VExprContext** ctx) {
-    if (texpr.nodes.size() == 0) {
-        *ctx = nullptr;
+        int num_children = nodes[*node_idx].num_children;
+        VExpr* expr = nullptr;
+        RETURN_IF_ERROR(create_expr(pool, nodes[*node_idx], &expr));
+        DCHECK(expr != nullptr);
+        if (parent != nullptr) {
+            parent->add_child(expr);
+        } else {
+            DCHECK(root_expr != nullptr);
+            DCHECK(ctx != nullptr);
+            *root_expr = expr;
+            *ctx = pool->add(new VExprContext(expr));
+        }
+        for (int i = 0; i < num_children; i++) {
+            *node_idx += 1;
+            RETURN_IF_ERROR(create_tree_from_thrift(pool, nodes, expr, 
node_idx, nullptr, nullptr));
+            // we are expecting a child, but have used all nodes
+            // this means we have been given a bad tree and must fail
+            if (*node_idx >= nodes.size()) {
+                return Status::InternalError("Failed to reconstruct expression 
tree from thrift.");
+            }
+        }
         return Status::OK();
     }
-    int node_idx = 0;
-    VExpr* e = nullptr;
-    Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
-    if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
-        status = Status::InternalError(
-                "Expression tree only partially reconstructed. Not all thrift 
nodes were used.");
-    }
-    if (!status.ok()) {
-        LOG(ERROR) << "Could not construct expr tree.\n"
-                   << status << "\n"
-                   << apache::thrift::ThriftDebugString(texpr);
-    }
-    return status;
-}
 
-Status VExpr::create_expr_trees(ObjectPool* pool, const 
std::vector<doris::TExpr>& texprs,
-                                std::vector<VExprContext*>* ctxs) {
-    ctxs->clear();
-    for (int i = 0; i < texprs.size(); ++i) {
-        VExprContext* ctx = nullptr;
-        RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
-        ctxs->push_back(ctx);
+    Status VExpr::create_expr_tree(doris::ObjectPool * pool, const 
doris::TExpr& texpr,
+                                   VExprContext** ctx) {
+        if (texpr.nodes.size() == 0) {
+            *ctx = nullptr;
+            return Status::OK();
+        }
+        int node_idx = 0;
+        VExpr* e = nullptr;
+        Status status = create_tree_from_thrift(pool, texpr.nodes, nullptr, 
&node_idx, &e, ctx);
+        if (status.ok() && node_idx + 1 != texpr.nodes.size()) {
+            status = Status::InternalError(
+                    "Expression tree only partially reconstructed. Not all 
thrift nodes were "
+                    "used.");
+        }
+        if (!status.ok()) {
+            LOG(ERROR) << "Could not construct expr tree.\n"
+                       << status << "\n"
+                       << apache::thrift::ThriftDebugString(texpr);
+        }
+        return status;
     }
-    return Status::OK();
-}
 
-Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state,
-                      const RowDescriptor& row_desc) {
-    for (auto ctx : ctxs) {
-        RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+    Status VExpr::create_expr_trees(ObjectPool * pool, const 
std::vector<doris::TExpr>& texprs,
+                                    std::vector<VExprContext*>* ctxs) {
+        ctxs->clear();
+        for (int i = 0; i < texprs.size(); ++i) {
+            VExprContext* ctx = nullptr;
+            RETURN_IF_ERROR(create_expr_tree(pool, texprs[i], &ctx));
+            ctxs->push_back(ctx);
+        }
+        return Status::OK();
     }
-    return Status::OK();
-}
 
-void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* state) 
{
-    for (auto ctx : ctxs) {
-        ctx->close(state);
+    Status VExpr::prepare(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                          const RowDescriptor& row_desc) {
+        for (auto ctx : ctxs) {
+            RETURN_IF_ERROR(ctx->prepare(state, row_desc));
+        }
+        return Status::OK();
     }
-}
 
-Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->open(state));
+    void VExpr::close(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (auto ctx : ctxs) {
+            ctx->close(state);
+        }
     }
-    return Status::OK();
-}
 
-Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
-                                  std::vector<VExprContext*>* new_ctxs) {
-    DCHECK(new_ctxs != nullptr);
-    if (!new_ctxs->empty()) {
-        // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
-        DCHECK_EQ(new_ctxs->size(), ctxs.size());
-        for (int i = 0; i < new_ctxs->size(); ++i) {
-            DCHECK((*new_ctxs)[i]->_is_clone);
+    Status VExpr::open(const std::vector<VExprContext*>& ctxs, RuntimeState* 
state) {
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->open(state));
         }
         return Status::OK();
     }
-    new_ctxs->resize(ctxs.size());
-    for (int i = 0; i < ctxs.size(); ++i) {
-        RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
-    }
-    return Status::OK();
-}
-std::string VExpr::debug_string() const {
-    // TODO: implement partial debug string for member vars
-    std::stringstream out;
-    out << " type=" << _type.debug_string();
-    out << " codegen="
-        << "false";
 
-    if (!_children.empty()) {
-        out << " children=" << debug_string(_children);
+    Status VExpr::clone_if_not_exists(const std::vector<VExprContext*>& ctxs, 
RuntimeState* state,
+                                      std::vector<VExprContext*>* new_ctxs) {
+        DCHECK(new_ctxs != nullptr);
+        if (!new_ctxs->empty()) {
+            // 'ctxs' was already cloned into '*new_ctxs', nothing to do.
+            DCHECK_EQ(new_ctxs->size(), ctxs.size());
+            for (int i = 0; i < new_ctxs->size(); ++i) {
+                DCHECK((*new_ctxs)[i]->_is_clone);
+            }
+            return Status::OK();
+        }
+        new_ctxs->resize(ctxs.size());
+        for (int i = 0; i < ctxs.size(); ++i) {
+            RETURN_IF_ERROR(ctxs[i]->clone(state, &(*new_ctxs)[i]));
+        }
+        return Status::OK();
     }
+    std::string VExpr::debug_string() const {
+        // TODO: implement partial debug string for member vars
+        std::stringstream out;
+        out << " type=" << _type.debug_string();
+        out << " codegen="
+            << "false";
 
-    return out.str();
-}
-
-std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
-    std::stringstream out;
-    out << "[";
+        if (!_children.empty()) {
+            out << " children=" << debug_string(_children);
+        }
 
-    for (int i = 0; i < exprs.size(); ++i) {
-        out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        return out.str();
     }
 
-    out << "]";
-    return out.str();
-}
+    std::string VExpr::debug_string(const std::vector<VExpr*>& exprs) {
+        std::stringstream out;
+        out << "[";
 
-std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
-    std::vector<VExpr*> exprs;
-    for (int i = 0; i < ctxs.size(); ++i) {
-        exprs.push_back(ctxs[i]->root());
+        for (int i = 0; i < exprs.size(); ++i) {
+            out << (i == 0 ? "" : " ") << exprs[i]->debug_string();
+        }
+
+        out << "]";
+        return out.str();
     }
-    return debug_string(exprs);
-}
 
-bool VExpr::is_constant() const {
-    for (int i = 0; i < _children.size(); ++i) {
-        if (!_children[i]->is_constant()) {
-            return false;
+    std::string VExpr::debug_string(const std::vector<VExprContext*>& ctxs) {
+        std::vector<VExpr*> exprs;
+        for (int i = 0; i < ctxs.size(); ++i) {
+            exprs.push_back(ctxs[i]->root());
         }
+        return debug_string(exprs);
     }
 
-    return true;
-}
+    bool VExpr::is_constant() const {
+        for (int i = 0; i < _children.size(); ++i) {
+            if (!_children[i]->is_constant()) {
+                return false;
+            }
+        }
 
-Status VExpr::get_const_col(VExprContext* context, ColumnPtrWrapper** output) {
-    *output = nullptr;
-    if (!is_constant()) {
-        return Status::OK();
+        return true;
     }
 
-    if (_constant_col != nullptr) {
+    Status VExpr::get_const_col(VExprContext * context, ColumnPtrWrapper * 
*output) {
+        *output = nullptr;
+        if (!is_constant()) {
+            return Status::OK();
+        }
+
+        if (_constant_col != nullptr) {
+            *output = _constant_col.get();
+            return Status::OK();
+        }
+
+        int result = -1;
+        Block block;
+        // If block is empty, some functions will produce no result. So we 
insert a column with
+        // single value here.
+        block.insert({ColumnUInt8::create(1), 
std::make_shared<DataTypeUInt8>(), ""});
+        RETURN_IF_ERROR(execute(context, &block, &result));
+        DCHECK(result != -1);
+        const auto& column = block.get_by_position(result).column;
+        _constant_col = std::make_shared<ColumnPtrWrapper>(column);
         *output = _constant_col.get();
         return Status::OK();
     }
 
-    int result = -1;
-    Block block;
-    // If block is empty, some functions will produce no result. So we insert 
a column with
-    // single value here.
-    block.insert({ColumnUInt8::create(1), std::make_shared<DataTypeUInt8>(), 
""});
-    RETURN_IF_ERROR(execute(context, &block, &result));
-    DCHECK(result != -1);
-    const auto& column = block.get_by_position(result).column;
-    _constant_col = std::make_shared<ColumnPtrWrapper>(column);
-    *output = _constant_col.get();
-    return Status::OK();
-}
+    void VExpr::register_function_context(doris::RuntimeState * state, 
VExprContext * context) {
+        FunctionContext::TypeDesc return_type = 
AnyValUtil::column_type_to_type_desc(_type);
+        std::vector<FunctionContext::TypeDesc> arg_types;
+        for (int i = 0; i < _children.size(); ++i) {
+            
arg_types.push_back(AnyValUtil::column_type_to_type_desc(_children[i]->type()));
+        }
 
-void VExpr::register_function_context(doris::RuntimeState* state, 
VExprContext* context) {
-    FunctionContext::TypeDesc return_type = 
AnyValUtil::column_type_to_type_desc(_type);
-    std::vector<FunctionContext::TypeDesc> arg_types;
-    for (int i = 0; i < _children.size(); ++i) {
-        
arg_types.push_back(AnyValUtil::column_type_to_type_desc(_children[i]->type()));
+        _fn_context_index = context->register_func(state, return_type, 
arg_types, 0);
     }
 
-    _fn_context_index = context->register_func(state, return_type, arg_types, 
0);
-}
-
-Status VExpr::init_function_context(VExprContext* context,
-                                    FunctionContext::FunctionStateScope scope,
-                                    const FunctionBasePtr& function) const {
-    FunctionContext* fn_ctx = context->fn_context(_fn_context_index);
-    if (scope == FunctionContext::FRAGMENT_LOCAL) {
-        std::vector<ColumnPtrWrapper*> constant_cols;
-        for (auto c : _children) {
-            ColumnPtrWrapper* const_col_wrapper = nullptr;
-            RETURN_IF_ERROR(c->get_const_col(context, &const_col_wrapper));
-            constant_cols.push_back(const_col_wrapper);
+    Status VExpr::init_function_context(VExprContext * context,
+                                        FunctionContext::FunctionStateScope 
scope,
+                                        const FunctionBasePtr& function) const 
{

Review Comment:
   warning: function definition is not allowed here [clang-diagnostic-error]
   ```cpp
                                           const FunctionBasePtr& function) 
const {
                                                                                
  ^
   ```
   



-- 
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-unsubscr...@doris.apache.org

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


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


Reply via email to