• Alexander Barkov's avatar
    A cleanup for MDEV-15340 + fix MDEV-15363 Wrong result for CAST(LAST_DAY(TIME'00:00:00') AS TIME) · 5417002d
    Alexander Barkov authored
    The change N7 in MDEV-15340 (see the commit message) introduced
    a regression in how CAST(AS TIME), HOUR(), TIME_TO_SEC() treat datetimes
    '0000-00-DD mm:hh:ss' (i.e. with zero YYYYMM part and a non-zero day).
    These functions historically do not mix days to hours on datetime-to-time
    conversion. Implementations of the underlying methods used get_arg0_time()
    to fetch MYSQL_TIME. After MDEV-15340, get_arg0_time() went through the
    Time() constructor, which always adds '0000-00-DD' to hours automatically
    (as in all other places in the code we do mix days to hours).
    
    Changes:
    1. Extending Time() to make it possible to choose a desired way of treating
       '0000-00-DD' (ignore or mix to hours) on datetime-to-time conversion.
       Adding a helper class Time::Options for this, which now describes two aspects
       of Time() creation:
       1. Flags for get_date()
       2. Days/hours mixing behavior.
    
    2. Removing Item_func::get_arg0_time(). Using Time() directly
       in all affected classes. Forcing Time() to ignore (rather than mix)
       '0000-00-DD' in these affected classes by passing a suitable Options value.
    
    3. Adding Time::to_seconds(), to reuse the code between
       Item_func_time_to_sec::decimal_op() and Item_func_time_to_sec::int_op().
    
    4. Item_func::get_arg0_date() now returns only a datetime value,
       with automatic time-to-datetime conversion if needed. An assert was
       added to catch attempts to pass TIME_TIME_ONLY to get_arg0_date().
       All callers were checked not to pass TIME_TIME_ONLY, this revealed
       a bug MDEV-15363.
    
    5. Changing Item_func_last_day::get_date() to remove the TIME_TIME_ONLY flag
       before calling get_arg0_date(). This fixes MDEV-15363.
    5417002d
func_time.test 75.4 KB