BiteTheDDDDt commented on code in PR #18565: URL: https://github.com/apache/doris/pull/18565#discussion_r1171066642
########## be/src/vec/functions/function_cast.h: ########## @@ -62,7 +65,91 @@ inline UInt32 extract_to_decimal_scale(const ColumnWithTypeAndName& named_column named_column.column->get(0, field); return field.get<UInt32>(); } +/** Cast from string or number to Time. + * In Doris, the underlying storage type of the Time class is Float64. + */ +struct TimeCast { + // Cast from string + // Some examples of conversions. + // '300' -> 00:03:00 '20:23' -> 20:23:00 '20:23:24' -> 20:23:24 + template <typename T> + static bool try_parse_time(char* s, size_t len, T& x) { + char* first_char = s; + char* end_char = s + len; + int hour = 0, minute = 0, second = 0; + auto parse_from_str_to_int = [](char* begin, size_t len, auto& num) { + StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS; + auto int_value = StringParser::string_to_unsigned_int<uint64_t>( + reinterpret_cast<char*>(begin), len, &parse_result); + if (UNLIKELY(parse_result != StringParser::PARSE_SUCCESS)) { + return false; + } + num = int_value; + return true; + }; + char *first_colon {nullptr}, *second_colon {nullptr}; + if ((first_colon = (char*)memchr(first_char, ':', len)) != nullptr) { + if ((second_colon = (char*)memchr(first_colon + 1, ':', end_char - first_colon - 1)) != + nullptr) { + // find tow colon + // parse hour + if (!parse_from_str_to_int(first_char, first_colon - first_char, hour)) { + // hour failed + return false; + } + // parse minute + if (!parse_from_str_to_int(first_colon + 1, second_colon - first_colon - 1, + minute)) { + return false; + } + // parse second + if (!parse_from_str_to_int(second_colon + 1, end_char - second_colon - 1, second)) { + return false; + } + } else { + // find one colon + // parse hour + if (!parse_from_str_to_int(first_char, first_colon - first_char, hour)) { + return false; + } + // parse minute + if (!parse_from_str_to_int(first_colon + 1, end_char - first_colon - 1, minute)) { + return false; + } + } + } else { + // no colon ,so try to parse as a number + size_t from {}; + if (!parse_from_str_to_int(first_char, len, from)) { + return false; + } + return try_parse_time(from, x); + } + // minute second must be < 60 + if (minute >= 60 || second >= 60) { + return false; + } + x = hour * 3600 + minute * 60 + second; + return true; + } + // Cast from number + template <typename T, typename S> + static bool try_parse_time(T from, S& x) { + int64 seconds = from; + int64 hour = 0, minute = 0, second = 0; + second = seconds % 100; + seconds /= 100; Review Comment: ``` seconds=from/100 second=from-seconds*100 ``` Maybe performance will be better this way -- 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