blob: bd1acbcd335338a863634c0ee59f5936151a087a [file] [log] [blame]
// 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 "jsonb_document.h"
#include "runtime/primitive_type.h"
#include "util/jsonb_utils.h"
#include "vec/core/types.h"
#include "vec/functions/cast/cast_base.h"
#include "vec/functions/cast/cast_to_basic_number_common.h"
#include "vec/functions/cast/cast_to_boolean.h"
#include "vec/functions/cast/cast_to_decimal.h"
namespace doris::vectorized {
struct JsonbCast {
static Status report_error(const JsonbValue* jsonb_value, PrimitiveType to_type) {
return Status::InvalidArgument("Cannot cast from jsonb value type {} to doris type {}",
JsonbToJson {}.to_json_string(jsonb_value),
type_to_string(to_type));
}
static bool cast_from_json_to_boolean(const JsonbValue* jsonb_value, UInt8& to,
CastParameters& params) {
switch (jsonb_value->type) {
case JsonbType::T_True:
case JsonbType::T_False: {
return CastToBool::from_number((UInt8)jsonb_value->isTrue(), to, params);
}
case JsonbType::T_Int8: {
auto val = jsonb_value->unpack<JsonbInt8Val>()->val();
return CastToBool::from_number(val, to, params);
}
case JsonbType::T_Int16: {
auto val = jsonb_value->unpack<JsonbInt16Val>()->val();
return CastToBool::from_number(val, to, params);
}
case JsonbType::T_Int32: {
auto val = jsonb_value->unpack<JsonbInt32Val>()->val();
return CastToBool::from_number(val, to, params);
}
case JsonbType::T_Int64: {
auto val = jsonb_value->unpack<JsonbInt64Val>()->val();
return CastToBool::from_number(val, to, params);
}
case JsonbType::T_Int128: {
auto val = jsonb_value->unpack<JsonbInt128Val>()->val();
return CastToBool::from_number(val, to, params);
}
case JsonbType::T_Double: {
auto val = jsonb_value->unpack<JsonbDoubleVal>()->val();
return CastToBool::from_number(val, to, params);
}
case JsonbType::T_Float: {
auto val = jsonb_value->unpack<JsonbFloatVal>()->val();
return CastToBool::from_number(val, to, params);
}
case JsonbType::T_Decimal32: {
auto val = jsonb_value->unpack<JsonbDecimal32>()->val();
UInt32 precision = jsonb_value->unpack<JsonbDecimal32>()->precision;
UInt32 scale = jsonb_value->unpack<JsonbDecimal32>()->scale;
return CastToBool::from_decimal(vectorized::Decimal32 {val}, to, precision, scale,
params);
}
case JsonbType::T_Decimal64: {
auto val = jsonb_value->unpack<JsonbDecimal64>()->val();
UInt32 precision = jsonb_value->unpack<JsonbDecimal64>()->precision;
UInt32 scale = jsonb_value->unpack<JsonbDecimal64>()->scale;
return CastToBool::from_decimal(vectorized::Decimal64 {val}, to, precision, scale,
params);
}
case JsonbType::T_Decimal128: {
auto val = jsonb_value->unpack<JsonbDecimal128>()->val();
UInt32 precision = jsonb_value->unpack<JsonbDecimal128>()->precision;
UInt32 scale = jsonb_value->unpack<JsonbDecimal128>()->scale;
return CastToBool::from_decimal(vectorized::Decimal128V3 {val}, to, precision, scale,
params);
}
case JsonbType::T_Decimal256: {
auto val = jsonb_value->unpack<JsonbDecimal256>()->val();
UInt32 precision = jsonb_value->unpack<JsonbDecimal256>()->precision;
UInt32 scale = jsonb_value->unpack<JsonbDecimal256>()->scale;
return CastToBool::from_decimal(vectorized::Decimal256 {val}, to, precision, scale,
params);
}
case JsonbType::T_String: {
const auto* blob = jsonb_value->unpack<JsonbBinaryVal>();
StringRef str_ref {blob->getBlob(), blob->getBlobLen()};
return CastToBool::from_string(str_ref, to, params);
}
default: {
return false;
}
}
}
template <typename T>
static bool cast_from_json_to_int(const JsonbValue* jsonb_value, T& to,
CastParameters& params) {
switch (jsonb_value->type) {
case JsonbType::T_True:
case JsonbType::T_False: {
auto val = (UInt8)jsonb_value->isTrue();
return CastToInt::from_bool(val, to, params);
}
case JsonbType::T_Int8: {
auto val = jsonb_value->unpack<JsonbInt8Val>()->val();
return CastToInt::from_int(val, to, params);
}
case JsonbType::T_Int16: {
auto val = jsonb_value->unpack<JsonbInt16Val>()->val();
return CastToInt::from_int(val, to, params);
}
case JsonbType::T_Int32: {
auto val = jsonb_value->unpack<JsonbInt32Val>()->val();
return CastToInt::from_int(val, to, params);
}
case JsonbType::T_Int64: {
auto val = jsonb_value->unpack<JsonbInt64Val>()->val();
return CastToInt::from_int(val, to, params);
}
case JsonbType::T_Int128: {
auto val = jsonb_value->unpack<JsonbInt128Val>()->val();
return CastToInt::from_int(val, to, params);
}
case JsonbType::T_Double: {
auto val = jsonb_value->unpack<JsonbDoubleVal>()->val();
return CastToInt::from_float(val, to, params);
}
case JsonbType::T_Float: {
auto val = jsonb_value->unpack<JsonbFloatVal>()->val();
return CastToInt::from_float(val, to, params);
}
case JsonbType::T_Decimal32: {
auto val = jsonb_value->unpack<JsonbDecimal32>()->val();
UInt32 precision = jsonb_value->unpack<JsonbDecimal32>()->precision;
UInt32 scale = jsonb_value->unpack<JsonbDecimal32>()->scale;
return CastToInt::from_decimal(vectorized::Decimal32 {val}, precision, scale, to,
params);
}
case JsonbType::T_Decimal64: {
auto val = jsonb_value->unpack<JsonbDecimal64>()->val();
UInt32 precision = jsonb_value->unpack<JsonbDecimal64>()->precision;
UInt32 scale = jsonb_value->unpack<JsonbDecimal64>()->scale;
return CastToInt::from_decimal(vectorized::Decimal64 {val}, precision, scale, to,
params);
}
case JsonbType::T_Decimal128: {
auto val = jsonb_value->unpack<JsonbDecimal128>()->val();
UInt32 precision = jsonb_value->unpack<JsonbDecimal128>()->precision;
UInt32 scale = jsonb_value->unpack<JsonbDecimal128>()->scale;
return CastToInt::from_decimal(vectorized::Decimal128V3 {val}, precision, scale, to,
params);
}
case JsonbType::T_Decimal256: {
auto val = jsonb_value->unpack<JsonbDecimal256>()->val();
UInt32 precision = jsonb_value->unpack<JsonbDecimal256>()->precision;
UInt32 scale = jsonb_value->unpack<JsonbDecimal256>()->scale;
return CastToInt::from_decimal(vectorized::Decimal256 {val}, precision, scale, to,
params);
}
case JsonbType::T_String: {
const auto* blob = jsonb_value->unpack<JsonbBinaryVal>();
StringRef str_ref {blob->getBlob(), blob->getBlobLen()};
return std::visit(
[&](auto is_strict_mode) {
return CastToInt::from_string<is_strict_mode>(str_ref, to, params);
},
vectorized::make_bool_variant(params.is_strict));
}
default: {
return false;
}
}
}
template <typename T>
static bool cast_from_json_to_float(const JsonbValue* jsonb_value, T& to,
CastParameters& params) {
switch (jsonb_value->type) {
case JsonbType::T_True:
case JsonbType::T_False: {
auto val = (UInt8)jsonb_value->isTrue();
return CastToFloat::from_bool(val, to, params);
}
case JsonbType::T_Int8: {
auto val = jsonb_value->unpack<JsonbInt8Val>()->val();
return CastToFloat::from_int(val, to, params);
}
case JsonbType::T_Int16: {
auto val = jsonb_value->unpack<JsonbInt16Val>()->val();
return CastToFloat::from_int(val, to, params);
}
case JsonbType::T_Int32: {
auto val = jsonb_value->unpack<JsonbInt32Val>()->val();
return CastToFloat::from_int(val, to, params);
}
case JsonbType::T_Int64: {
auto val = jsonb_value->unpack<JsonbInt64Val>()->val();
return CastToFloat::from_int(val, to, params);
}
case JsonbType::T_Int128: {
auto val = jsonb_value->unpack<JsonbInt128Val>()->val();
return CastToFloat::from_int(val, to, params);
}
case JsonbType::T_Double: {
auto val = jsonb_value->unpack<JsonbDoubleVal>()->val();
return CastToFloat::from_float(val, to, params);
}
case JsonbType::T_Float: {
auto val = jsonb_value->unpack<JsonbFloatVal>()->val();
return CastToFloat::from_float(val, to, params);
}
case JsonbType::T_Decimal32: {
auto val = jsonb_value->unpack<JsonbDecimal32>()->val();
UInt32 scale = jsonb_value->unpack<JsonbDecimal32>()->scale;
return CastToFloat::from_decimal(vectorized::Decimal32 {val}, scale, to, params);
}
case JsonbType::T_Decimal64: {
auto val = jsonb_value->unpack<JsonbDecimal64>()->val();
UInt32 scale = jsonb_value->unpack<JsonbDecimal64>()->scale;
return CastToFloat::from_decimal(vectorized::Decimal64 {val}, scale, to, params);
}
case JsonbType::T_Decimal128: {
auto val = jsonb_value->unpack<JsonbDecimal128>()->val();
UInt32 scale = jsonb_value->unpack<JsonbDecimal128>()->scale;
return CastToFloat::from_decimal(vectorized::Decimal128V3 {val}, scale, to, params);
}
case JsonbType::T_Decimal256: {
auto val = jsonb_value->unpack<JsonbDecimal256>()->val();
UInt32 scale = jsonb_value->unpack<JsonbDecimal256>()->scale;
return CastToFloat::from_decimal(vectorized::Decimal256 {val}, scale, to, params);
}
case JsonbType::T_String: {
const auto* blob = jsonb_value->unpack<JsonbBinaryVal>();
StringRef str_ref {blob->getBlob(), blob->getBlobLen()};
return CastToFloat::from_string(str_ref, to, params);
}
default: {
return false;
}
}
}
template <typename T>
static bool cast_from_json_to_decimal(const JsonbValue* jsonb_value, T& to, UInt32 to_precision,
UInt32 to_scale, CastParameters& params) {
switch (jsonb_value->type) {
case JsonbType::T_True:
case JsonbType::T_False: {
UInt8 val = jsonb_value->isTrue();
return CastToDecimal::from_bool(val, to, to_precision, to_scale, params);
}
case JsonbType::T_Int8: {
auto val = jsonb_value->unpack<JsonbInt8Val>()->val();
return CastToDecimal::from_int(val, to, to_precision, to_scale, params);
}
case JsonbType::T_Int16: {
auto val = jsonb_value->unpack<JsonbInt16Val>()->val();
return CastToDecimal::from_int(val, to, to_precision, to_scale, params);
}
case JsonbType::T_Int32: {
auto val = jsonb_value->unpack<JsonbInt32Val>()->val();
return CastToDecimal::from_int(val, to, to_precision, to_scale, params);
}
case JsonbType::T_Int64: {
auto val = jsonb_value->unpack<JsonbInt64Val>()->val();
return CastToDecimal::from_int(val, to, to_precision, to_scale, params);
}
case JsonbType::T_Int128: {
auto val = jsonb_value->unpack<JsonbInt128Val>()->val();
return CastToDecimal::from_int(val, to, to_precision, to_scale, params);
}
case JsonbType::T_Double: {
auto val = jsonb_value->unpack<JsonbDoubleVal>()->val();
return CastToDecimal::from_float(val, to, to_precision, to_scale, params);
}
case JsonbType::T_Float: {
auto val = jsonb_value->unpack<JsonbFloatVal>()->val();
return CastToDecimal::from_float(val, to, to_precision, to_scale, params);
}
case JsonbType::T_Decimal32: {
auto val = Decimal32 {jsonb_value->unpack<JsonbDecimal32>()->val()};
UInt32 from_precision = jsonb_value->unpack<JsonbDecimal32>()->precision;
UInt32 from_scale = jsonb_value->unpack<JsonbDecimal32>()->scale;
return CastToDecimal::from_decimalv3(val, from_precision, from_scale, to, to_precision,
to_scale, params);
}
case JsonbType::T_Decimal64: {
auto val = Decimal64 {jsonb_value->unpack<JsonbDecimal64>()->val()};
UInt32 from_precision = jsonb_value->unpack<JsonbDecimal64>()->precision;
UInt32 from_scale = jsonb_value->unpack<JsonbDecimal64>()->scale;
return CastToDecimal::from_decimalv3(val, from_precision, from_scale, to, to_precision,
to_scale, params);
}
case JsonbType::T_Decimal128: {
auto val = Decimal128V3 {jsonb_value->unpack<JsonbDecimal128>()->val()};
UInt32 from_precision = jsonb_value->unpack<JsonbDecimal128>()->precision;
UInt32 from_scale = jsonb_value->unpack<JsonbDecimal128>()->scale;
return CastToDecimal::from_decimalv3(val, from_precision, from_scale, to, to_precision,
to_scale, params);
}
case JsonbType::T_Decimal256: {
auto val = Decimal256 {jsonb_value->unpack<JsonbDecimal256>()->val()};
UInt32 from_precision = jsonb_value->unpack<JsonbDecimal256>()->precision;
UInt32 from_scale = jsonb_value->unpack<JsonbDecimal256>()->scale;
return CastToDecimal::from_decimalv3(val, from_precision, from_scale, to, to_precision,
to_scale, params);
}
case JsonbType::T_String: {
const auto* blob = jsonb_value->unpack<JsonbBinaryVal>();
StringRef str_ref {blob->getBlob(), blob->getBlobLen()};
return CastToDecimal::from_string(str_ref, to, to_precision, to_scale, params);
}
default: {
return false;
}
}
}
};
} // namespace doris::vectorized