• Alexander Barkov's avatar
    MDEV-15176 Storing DATETIME-alike VARCHAR data into TIME produces wrong results · 28d4cf0c
    Alexander Barkov authored
    When storing '0001-01-01 10:20:30x', execution went throw the last code
    branch in Field_time::store_TIME_with_warning(), around the test
    for (ltime->year || ltime->month). This then resulted into wrong results
    because:
    
    1. Field_time::store_TIME() does not check YYYYMM against zero.
      It assumes that ltime->days and ltime->hours are already properly set.
      So it mixed days to hours, even when YYYYMM was not zero.
    
    2. Field_time_hires::store_TIME() does not check YYYYMM against zero.
      It assumes that ltime->year, ltime->month, ltime->days and ltime->hours
      are already properly set. So it always mixed days and even months(!) and years(!)
      to hours, using pack_time(). This gave even worse results comparing to #2.
    
    3. Field_timef::store_TIME() did not check the entire YYYYMM for being zero.
      It only checked MM, but did not check YYYY. In case of a zero MM,
      it mixed days to hours, even if YYYY was not zero.
      The wrong code was in TIME_to_longlong_time_packed().
    
    In the new reduction Field_time::store_TIME_with_warning() is responsible
    to prepare the YYYYYMMDD part properly in all code branches
    (with trailing garbage like 'x' and without trailing garbage).
    It was reorganized into a more straightforward style.
    
    Field_time:store_TIME(), Field_time_hires::store_TIME() and
    TIME_to_longlong_time_packed() were fixed to do a DBUG_ASSERT
    on non-zero ltime->year or ltime->month. The code testing ltime->month
    was removed from TIME_to_longlong_time_packed(), as it's now
    properly done on the caller level.
    
    Truncation was moved from Field_timef::store_TIME() to
    Field_time::store_TIME_with_warning().
    
    So now all thee methods Field_time*::store_TIME() assume a properly
    set input value:
    - Only zero ltime->year and ltime->month are allowed.
    - The value must be already properly truncated according to decimals()
      (this will help to add rounding soon, see MDEV-8894)
    
    A "const" qualifier was added to the argument of Field_time*::store_TIME().
    28d4cf0c
field.cc 312 KB