Files
doris/be/src/vec/exprs/vliteral.cpp
Gabriel 3b46242483 [feature-wip] Optimize Decimal type (#10794)
* [feature-wip](decimalv3) support decimalv3

* [feature-wip] Optimize Decimal type

Co-authored-by: liaoxin <liaoxinbit@126.com>
2022-07-14 10:50:50 +08:00

258 lines
9.9 KiB
C++

// 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.
#include "vec/exprs/vliteral.h"
#include <fmt/format.h>
#include "runtime/large_int_value.h"
#include "util/string_parser.hpp"
#include "vec/core/field.h"
#include "vec/data_types/data_type_decimal.h"
#include "vec/io/io_helper.h"
#include "vec/runtime/vdatetime_value.h"
namespace doris {
namespace vectorized {
void VLiteral::init(const TExprNode& node) {
Field field;
if (node.node_type != TExprNodeType::NULL_LITERAL) {
switch (_type.type) {
case TYPE_BOOLEAN: {
DCHECK_EQ(node.node_type, TExprNodeType::BOOL_LITERAL);
DCHECK(node.__isset.bool_literal);
field = Int8(node.bool_literal.value);
break;
}
case TYPE_TINYINT: {
DCHECK_EQ(node.node_type, TExprNodeType::INT_LITERAL);
DCHECK(node.__isset.int_literal);
field = Int8(node.int_literal.value);
break;
}
case TYPE_SMALLINT: {
DCHECK_EQ(node.node_type, TExprNodeType::INT_LITERAL);
DCHECK(node.__isset.int_literal);
field = Int16(node.int_literal.value);
break;
}
case TYPE_INT: {
DCHECK_EQ(node.node_type, TExprNodeType::INT_LITERAL);
DCHECK(node.__isset.int_literal);
field = Int32(node.int_literal.value);
break;
}
case TYPE_BIGINT: {
DCHECK_EQ(node.node_type, TExprNodeType::INT_LITERAL);
DCHECK(node.__isset.int_literal);
field = Int64(node.int_literal.value);
break;
}
case TYPE_LARGEINT: {
StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS;
DCHECK_EQ(node.node_type, TExprNodeType::LARGE_INT_LITERAL);
__int128_t value = StringParser::string_to_int<__int128>(
node.large_int_literal.value.c_str(), node.large_int_literal.value.size(),
&parse_result);
if (parse_result != StringParser::PARSE_SUCCESS) {
value = MAX_INT128;
}
field = Int128(value);
break;
}
case TYPE_FLOAT: {
DCHECK_EQ(node.node_type, TExprNodeType::FLOAT_LITERAL);
DCHECK(node.__isset.float_literal);
field = Float32(node.float_literal.value);
break;
}
case TYPE_TIME:
case TYPE_DOUBLE: {
DCHECK_EQ(node.node_type, TExprNodeType::FLOAT_LITERAL);
DCHECK(node.__isset.float_literal);
field = Float64(node.float_literal.value);
break;
}
case TYPE_DATE: {
VecDateTimeValue value;
value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size());
value.cast_to_date();
field = Int64(*reinterpret_cast<__int64_t*>(&value));
break;
}
case TYPE_DATEV2: {
DateV2Value value;
value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size());
field = value.to_date_uint32();
break;
}
case TYPE_DATETIME: {
VecDateTimeValue value;
value.from_date_str(node.date_literal.value.c_str(), node.date_literal.value.size());
value.to_datetime();
field = Int64(*reinterpret_cast<__int64_t*>(&value));
break;
}
case TYPE_STRING:
case TYPE_CHAR:
case TYPE_VARCHAR: {
DCHECK_EQ(node.node_type, TExprNodeType::STRING_LITERAL);
DCHECK(node.__isset.string_literal);
field = node.string_literal.value;
break;
}
case TYPE_DECIMALV2: {
DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL);
DCHECK(node.__isset.decimal_literal);
DecimalV2Value value(node.decimal_literal.value);
field = DecimalField<Decimal128>(value.value(), value.scale());
break;
}
case TYPE_DECIMAL32: {
DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL);
DCHECK(node.__isset.decimal_literal);
DataTypePtr type_ptr = create_decimal(node.type.types[0].scalar_type.precision,
node.type.types[0].scalar_type.scale);
auto val = typeid_cast<const DataTypeDecimal<Decimal32>*>(type_ptr.get())
->parse_from_string(node.decimal_literal.value);
auto scale =
typeid_cast<const DataTypeDecimal<Decimal32>*>(type_ptr.get())->get_scale();
field = DecimalField<Decimal32>(val, scale);
break;
}
case TYPE_DECIMAL64: {
DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL);
DCHECK(node.__isset.decimal_literal);
DataTypePtr type_ptr = create_decimal(node.type.types[0].scalar_type.precision,
node.type.types[0].scalar_type.scale);
auto val = typeid_cast<const DataTypeDecimal<Decimal64>*>(type_ptr.get())
->parse_from_string(node.decimal_literal.value);
auto scale =
typeid_cast<const DataTypeDecimal<Decimal64>*>(type_ptr.get())->get_scale();
field = DecimalField<Decimal64>(val, scale);
break;
}
case TYPE_DECIMAL128: {
DCHECK_EQ(node.node_type, TExprNodeType::DECIMAL_LITERAL);
DCHECK(node.__isset.decimal_literal);
DataTypePtr type_ptr = create_decimal(node.type.types[0].scalar_type.precision,
node.type.types[0].scalar_type.scale);
auto val = typeid_cast<const DataTypeDecimal<Decimal128>*>(type_ptr.get())
->parse_from_string(node.decimal_literal.value);
auto scale =
typeid_cast<const DataTypeDecimal<Decimal128>*>(type_ptr.get())->get_scale();
field = DecimalField<Decimal128>(val, scale);
break;
}
default: {
DCHECK(false) << "Invalid type: " << _type.type;
break;
}
}
}
_column_ptr = _data_type->create_column_const(1, field);
}
Status VLiteral::execute(VExprContext* context, vectorized::Block* block, int* result_column_id) {
// Literal expr should return least one row.
size_t row_size = std::max(block->rows(), size_t(1));
*result_column_id = VExpr::insert_param(block, {_column_ptr, _data_type, _expr_name}, row_size);
return Status::OK();
}
std::string VLiteral::debug_string() const {
std::stringstream out;
out << "VLiteral (type = " << _data_type->get_name();
out << ", value = ";
if (_column_ptr.get()->size() > 0) {
StringRef ref = _column_ptr.get()->get_data_at(0);
if (ref.data == nullptr) {
out << "null";
} else {
switch (_type.type) {
case TYPE_BOOLEAN:
case TYPE_TINYINT:
case TYPE_SMALLINT:
case TYPE_INT: {
out << *(reinterpret_cast<const int32_t*>(ref.data));
break;
}
case TYPE_BIGINT: {
out << *(reinterpret_cast<const int64_t*>(ref.data));
break;
}
case TYPE_LARGEINT: {
out << fmt::format("{}", *(reinterpret_cast<const __int128_t*>(ref.data)));
break;
}
case TYPE_FLOAT: {
out << *(reinterpret_cast<const float*>(ref.data));
break;
}
case TYPE_TIME:
case TYPE_DOUBLE: {
out << *(reinterpret_cast<const double_t*>(ref.data));
break;
}
case TYPE_DATE:
case TYPE_DATETIME: {
auto value = *(reinterpret_cast<const int64_t*>(ref.data));
auto date_value = (VecDateTimeValue*)&value;
out << date_value;
break;
}
case TYPE_STRING:
case TYPE_CHAR:
case TYPE_VARCHAR: {
out << ref;
break;
}
case TYPE_DECIMALV2: {
DecimalV2Value value(*(reinterpret_cast<const int128_t*>(ref.data)));
out << value;
break;
}
case TYPE_DECIMAL32: {
write_text<int32_t>(*(reinterpret_cast<const int32_t*>(ref.data)), _type.scale,
out);
break;
}
case TYPE_DECIMAL64: {
write_text<int64_t>(*(reinterpret_cast<const int64_t*>(ref.data)), _type.scale,
out);
break;
}
case TYPE_DECIMAL128: {
write_text<int128_t>(*(reinterpret_cast<const int128_t*>(ref.data)), _type.scale,
out);
break;
}
default: {
out << "UNKNOWN TYPE: " << int(_type.type);
break;
}
}
}
}
out << ")";
return out.str();
}
} // namespace vectorized
} // namespace doris