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


##########
be/src/exec/base_scanner.cpp:
##########
@@ -251,6 +266,28 @@
                 std::move(column_ptr), slot_desc->get_data_type_ptr(), 
slot_desc->col_name()));
     }
 
+    // handle dynamic generated columns
+    if (!_full_base_schema_view->empty()) {
+        assert(_is_dynamic_schema);
+        for (size_t x = dest_block->columns(); x < _src_block.columns(); ++x) {
+            auto& column_type_name = _src_block.get_by_position(x);
+            const TColumn& tcolumn =
+                    
_full_base_schema_view->column_name_to_column[column_type_name.name];
+            auto original_type = 
vectorized::DataTypeFactory::instance().create_data_type(tcolumn);
+            // type conflict free path, always cast to original type
+            if (!column_type_name.type->equals(*original_type)) {
+                vectorized::ColumnPtr column_ptr;
+                
RETURN_IF_ERROR(vectorized::object_util::cast_column(column_type_name,
+                                                                     
original_type, &column_ptr));
+                column_type_name.column = column_ptr;
+                column_type_name.type = original_type;
+            }
+            
dest_block->insert(vectorized::ColumnWithTypeAndName(std::move(column_type_name.column),
+                                                                 
std::move(column_type_name.type),

Review Comment:
   warning: passing result of std::move() as a const reference argument; no 
move will actually happen [performance-move-const-arg]
   
   ```suggestion
                                                                    
column_type_name.type,
   ```
   



##########
be/src/exec/base_scanner.cpp:
##########
@@ -251,6 +266,28 @@ Status 
BaseScanner::_materialize_dest_block(vectorized::Block* dest_block) {
                 std::move(column_ptr), slot_desc->get_data_type_ptr(), 
slot_desc->col_name()));
     }
 
+    // handle dynamic generated columns
+    if (!_full_base_schema_view->empty()) {
+        assert(_is_dynamic_schema);
+        for (size_t x = dest_block->columns(); x < _src_block.columns(); ++x) {
+            auto& column_type_name = _src_block.get_by_position(x);
+            const TColumn& tcolumn =
+                    
_full_base_schema_view->column_name_to_column[column_type_name.name];
+            auto original_type = 
vectorized::DataTypeFactory::instance().create_data_type(tcolumn);
+            // type conflict free path, always cast to original type
+            if (!column_type_name.type->equals(*original_type)) {
+                vectorized::ColumnPtr column_ptr;
+                
RETURN_IF_ERROR(vectorized::object_util::cast_column(column_type_name,
+                                                                     
original_type, &column_ptr));
+                column_type_name.column = column_ptr;
+                column_type_name.type = original_type;
+            }
+            
dest_block->insert(vectorized::ColumnWithTypeAndName(std::move(column_type_name.column),

Review Comment:
   warning: passing result of std::move() as a const reference argument; no 
move will actually happen [performance-move-const-arg]
   
   ```suggestion
               
dest_block->insert(vectorized::ColumnWithTypeAndName(column_type_name.column,
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);

Review Comment:
   warning: unknown type name 'StringValue'; did you mean 'StringVal'? 
[clang-diagnostic-error]
   
   ```suggestion
           string_val = reinterpret_cast<const StringVal*>(value);
   ```
   **be/src/udf/udf.h:393:** 'StringVal' declared here
   ```cpp
   struct StringVal : public AnyVal {
          ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,

Review Comment:
   warning: out-of-line definition of 'print_value_as_bytes' does not match any 
declaration in 'doris::RawValue' [clang-diagnostic-error]
   ```cpp
   void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
                  ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);

Review Comment:
   warning: static_cast from 'uint8_t *' (aka 'unsigned char *') to 'char *' is 
not allowed [clang-diagnostic-error]
   ```cpp
           tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
                      ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {

Review Comment:
   warning: use of undeclared identifier 'TYPE_DECIMAL128'; did you mean 
'TYPE_DECIMAL128I'? [clang-diagnostic-error]
   
   ```suggestion
       case TYPE_DECIMAL128I: {
   ```
   **be/src/runtime/define_primitive_type.h:54:** 'TYPE_DECIMAL128I' declared 
here
   ```cpp
       TYPE_DECIMAL128I,    /* 30 */
       ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);
+        *stream << "[";
+        print_value(iter.get(), children_type, scale, stream);
+        iter.next();
+        for (; iter.has_next(); iter.next()) {
+            *stream << ", ";
+            print_value(iter.get(), children_type, scale, stream);
+        }
+        *stream << "]";
+        break;
+    }
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+
+    stream->precision(old_precision);
+    // Undo setting stream to fixed
+    stream->flags(old_flags);
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::string* str) {
+    if (value == nullptr) {
+        *str = "NULL";
+        return;
+    }
+
+    std::stringstream out;
+    out.precision(ASCII_PRECISION);
+    const StringValue* string_val = nullptr;
+    std::string tmp;
+    bool val = false;
+
+    // Special case types that we can print more efficiently without using a 
std::stringstream
+    switch (type.type) {
+    case TYPE_BOOLEAN:
+        val = *reinterpret_cast<const bool*>(value);
+        *str = (val ? "true" : "false");
+        return;
+
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_OBJECT:
+    case TYPE_HLL:
+    case TYPE_QUANTILE_STATE:
+    case TYPE_STRING: {
+        string_val = reinterpret_cast<const StringValue*>(value);
+        std::stringstream ss;
+        ss << "ptr:" << (void*)string_val->ptr << " len:" << string_val->len;
+        tmp = ss.str();
+        if (string_val->len <= 1000) {
+            tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);

Review Comment:
   warning: static_cast from 'uint8_t *' (aka 'unsigned char *') to 'char *' is 
not allowed [clang-diagnostic-error]
   ```cpp
               tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
                          ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);
+        *stream << "[";
+        print_value(iter.get(), children_type, scale, stream);
+        iter.next();
+        for (; iter.has_next(); iter.next()) {
+            *stream << ", ";
+            print_value(iter.get(), children_type, scale, stream);
+        }
+        *stream << "]";
+        break;
+    }
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+
+    stream->precision(old_precision);
+    // Undo setting stream to fixed
+    stream->flags(old_flags);
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::string* str) {
+    if (value == nullptr) {
+        *str = "NULL";
+        return;
+    }
+
+    std::stringstream out;
+    out.precision(ASCII_PRECISION);
+    const StringValue* string_val = nullptr;
+    std::string tmp;
+    bool val = false;
+
+    // Special case types that we can print more efficiently without using a 
std::stringstream
+    switch (type.type) {
+    case TYPE_BOOLEAN:
+        val = *reinterpret_cast<const bool*>(value);
+        *str = (val ? "true" : "false");
+        return;
+
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_OBJECT:
+    case TYPE_HLL:
+    case TYPE_QUANTILE_STATE:
+    case TYPE_STRING: {
+        string_val = reinterpret_cast<const StringValue*>(value);
+        std::stringstream ss;
+        ss << "ptr:" << (void*)string_val->ptr << " len:" << string_val->len;
+        tmp = ss.str();
+        if (string_val->len <= 1000) {
+            tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        }
+        str->swap(tmp);
+        return;
+    }
+    case TYPE_NULL: {
+        *str = "NULL";
+        return;
+    }
+    default:
+        print_value(value, type, scale, &out);
+    }
+
+    *str = out.str();
+}
+
+void RawValue::write(const void* value, void* dst, const TypeDescriptor& type, 
MemPool* pool) {
+    DCHECK(value != nullptr);
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN: {
+        *reinterpret_cast<bool*>(dst) = *reinterpret_cast<const bool*>(value);
+        break;
+    }
+
+    case TYPE_TINYINT: {
+        *reinterpret_cast<int8_t*>(dst) = *reinterpret_cast<const 
int8_t*>(value);
+        break;
+    }
+
+    case TYPE_SMALLINT: {
+        *reinterpret_cast<int16_t*>(dst) = *reinterpret_cast<const 
int16_t*>(value);
+        break;
+    }
+
+    case TYPE_INT: {
+        *reinterpret_cast<int32_t*>(dst) = *reinterpret_cast<const 
int32_t*>(value);
+        break;
+    }
+
+    case TYPE_BIGINT: {
+        *reinterpret_cast<int64_t*>(dst) = *reinterpret_cast<const 
int64_t*>(value);
+        break;
+    }
+
+    case TYPE_LARGEINT: {
+        *reinterpret_cast<PackedInt128*>(dst) = *reinterpret_cast<const 
PackedInt128*>(value);
+        break;
+    }
+
+    case TYPE_FLOAT: {
+        *reinterpret_cast<float*>(dst) = *reinterpret_cast<const 
float*>(value);
+        break;
+    }
+
+    case TYPE_TIME:
+    case TYPE_DOUBLE: {
+        *reinterpret_cast<double*>(dst) = *reinterpret_cast<const 
double*>(value);
+        break;
+    }
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *reinterpret_cast<DateTimeValue*>(dst) = *reinterpret_cast<const 
DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        
*reinterpret_cast<doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(
+                dst) =
+                *reinterpret_cast<
+                        const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(
+                        value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        
*reinterpret_cast<doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                dst) =
+                *reinterpret_cast<const doris::vectorized::DateV2Value<
+                        doris::vectorized::DateTimeV2ValueType>*>(value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *reinterpret_cast<PackedInt128*>(dst) = *reinterpret_cast<const 
PackedInt128*>(value);
+        break;
+
+    case TYPE_DECIMAL32:
+        *reinterpret_cast<doris::vectorized::Decimal32*>(dst) =
+                *reinterpret_cast<const doris::vectorized::Decimal32*>(value);
+        break;
+    case TYPE_DECIMAL64:
+        *reinterpret_cast<doris::vectorized::Decimal64*>(dst) =
+                *reinterpret_cast<const doris::vectorized::Decimal64*>(value);
+        break;
+    case TYPE_DECIMAL128:
+        *reinterpret_cast<doris::vectorized::Decimal128*>(dst) =
+                *reinterpret_cast<const doris::vectorized::Decimal128*>(value);
+        break;
+
+    case TYPE_OBJECT:
+    case TYPE_HLL:
+    case TYPE_QUANTILE_STATE:
+    case TYPE_VARCHAR:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING: {
+        const StringValue* src = reinterpret_cast<const StringValue*>(value);

Review Comment:
   warning: unknown type name 'StringValue'; did you mean 'StringVal'? 
[clang-diagnostic-error]
   
   ```suggestion
           const StringVal* src = reinterpret_cast<const StringValue*>(value);
   ```
   **be/src/udf/udf.h:393:** 'StringVal' declared here
   ```cpp
   struct StringVal : public AnyVal {
          ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);
+        *stream << "[";
+        print_value(iter.get(), children_type, scale, stream);
+        iter.next();
+        for (; iter.has_next(); iter.next()) {
+            *stream << ", ";
+            print_value(iter.get(), children_type, scale, stream);
+        }
+        *stream << "]";
+        break;
+    }
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+
+    stream->precision(old_precision);
+    // Undo setting stream to fixed
+    stream->flags(old_flags);
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::string* str) {
+    if (value == nullptr) {
+        *str = "NULL";
+        return;
+    }
+
+    std::stringstream out;
+    out.precision(ASCII_PRECISION);
+    const StringValue* string_val = nullptr;
+    std::string tmp;
+    bool val = false;
+
+    // Special case types that we can print more efficiently without using a 
std::stringstream
+    switch (type.type) {
+    case TYPE_BOOLEAN:
+        val = *reinterpret_cast<const bool*>(value);
+        *str = (val ? "true" : "false");
+        return;
+
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_OBJECT:
+    case TYPE_HLL:
+    case TYPE_QUANTILE_STATE:
+    case TYPE_STRING: {
+        string_val = reinterpret_cast<const StringValue*>(value);
+        std::stringstream ss;
+        ss << "ptr:" << (void*)string_val->ptr << " len:" << string_val->len;
+        tmp = ss.str();
+        if (string_val->len <= 1000) {
+            tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        }
+        str->swap(tmp);
+        return;
+    }
+    case TYPE_NULL: {
+        *str = "NULL";
+        return;
+    }
+    default:
+        print_value(value, type, scale, &out);
+    }
+
+    *str = out.str();
+}
+
+void RawValue::write(const void* value, void* dst, const TypeDescriptor& type, 
MemPool* pool) {
+    DCHECK(value != nullptr);
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN: {
+        *reinterpret_cast<bool*>(dst) = *reinterpret_cast<const bool*>(value);
+        break;
+    }
+
+    case TYPE_TINYINT: {
+        *reinterpret_cast<int8_t*>(dst) = *reinterpret_cast<const 
int8_t*>(value);
+        break;
+    }
+
+    case TYPE_SMALLINT: {
+        *reinterpret_cast<int16_t*>(dst) = *reinterpret_cast<const 
int16_t*>(value);
+        break;
+    }
+
+    case TYPE_INT: {
+        *reinterpret_cast<int32_t*>(dst) = *reinterpret_cast<const 
int32_t*>(value);
+        break;
+    }
+
+    case TYPE_BIGINT: {
+        *reinterpret_cast<int64_t*>(dst) = *reinterpret_cast<const 
int64_t*>(value);
+        break;
+    }
+
+    case TYPE_LARGEINT: {
+        *reinterpret_cast<PackedInt128*>(dst) = *reinterpret_cast<const 
PackedInt128*>(value);
+        break;
+    }
+
+    case TYPE_FLOAT: {
+        *reinterpret_cast<float*>(dst) = *reinterpret_cast<const 
float*>(value);
+        break;
+    }
+
+    case TYPE_TIME:
+    case TYPE_DOUBLE: {
+        *reinterpret_cast<double*>(dst) = *reinterpret_cast<const 
double*>(value);
+        break;
+    }
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *reinterpret_cast<DateTimeValue*>(dst) = *reinterpret_cast<const 
DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        
*reinterpret_cast<doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(
+                dst) =
+                *reinterpret_cast<
+                        const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(
+                        value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        
*reinterpret_cast<doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                dst) =
+                *reinterpret_cast<const doris::vectorized::DateV2Value<
+                        doris::vectorized::DateTimeV2ValueType>*>(value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *reinterpret_cast<PackedInt128*>(dst) = *reinterpret_cast<const 
PackedInt128*>(value);
+        break;
+
+    case TYPE_DECIMAL32:
+        *reinterpret_cast<doris::vectorized::Decimal32*>(dst) =
+                *reinterpret_cast<const doris::vectorized::Decimal32*>(value);
+        break;
+    case TYPE_DECIMAL64:
+        *reinterpret_cast<doris::vectorized::Decimal64*>(dst) =
+                *reinterpret_cast<const doris::vectorized::Decimal64*>(value);
+        break;
+    case TYPE_DECIMAL128:

Review Comment:
   warning: use of undeclared identifier 'TYPE_DECIMAL128'; did you mean 
'TYPE_DECIMAL128I'? [clang-diagnostic-error]
   
   ```suggestion
       case TYPE_DECIMAL128I:
   ```
   **be/src/runtime/define_primitive_type.h:54:** 'TYPE_DECIMAL128I' declared 
here
   ```cpp
       TYPE_DECIMAL128I,    /* 30 */
       ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;

Review Comment:
   warning: unknown type name 'StringValue'; did you mean 'StringVal'? 
[clang-diagnostic-error]
   
   ```suggestion
       const StringVal* string_val = nullptr;
   ```
   **be/src/udf/udf.h:393:** 'StringVal' declared here
   ```cpp
   struct StringVal : public AnyVal {
          ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);

Review Comment:
   warning: static_cast from 'uint8_t *' (aka 'unsigned char *') to 'char *' is 
not allowed [clang-diagnostic-error]
   ```cpp
           stream->write(static_cast<char*>(string_val->ptr), string_val->len);
                         ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:

Review Comment:
   warning: use of undeclared identifier 'TYPE_DECIMAL128'; did you mean 
'TYPE_DECIMAL128I'? [clang-diagnostic-error]
   
   ```suggestion
       case TYPE_DECIMAL128I:
   ```
   **be/src/runtime/define_primitive_type.h:54:** 'TYPE_DECIMAL128I' declared 
here
   ```cpp
       TYPE_DECIMAL128I,    /* 30 */
       ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);

Review Comment:
   warning: unknown type name 'StringValue'; did you mean 'StringVal'? 
[clang-diagnostic-error]
   
   ```suggestion
           string_val = reinterpret_cast<const StringVal*>(value);
   ```
   **be/src/udf/udf.h:393:** 'StringVal' declared here
   ```cpp
   struct StringVal : public AnyVal {
          ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,

Review Comment:
   warning: out-of-line definition of 'print_value' does not match any 
declaration in 'doris::RawValue' [clang-diagnostic-error]
   ```cpp
   void RawValue::print_value(const void* value, const TypeDescriptor& type, 
int scale,
                  ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;

Review Comment:
   warning: unknown type name 'StringValue'; did you mean 'StringVal'? 
[clang-diagnostic-error]
   
   ```suggestion
       const StringVal* string_val = nullptr;
   ```
   **be/src/udf/udf.h:393:** 'StringVal' declared here
   ```cpp
   struct StringVal : public AnyVal {
          ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);
+        *stream << "[";
+        print_value(iter.get(), children_type, scale, stream);
+        iter.next();
+        for (; iter.has_next(); iter.next()) {
+            *stream << ", ";
+            print_value(iter.get(), children_type, scale, stream);
+        }
+        *stream << "]";
+        break;
+    }
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+
+    stream->precision(old_precision);
+    // Undo setting stream to fixed
+    stream->flags(old_flags);
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::string* str) {
+    if (value == nullptr) {
+        *str = "NULL";
+        return;
+    }
+
+    std::stringstream out;
+    out.precision(ASCII_PRECISION);
+    const StringValue* string_val = nullptr;

Review Comment:
   warning: unknown type name 'StringValue'; did you mean 'StringVal'? 
[clang-diagnostic-error]
   
   ```suggestion
       const StringVal* string_val = nullptr;
   ```
   **be/src/udf/udf.h:393:** 'StringVal' declared here
   ```cpp
   struct StringVal : public AnyVal {
          ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);
+        *stream << "[";
+        print_value(iter.get(), children_type, scale, stream);
+        iter.next();
+        for (; iter.has_next(); iter.next()) {
+            *stream << ", ";
+            print_value(iter.get(), children_type, scale, stream);
+        }
+        *stream << "]";
+        break;
+    }
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+
+    stream->precision(old_precision);
+    // Undo setting stream to fixed
+    stream->flags(old_flags);
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,

Review Comment:
   warning: out-of-line definition of 'print_value' does not match any 
declaration in 'doris::RawValue' [clang-diagnostic-error]
   ```cpp
   void RawValue::print_value(const void* value, const TypeDescriptor& type, 
int scale,
                  ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);
+        *stream << "[";
+        print_value(iter.get(), children_type, scale, stream);
+        iter.next();
+        for (; iter.has_next(); iter.next()) {
+            *stream << ", ";
+            print_value(iter.get(), children_type, scale, stream);
+        }
+        *stream << "]";
+        break;
+    }
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+
+    stream->precision(old_precision);
+    // Undo setting stream to fixed
+    stream->flags(old_flags);
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::string* str) {
+    if (value == nullptr) {
+        *str = "NULL";
+        return;
+    }
+
+    std::stringstream out;
+    out.precision(ASCII_PRECISION);
+    const StringValue* string_val = nullptr;
+    std::string tmp;
+    bool val = false;
+
+    // Special case types that we can print more efficiently without using a 
std::stringstream
+    switch (type.type) {
+    case TYPE_BOOLEAN:
+        val = *reinterpret_cast<const bool*>(value);
+        *str = (val ? "true" : "false");
+        return;
+
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_OBJECT:
+    case TYPE_HLL:
+    case TYPE_QUANTILE_STATE:
+    case TYPE_STRING: {
+        string_val = reinterpret_cast<const StringValue*>(value);

Review Comment:
   warning: unknown type name 'StringValue'; did you mean 'StringVal'? 
[clang-diagnostic-error]
   
   ```suggestion
           string_val = reinterpret_cast<const StringVal*>(value);
   ```
   **be/src/udf/udf.h:393:** 'StringVal' declared here
   ```cpp
   struct StringVal : public AnyVal {
          ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);

Review Comment:
   warning: no member named 'iterator' in 'doris::CollectionValue' 
[clang-diagnostic-error]
   ```cpp
           auto iter = src->iterator(children_type.type);
                            ^
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);
+        *stream << "[";
+        print_value(iter.get(), children_type, scale, stream);
+        iter.next();
+        for (; iter.has_next(); iter.next()) {
+            *stream << ", ";
+            print_value(iter.get(), children_type, scale, stream);
+        }
+        *stream << "]";
+        break;
+    }
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+
+    stream->precision(old_precision);
+    // Undo setting stream to fixed
+    stream->flags(old_flags);
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::string* str) {
+    if (value == nullptr) {
+        *str = "NULL";
+        return;
+    }
+
+    std::stringstream out;
+    out.precision(ASCII_PRECISION);
+    const StringValue* string_val = nullptr;
+    std::string tmp;
+    bool val = false;
+
+    // Special case types that we can print more efficiently without using a 
std::stringstream
+    switch (type.type) {
+    case TYPE_BOOLEAN:
+        val = *reinterpret_cast<const bool*>(value);
+        *str = (val ? "true" : "false");
+        return;
+
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_OBJECT:
+    case TYPE_HLL:
+    case TYPE_QUANTILE_STATE:
+    case TYPE_STRING: {
+        string_val = reinterpret_cast<const StringValue*>(value);
+        std::stringstream ss;
+        ss << "ptr:" << (void*)string_val->ptr << " len:" << string_val->len;
+        tmp = ss.str();
+        if (string_val->len <= 1000) {
+            tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        }
+        str->swap(tmp);
+        return;
+    }
+    case TYPE_NULL: {
+        *str = "NULL";
+        return;
+    }
+    default:
+        print_value(value, type, scale, &out);
+    }
+
+    *str = out.str();
+}
+
+void RawValue::write(const void* value, void* dst, const TypeDescriptor& type, 
MemPool* pool) {

Review Comment:
   warning: out-of-line definition of 'write' does not match any declaration in 
'doris::RawValue' [clang-diagnostic-error]
   ```cpp
   void RawValue::write(const void* value, void* dst, const TypeDescriptor& 
type, MemPool* pool) {
                  ^
   ```
   



##########
be/src/vec/columns/column.h:
##########
@@ -448,6 +449,26 @@ class IColumn : public COW<IColumn> {
         LOG(FATAL) << "not support";
     };
 
+    /// Appends one field multiple times. Can be optimized in inherited 
classes.
+    virtual void insert_many(const Field& field, size_t length) {
+        for (size_t i = 0; i < length; ++i) insert(field);

Review Comment:
   warning: statement should be inside braces 
[readability-braces-around-statements]
   
   ```suggestion
           for (size_t i = 0; i < length; ++i) { insert(field);
   }
   ```
   



##########
be/src/runtime/raw_value.cpp:
##########
@@ -0,0 +1,651 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+// This file is copied from
+// 
https://github.com/apache/impala/blob/branch-2.9.0/be/src/runtime/raw-value.cpp
+// and modified by Doris
+
+#include "runtime/raw_value.h"
+
+#include <sstream>
+
+#include "common/consts.h"
+#include "runtime/collection_value.h"
+#include "runtime/large_int_value.h"
+#include "runtime/tuple.h"
+#include "util/types.h"
+#include "vec/io/io_helper.h"
+
+namespace doris {
+
+const int RawValue::ASCII_PRECISION = 16; // print 16 digits for double/float
+
+void RawValue::print_value_as_bytes(const void* value, const TypeDescriptor& 
type,
+                                    std::stringstream* stream) {
+    if (value == nullptr) {
+        return;
+    }
+
+    const char* chars = reinterpret_cast<const char*>(value);
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN:
+        stream->write(chars, sizeof(bool));
+        return;
+
+    case TYPE_TINYINT:
+        stream->write(chars, sizeof(int8_t));
+        break;
+
+    case TYPE_SMALLINT:
+        stream->write(chars, sizeof(int16_t));
+        break;
+
+    case TYPE_INT:
+        stream->write(chars, sizeof(int32_t));
+        break;
+
+    case TYPE_BIGINT:
+        stream->write(chars, sizeof(int64_t));
+        break;
+
+    case TYPE_FLOAT:
+        stream->write(chars, sizeof(float));
+        break;
+
+    case TYPE_DOUBLE:
+        stream->write(chars, sizeof(double));
+        break;
+
+    case TYPE_VARCHAR:
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        stream->write(static_cast<char*>(string_val->ptr), string_val->len);
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        stream->write(chars, sizeof(DateTimeValue));
+        break;
+
+    case TYPE_DATEV2:
+        stream->write(chars,
+                      
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>));
+        break;
+
+    case TYPE_DATETIMEV2:
+        stream->write(
+                chars,
+                
sizeof(doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>));
+        break;
+
+    case TYPE_DECIMALV2:
+        stream->write(chars, sizeof(DecimalV2Value));
+        break;
+
+    case TYPE_DECIMAL32:
+        stream->write(chars, 4);
+        break;
+
+    case TYPE_DECIMAL64:
+        stream->write(chars, 8);
+        break;
+
+    case TYPE_DECIMAL128:
+        stream->write(chars, 16);
+        break;
+
+    case TYPE_LARGEINT:
+        stream->write(chars, sizeof(__int128));
+        break;
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::stringstream* stream) {
+    if (value == nullptr) {
+        *stream << "NULL";
+        return;
+    }
+
+    int old_precision = stream->precision();
+    std::ios_base::fmtflags old_flags = stream->flags();
+
+    if (scale > -1) {
+        stream->precision(scale);
+        // Setting 'fixed' causes precision to set the number of digits 
printed after the
+        // decimal (by default it sets the maximum number of digits total).
+        *stream << std::fixed;
+    }
+
+    std::string tmp;
+    const StringValue* string_val = nullptr;
+
+    switch (type.type) {
+    case TYPE_BOOLEAN: {
+        bool val = *reinterpret_cast<const bool*>(value);
+        *stream << (val ? "true" : "false");
+        return;
+    }
+
+    case TYPE_TINYINT:
+        // Extra casting for chars since they should not be interpreted as 
ASCII.
+        *stream << static_cast<int>(*reinterpret_cast<const int8_t*>(value));
+        break;
+
+    case TYPE_SMALLINT:
+        *stream << *reinterpret_cast<const int16_t*>(value);
+        break;
+
+    case TYPE_INT:
+        *stream << *reinterpret_cast<const int32_t*>(value);
+        break;
+
+    case TYPE_BIGINT:
+        *stream << *reinterpret_cast<const int64_t*>(value);
+        break;
+
+    case TYPE_FLOAT:
+        *stream << *reinterpret_cast<const float*>(value);
+        break;
+
+    case TYPE_DOUBLE:
+        *stream << *reinterpret_cast<const double*>(value);
+        break;
+    case TYPE_HLL:
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_STRING:
+    case TYPE_VARIANT:
+        string_val = reinterpret_cast<const StringValue*>(value);
+        tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        *stream << tmp;
+        return;
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *stream << *reinterpret_cast<const DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        *stream << *reinterpret_cast<
+                const 
doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *stream << DecimalV2Value(reinterpret_cast<const 
PackedInt128*>(value)->value).to_string();
+        break;
+
+    case TYPE_DECIMAL32: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal32*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL64: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal64*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_DECIMAL128: {
+        auto decimal_val = reinterpret_cast<const 
doris::vectorized::Decimal128*>(value);
+        write_text(*decimal_val, type.scale, *stream);
+        break;
+    }
+
+    case TYPE_LARGEINT:
+        *stream << reinterpret_cast<const PackedInt128*>(value)->value;
+        break;
+
+    case TYPE_ARRAY: {
+        const CollectionValue* src = reinterpret_cast<const 
CollectionValue*>(value);
+        auto children_type = type.children.at(0);
+        auto iter = src->iterator(children_type.type);
+        *stream << "[";
+        print_value(iter.get(), children_type, scale, stream);
+        iter.next();
+        for (; iter.has_next(); iter.next()) {
+            *stream << ", ";
+            print_value(iter.get(), children_type, scale, stream);
+        }
+        *stream << "]";
+        break;
+    }
+
+    default:
+        DCHECK(false) << "bad RawValue::print_value() type: " << type;
+    }
+
+    stream->precision(old_precision);
+    // Undo setting stream to fixed
+    stream->flags(old_flags);
+}
+
+void RawValue::print_value(const void* value, const TypeDescriptor& type, int 
scale,
+                           std::string* str) {
+    if (value == nullptr) {
+        *str = "NULL";
+        return;
+    }
+
+    std::stringstream out;
+    out.precision(ASCII_PRECISION);
+    const StringValue* string_val = nullptr;
+    std::string tmp;
+    bool val = false;
+
+    // Special case types that we can print more efficiently without using a 
std::stringstream
+    switch (type.type) {
+    case TYPE_BOOLEAN:
+        val = *reinterpret_cast<const bool*>(value);
+        *str = (val ? "true" : "false");
+        return;
+
+    case TYPE_CHAR:
+    case TYPE_VARCHAR:
+    case TYPE_OBJECT:
+    case TYPE_HLL:
+    case TYPE_QUANTILE_STATE:
+    case TYPE_STRING: {
+        string_val = reinterpret_cast<const StringValue*>(value);
+        std::stringstream ss;
+        ss << "ptr:" << (void*)string_val->ptr << " len:" << string_val->len;
+        tmp = ss.str();
+        if (string_val->len <= 1000) {
+            tmp.assign(static_cast<char*>(string_val->ptr), string_val->len);
+        }
+        str->swap(tmp);
+        return;
+    }
+    case TYPE_NULL: {
+        *str = "NULL";
+        return;
+    }
+    default:
+        print_value(value, type, scale, &out);
+    }
+
+    *str = out.str();
+}
+
+void RawValue::write(const void* value, void* dst, const TypeDescriptor& type, 
MemPool* pool) {
+    DCHECK(value != nullptr);
+
+    switch (type.type) {
+    case TYPE_NULL:
+        break;
+    case TYPE_BOOLEAN: {
+        *reinterpret_cast<bool*>(dst) = *reinterpret_cast<const bool*>(value);
+        break;
+    }
+
+    case TYPE_TINYINT: {
+        *reinterpret_cast<int8_t*>(dst) = *reinterpret_cast<const 
int8_t*>(value);
+        break;
+    }
+
+    case TYPE_SMALLINT: {
+        *reinterpret_cast<int16_t*>(dst) = *reinterpret_cast<const 
int16_t*>(value);
+        break;
+    }
+
+    case TYPE_INT: {
+        *reinterpret_cast<int32_t*>(dst) = *reinterpret_cast<const 
int32_t*>(value);
+        break;
+    }
+
+    case TYPE_BIGINT: {
+        *reinterpret_cast<int64_t*>(dst) = *reinterpret_cast<const 
int64_t*>(value);
+        break;
+    }
+
+    case TYPE_LARGEINT: {
+        *reinterpret_cast<PackedInt128*>(dst) = *reinterpret_cast<const 
PackedInt128*>(value);
+        break;
+    }
+
+    case TYPE_FLOAT: {
+        *reinterpret_cast<float*>(dst) = *reinterpret_cast<const 
float*>(value);
+        break;
+    }
+
+    case TYPE_TIME:
+    case TYPE_DOUBLE: {
+        *reinterpret_cast<double*>(dst) = *reinterpret_cast<const 
double*>(value);
+        break;
+    }
+
+    case TYPE_DATE:
+    case TYPE_DATETIME:
+        *reinterpret_cast<DateTimeValue*>(dst) = *reinterpret_cast<const 
DateTimeValue*>(value);
+        break;
+
+    case TYPE_DATEV2:
+        
*reinterpret_cast<doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(
+                dst) =
+                *reinterpret_cast<
+                        const 
doris::vectorized::DateV2Value<doris::vectorized::DateV2ValueType>*>(
+                        value);
+        break;
+
+    case TYPE_DATETIMEV2:
+        
*reinterpret_cast<doris::vectorized::DateV2Value<doris::vectorized::DateTimeV2ValueType>*>(
+                dst) =
+                *reinterpret_cast<const doris::vectorized::DateV2Value<
+                        doris::vectorized::DateTimeV2ValueType>*>(value);
+        break;
+
+    case TYPE_DECIMALV2:
+        *reinterpret_cast<PackedInt128*>(dst) = *reinterpret_cast<const 
PackedInt128*>(value);
+        break;
+
+    case TYPE_DECIMAL32:
+        *reinterpret_cast<doris::vectorized::Decimal32*>(dst) =
+                *reinterpret_cast<const doris::vectorized::Decimal32*>(value);
+        break;
+    case TYPE_DECIMAL64:
+        *reinterpret_cast<doris::vectorized::Decimal64*>(dst) =
+                *reinterpret_cast<const doris::vectorized::Decimal64*>(value);
+        break;
+    case TYPE_DECIMAL128:
+        *reinterpret_cast<doris::vectorized::Decimal128*>(dst) =
+                *reinterpret_cast<const doris::vectorized::Decimal128*>(value);
+        break;
+
+    case TYPE_OBJECT:
+    case TYPE_HLL:
+    case TYPE_QUANTILE_STATE:
+    case TYPE_VARCHAR:
+    case TYPE_CHAR:
+    case TYPE_VARIANT:
+    case TYPE_STRING: {
+        const StringValue* src = reinterpret_cast<const StringValue*>(value);

Review Comment:
   warning: unknown type name 'StringValue'; did you mean 'StringVal'? 
[clang-diagnostic-error]
   
   ```suggestion
           const StringValue* src = reinterpret_cast<const StringVal*>(value);
   ```
   **be/src/udf/udf.h:393:** 'StringVal' declared here
   ```cpp
   struct StringVal : public AnyVal {
          ^
   ```
   



##########
be/src/vec/columns/column_array.cpp:
##########
@@ -46,6 +46,34 @@
   */
 static constexpr size_t max_array_size_as_field = 1000000;
 
+template <typename T>
+ColumnPtr ColumnArray::index_impl(const PaddedPODArray<T>& indexes, size_t 
limit) const {
+    assert(limit <= indexes.size());
+    if (limit == 0) return ColumnArray::create(data->clone_empty());
+    /// Convert indexes to UInt64 in case of overflow.
+    auto nested_indexes_column = ColumnUInt64::create();
+    PaddedPODArray<UInt64>& nested_indexes = nested_indexes_column->get_data();
+    nested_indexes.reserve(get_offsets().back());
+    auto res = ColumnArray::create(data->clone_empty());
+    Offsets64& res_offsets = res->get_offsets();
+    res_offsets.resize(limit);
+    size_t current_offset = 0;
+    for (size_t i = 0; i < limit; ++i) {
+        for (size_t j = 0; j < size_at(indexes[i]); ++j)
+            nested_indexes.push_back(offset_at(indexes[i]) + j);
+        current_offset += size_at(indexes[i]);
+        res_offsets[i] = current_offset;
+    }
+    if (current_offset != 0) res->data = data->index(*nested_indexes_column, 
current_offset);

Review Comment:
   warning: statement should be inside braces 
[readability-braces-around-statements]
   
   ```suggestion
       if (current_offset != 0) { res->data = 
data->index(*nested_indexes_column, current_offset);
   }
   ```
   



##########
be/src/vec/columns/column_array.cpp:
##########
@@ -46,6 +46,34 @@
   */
 static constexpr size_t max_array_size_as_field = 1000000;
 
+template <typename T>
+ColumnPtr ColumnArray::index_impl(const PaddedPODArray<T>& indexes, size_t 
limit) const {
+    assert(limit <= indexes.size());
+    if (limit == 0) return ColumnArray::create(data->clone_empty());
+    /// Convert indexes to UInt64 in case of overflow.
+    auto nested_indexes_column = ColumnUInt64::create();
+    PaddedPODArray<UInt64>& nested_indexes = nested_indexes_column->get_data();
+    nested_indexes.reserve(get_offsets().back());
+    auto res = ColumnArray::create(data->clone_empty());
+    Offsets64& res_offsets = res->get_offsets();
+    res_offsets.resize(limit);
+    size_t current_offset = 0;
+    for (size_t i = 0; i < limit; ++i) {
+        for (size_t j = 0; j < size_at(indexes[i]); ++j)
+            nested_indexes.push_back(offset_at(indexes[i]) + j);

Review Comment:
   warning: statement should be inside braces 
[readability-braces-around-statements]
   
   ```suggestion
           for (size_t j = 0; j < size_at(indexes[i]); ++j) {
               nested_indexes.push_back(offset_at(indexes[i]) + j);
   }
   ```
   



##########
be/src/vec/columns/column_array.cpp:
##########
@@ -46,6 +46,34 @@ extern const int TOO_LARGE_ARRAY_SIZE;
   */
 static constexpr size_t max_array_size_as_field = 1000000;
 
+template <typename T>
+ColumnPtr ColumnArray::index_impl(const PaddedPODArray<T>& indexes, size_t 
limit) const {
+    assert(limit <= indexes.size());
+    if (limit == 0) return ColumnArray::create(data->clone_empty());

Review Comment:
   warning: statement should be inside braces 
[readability-braces-around-statements]
   
   ```suggestion
       if (limit == 0) { return ColumnArray::create(data->clone_empty());
   }
   ```
   



-- 
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