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

Reply via email to