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