diff --git a/be/src/util/string_parser.hpp b/be/src/util/string_parser.hpp index e95f825dd11b87..2a9a892c96f095 100644 --- a/be/src/util/string_parser.hpp +++ b/be/src/util/string_parser.hpp @@ -114,6 +114,7 @@ bool range_suite(const char* s, const char* end) { } inline auto is_digit_range = range_suite; +inline auto is_space_range = range_suite; inline Status assert_within_bound(const char* s, const char* end, size_t offset) { if (s + offset >= end) [[unlikely]] { diff --git a/be/src/vec/data_types/serde/data_type_date_or_datetime_serde.cpp b/be/src/vec/data_types/serde/data_type_date_or_datetime_serde.cpp index 71edd0f846ac96..b959d39e6caa11 100644 --- a/be/src/vec/data_types/serde/data_type_date_or_datetime_serde.cpp +++ b/be/src/vec/data_types/serde/data_type_date_or_datetime_serde.cpp @@ -394,7 +394,11 @@ Status DataTypeDateSerDe::from_string_strict_mode_batch( CastToDateOrDatetime::from_string_strict_mode(str, res, options.timezone, params); // only after we called something with `IS_STRICT = true`, params.status will be set - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {} to {} failed: ", str.to_string_view(), name())); + return params.status; + } col_data.get_data()[i] = binary_cast(res); } @@ -433,7 +437,10 @@ Status DataTypeDateSerDe::from_string_strict_mode(StringRef& str, IColumn& co CastToDateOrDatetime::from_string_strict_mode(str, res, options.timezone, params); // only after we called something with `IS_STRICT = true`, params.status will be set - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format("parse {} to {} failed: ", str.to_string_view(), name())); + return params.status; + } col_data.insert_value(binary_cast(res)); return Status::OK(); @@ -475,7 +482,11 @@ Status DataTypeDateSerDe::from_int_strict_mode_batch(const IntDataType::Colum for (size_t i = 0; i < int_col.size(); ++i) { CppType val; CastToDateOrDatetime::from_integer(int_col.get_element(i), val, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {} to {} failed: ", int_col.get_element(i), name())); + return params.status; + } col_data.get_data()[i] = binary_cast(val); } @@ -517,7 +528,11 @@ Status DataTypeDateSerDe::from_float_strict_mode_batch( for (size_t i = 0; i < float_col.size(); ++i) { CppType val; CastToDateOrDatetime::from_float(float_col.get_data()[i], val, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {} to {} failed: ", float_col.get_data()[i], name())); + return params.status; + } col_data.get_data()[i] = binary_cast(val); } @@ -562,7 +577,12 @@ Status DataTypeDateSerDe::from_decimal_strict_mode_batch( CastToDateOrDatetime::from_decimal(decimal_col.get_intergral_part(i), decimal_col.get_fractional_part(i), decimal_col.get_scale(), val, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {}.{} to {} failed: ", decimal_col.get_intergral_part(i), + decimal_col.get_fractional_part(i), name())); + return params.status; + } col_data.get_data()[i] = binary_cast(val); } diff --git a/be/src/vec/data_types/serde/data_type_date_or_datetime_serde.h b/be/src/vec/data_types/serde/data_type_date_or_datetime_serde.h index f762b2d8c983b2..0f0e182d4a282b 100644 --- a/be/src/vec/data_types/serde/data_type_date_or_datetime_serde.h +++ b/be/src/vec/data_types/serde/data_type_date_or_datetime_serde.h @@ -22,6 +22,7 @@ #include #include +#include #include "common/status.h" #include "data_type_number_serde.h" @@ -43,6 +44,7 @@ class DataTypeDateSerDe : public DataTypeNumberSerDe { using ColumnType = PrimitiveTypeTraits::ColumnType; using NativeType = PrimitiveTypeTraits::CppNativeType; // int64 using CppType = PrimitiveTypeTraits::CppType; // VecDateTimeValue + constexpr static std::string_view name() { return IsDatetime ? "DateTime" : "Date"; } using typename DataTypeNumberSerDe::FormatOptions; DataTypeDateSerDe(int nesting_level = 1) : DataTypeNumberSerDe(nesting_level) {}; diff --git a/be/src/vec/data_types/serde/data_type_datetimev2_serde.cpp b/be/src/vec/data_types/serde/data_type_datetimev2_serde.cpp index bcf287346094e2..2bf24368e8b098 100644 --- a/be/src/vec/data_types/serde/data_type_datetimev2_serde.cpp +++ b/be/src/vec/data_types/serde/data_type_datetimev2_serde.cpp @@ -93,7 +93,11 @@ Status DataTypeDateTimeV2SerDe::from_string_strict_mode_batch( DateV2Value res; CastToDatetimeV2::from_string_strict_mode(str, res, options.timezone, _scale, params); // only after we called something with `IS_STRICT = true`, params.status will be set - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {} to datetime failed: ", str.to_string_view())); + return params.status; + } col_data.get_data()[i] = binary_cast, UInt64>(res); } @@ -128,7 +132,10 @@ Status DataTypeDateTimeV2SerDe::from_string_strict_mode(StringRef& str, IColumn& DateV2Value res; CastToDatetimeV2::from_string_strict_mode(str, res, options.timezone, _scale, params); // only after we called something with `IS_STRICT = true`, params.status will be set - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format("parse {} to datetime failed: ", str.to_string_view())); + return params.status; + } col_data.insert_value(binary_cast, UInt64>(res)); return Status::OK(); } @@ -166,7 +173,11 @@ Status DataTypeDateTimeV2SerDe::from_int_strict_mode_batch(const IntDataType::Co for (size_t i = 0; i < int_col.size(); ++i) { DateV2Value val; CastToDatetimeV2::from_integer(int_col.get_element(i), val, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {} to datetime failed: ", int_col.get_element(i))); + return params.status; + } col_data.get_data()[i] = binary_cast, UInt64>(val); } @@ -207,7 +218,11 @@ Status DataTypeDateTimeV2SerDe::from_float_strict_mode_batch( for (size_t i = 0; i < float_col.size(); ++i) { DateV2Value val; CastToDatetimeV2::from_float(float_col.get_data()[i], val, _scale, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {} to datetime failed: ", float_col.get_data()[i])); + return params.status; + } col_data.get_data()[i] = binary_cast, UInt64>(val); } @@ -251,7 +266,12 @@ Status DataTypeDateTimeV2SerDe::from_decimal_strict_mode_batch( CastToDatetimeV2::from_decimal(decimal_col.get_intergral_part(i), decimal_col.get_fractional_part(i), decimal_col.get_scale(), val, _scale, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format( + "parse {}.{} to datetime failed: ", decimal_col.get_intergral_part(i), + decimal_col.get_fractional_part(i))); + return params.status; + } col_data.get_data()[i] = binary_cast, UInt64>(val); } diff --git a/be/src/vec/data_types/serde/data_type_datev2_serde.cpp b/be/src/vec/data_types/serde/data_type_datev2_serde.cpp index fb26768d5df35a..360aa7cd59f6cc 100644 --- a/be/src/vec/data_types/serde/data_type_datev2_serde.cpp +++ b/be/src/vec/data_types/serde/data_type_datev2_serde.cpp @@ -19,6 +19,7 @@ #include #include +#include #include @@ -270,7 +271,10 @@ Status DataTypeDateV2SerDe::from_string_strict_mode_batch( DateV2Value res; CastToDateV2::from_string_strict_mode(str, res, options.timezone, params); // only after we called something with `IS_STRICT = true`, params.status will be set - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format("parse {} to date failed: ", str.to_string_view())); + return params.status; + } col_data.get_data()[i] = binary_cast, UInt32>(res); } @@ -305,7 +309,10 @@ Status DataTypeDateV2SerDe::from_string_strict_mode(StringRef& str, IColumn& col DateV2Value res; CastToDateV2::from_string_strict_mode(str, res, options.timezone, params); // only after we called something with `IS_STRICT = true`, params.status will be set - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format("parse {} to date failed: ", str.to_string_view())); + return params.status; + } col_data.insert_value(binary_cast, UInt32>(res)); return Status::OK(); @@ -343,7 +350,10 @@ Status DataTypeDateV2SerDe::from_int_strict_mode_batch(const IntDataType::Column for (size_t i = 0; i < int_col.size(); ++i) { DateV2Value val; CastToDateV2::from_integer(int_col.get_element(i), val, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format("parse {} to date failed: ", int_col.get_element(i))); + return params.status; + } col_data.get_data()[i] = binary_cast, UInt32>(val); } @@ -382,7 +392,11 @@ Status DataTypeDateV2SerDe::from_float_strict_mode_batch(const FloatDataType::Co for (size_t i = 0; i < float_col.size(); ++i) { DateV2Value val; CastToDateV2::from_float(float_col.get_data()[i], val, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {} to date failed: ", float_col.get_data()[i])); + return params.status; + } col_data.get_data()[i] = binary_cast, UInt32>(val); } @@ -423,7 +437,12 @@ Status DataTypeDateV2SerDe::from_decimal_strict_mode_batch( DateV2Value val; CastToDateV2::from_decimal(decimal_col.get_intergral_part(i), decimal_col.get_scale(), val, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {}.{} to date failed: ", decimal_col.get_intergral_part(i), + decimal_col.get_fractional_part(i))); + return params.status; + } col_data.get_data()[i] = binary_cast, UInt32>(val); } diff --git a/be/src/vec/data_types/serde/data_type_time_serde.cpp b/be/src/vec/data_types/serde/data_type_time_serde.cpp index c641dcf14a2694..a31701aa41836c 100644 --- a/be/src/vec/data_types/serde/data_type_time_serde.cpp +++ b/be/src/vec/data_types/serde/data_type_time_serde.cpp @@ -109,7 +109,10 @@ Status DataTypeTimeV2SerDe::from_string_strict_mode_batch( TimeValue::TimeType res; CastToTimeV2::from_string_strict_mode(str, res, options.timezone, _scale, params); // only after we called something with `IS_STRICT = true`, params.status will be set - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format("parse {} to time failed: ", str.to_string_view())); + return params.status; + } col_data.get_data()[i] = res; } @@ -141,7 +144,11 @@ Status DataTypeTimeV2SerDe::from_string_strict_mode(StringRef& str, IColumn& col TimeValue::TimeType res; CastToTimeV2::from_string_strict_mode(str, res, options.timezone, _scale, params); // only after we called something with `IS_STRICT = true`, params.status will be set - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format("parse {} to time failed: ", str.to_string_view())); + return params.status; + } + col_data.insert_value(res); return Status::OK(); } @@ -178,7 +185,10 @@ Status DataTypeTimeV2SerDe::from_int_strict_mode_batch(const IntDataType::Column for (size_t i = 0; i < int_col.size(); ++i) { TimeValue::TimeType val = 0; CastToTimeV2::from_integer(int_col.get_element(i), val, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend(fmt::format("parse {} to time failed: ", int_col.get_element(i))); + return params.status; + } col_data.get_data()[i] = val; } @@ -218,7 +228,11 @@ Status DataTypeTimeV2SerDe::from_float_strict_mode_batch(const FloatDataType::Co for (size_t i = 0; i < float_col.size(); ++i) { TimeValue::TimeType val = 0; CastToTimeV2::from_float(float_col.get_data()[i], val, _scale, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {} to time failed: ", float_col.get_data()[i])); + return params.status; + } col_data.get_data()[i] = val; } @@ -261,7 +275,12 @@ Status DataTypeTimeV2SerDe::from_decimal_strict_mode_batch( CastToTimeV2::from_decimal(decimal_col.get_intergral_part(i), decimal_col.get_fractional_part(i), decimal_col.get_scale(), val, _scale, params); - RETURN_IF_ERROR(params.status); + if (!params.status.ok()) [[unlikely]] { + params.status.prepend( + fmt::format("parse {}.{} to time failed: ", decimal_col.get_intergral_part(i), + decimal_col.get_fractional_part(i))); + return params.status; + } col_data.get_data()[i] = val; } diff --git a/be/src/vec/functions/cast/cast_to_datetimev2_impl.hpp b/be/src/vec/functions/cast/cast_to_datetimev2_impl.hpp index f79e729fb9e26e..ba41b76d1e92c5 100644 --- a/be/src/vec/functions/cast/cast_to_datetimev2_impl.hpp +++ b/be/src/vec/functions/cast/cast_to_datetimev2_impl.hpp @@ -442,7 +442,10 @@ inline bool CastToDatetimeV2::from_string_strict_mode(const StringRef& str, SET_PARAMS_RET_FALSE_IF_ERR((consume_digit(ptr, end, part[0]))); SET_PARAMS_RET_FALSE_IFN(res.set_time_unit(part[0]), "invalid hour {}", part[0]); - SET_PARAMS_RET_FALSE_IF_ERR(assert_within_bound(ptr, end, 0)); + if (ptr == end) { + // no minute part, just return. + return true; + } if (*ptr == ':') { // with hour:minute:second if (consume_one_colon(ptr, end)) { // minute @@ -675,7 +678,7 @@ inline bool CastToDatetimeV2::from_string_non_strict_mode_impl( SET_PARAMS_RET_FALSE_IFN(res.set_time_unit(day), "invalid day {}", day); } - if (ptr == end) { + if (is_space_range(ptr, end)) { // no time part, just return. res.unchecked_set_time_unit(0); res.unchecked_set_time_unit(0); diff --git a/be/src/vec/functions/cast/cast_to_datev2_impl.hpp b/be/src/vec/functions/cast/cast_to_datev2_impl.hpp index 79910b5a042728..e4bfbc3e85d968 100644 --- a/be/src/vec/functions/cast/cast_to_datev2_impl.hpp +++ b/be/src/vec/functions/cast/cast_to_datev2_impl.hpp @@ -24,6 +24,7 @@ #include "cast_base.h" #include "common/status.h" #include "runtime/primitive_type.h" +#include "util/string_parser.hpp" #include "vec/core/types.h" #include "vec/data_types/data_type_decimal.h" // IWYU pragma: keep #include "vec/data_types/serde/data_type_serde.h" @@ -377,7 +378,10 @@ inline bool CastToDateV2::from_string_strict_mode(const StringRef& str, SET_PARAMS_RET_FALSE_IF_ERR((consume_digit(ptr, end, part[0]))); SET_PARAMS_RET_FALSE_IFN(res.test_time_unit(part[0]), "invalid hour {}", part[0]); - SET_PARAMS_RET_FALSE_IF_ERR(assert_within_bound(ptr, end, 0)); + if (ptr == end) { + // no minute part, just return. + return true; + } if (*ptr == ':') { // with hour:minute:second if (consume_one_colon(ptr, end)) { // minute @@ -559,7 +563,7 @@ inline bool CastToDateV2::from_string_non_strict_mode_impl(const StringRef& str, SET_PARAMS_RET_FALSE_IFN(res.set_time_unit(day), "invalid day {}", day); } - if (ptr == end) { + if (is_space_range(ptr, end)) { // no time part, just return. return true; } diff --git a/be/src/vec/functions/cast/cast_to_time_impl.hpp b/be/src/vec/functions/cast/cast_to_time_impl.hpp index 076d110556f5dd..db7110336caea5 100644 --- a/be/src/vec/functions/cast/cast_to_time_impl.hpp +++ b/be/src/vec/functions/cast/cast_to_time_impl.hpp @@ -221,56 +221,18 @@ inline bool CastToTimeV2::from_integer(T input, TimeValue::TimeType& val, CastPa } /** - ::= (("T" | " ")