• Alexander Barkov's avatar
    MDEV-15926 MEDIUMINT returns wrong I_S attributes · 9aaf62d0
    Alexander Barkov authored
    Problem:
    
    The logic in store_column_type() with a switch on field type was
    hard to follow. The part for MEDIUMINT (MYSQL_TYPE_INT24) was not correct.
    It erroneously calculated the precision of MEDIUMINT UNSIGNED
    as 7 instead of 8.
    
    A similar hard-to-follow switch doing some type specific calculations
    resided in adjust_max_effective_column_length(). It was also wrong for
    MEDIUMINT (reported as a separate issue in MDEV-15946).
    
    Solution:
    
    1. Introducing a new class Information_schema_numeric_attributes
    2. Adding a new virtual method Field::information_schema_numeric_attributes()
    3. Splitting the logic in store_column_type() into virtual
       implementations of information_schema_numeric_attributes().
    4. In order to avoid adding duplicate code for the integer data types,
       adding a new virtual method Field_int::numeric_precision(),
       which returns the number of digits.
    
    Additional changes:
    
    1. Adding the "const" qualifier to Field::max_display_length()
    
    2. Moving the code from adjust_max_effective_column_length()
      directly to Field::max_display_length().
      There was no any sense to have two implementations:
      - a set of wrong virtual implementations for Field_xxx::max_display_length()
      - additional code in adjust_max_effective_column_length() fixing
        bad results of Field_xxx::max_display_length()
      This change is safe:
      - The code using Field::max_display_length()
        in field.cc, sql_show.cc, sql_type.cc is not affected.
      - The code in rpl_utility.cc is also not affected.
        See a new DBUG_ASSSERT and new comments explaining why.
    
      In the new reduction, Field_xxx::max_display_length() returns
      correct results for all integer types (except MEDIUMINT, see below).
    
      Putting implementations of numeric_precision() and max_display_length()
      near each other in field.h made the logic much clearer and thus
      helped to reveal bad results for Field_medium::max_display_length(),
      which returns 9 instead of 8 for signed MEDIUMINT fields.
      This problem will be addressed separately (MDEV-15946).
    
    Note, this change is also useful for pluggable data types (see MDEV-4912),
    as now a user defined Field_xxx has a way to control what's returned
    in INFORMATION_SCHEMA.COLUMNS.NUMERIC_PRECISION and
    INFORMATION_SCHEMA.COLUMNS.NUMERIC_SCALE by implementing
    a desired behavior in Field_xxx::information_schema_numeric_attributes().
    9aaf62d0
rpl_utility.cc 38.1 KB