• unknown's avatar
    Bug #24791: Union with AVG-groups generates wrong results · aa323361
    unknown authored
    The problem in this bug is when we create temporary tables. When
    temporary tables are created for unions, there is some 
    inferrence being carried out regarding the type of the column.
    Whenever this column type is inferred to be REAL (i.e. FLOAT or
    DOUBLE), MySQL will always try to maintain exact precision, and
    if that is not possible (there are hardware limits, since FLOAT
    and DOUBLE are stored as approximate values) will switch to
    using approximate values. The problem here is that at this point
    the information about number of significant digits is not 
    available. Furthermore, the number of significant digits should
    be increased for the AVG function, however, this was not properly 
    handled. There are 4 parts to the problem:
    
    #1: DOUBLE and FLOAT fields don't display their proper display 
    lengths in max_display_length(). This is hard-coded as 53 for 
    DOUBLE and 24 for FLOAT. Now changed to instead return the 
    field_length.
    
    #2: Type holders for temporary tables do not preserve the 
    max_length of the Item's from which they are created, and is 
    instead reverted to the 53 and 24 from above. This causes 
    *all* fields to get non-fixed significant digits.
    
    #3: AVG function does not update max_length (display length)
    when updating number of decimals.
    
    #4: The function that switches to non-fixed number of 
    significant digits should use DBL_DIG + 2 or FLT_DIG + 2 as 
    cut-off values (Since fixed precision does not use the 'e' 
    notation)
    
    Of these points, #1 is the controversial one, but this 
    change is preferred and has been cleared with Monty. The 
    function causes quite a few unit tests to blow up and they had
    to b changed, but each one is annotated and motivated. We 
    frequently see the magical 53 and 24 give way to more relevant
    numbers.
    
    
    mysql-test/r/create.result:
      bug#24791
      
      changed test result
      
      With the changes made for FLOAT and DOUBLE, the original display
      lengths are now preserved.
    mysql-test/r/temp_table.result:
      bug#24791
      
      changed test resullt
      
      Test case added
    mysql-test/r/type_float.result:
      bug#24791
      
      changed test result
      
      delta 1: field was originally declared as DOUBLE with no display
      length, so the hardware maximum is chosen rather than 53.
      
      delta 2: fields exceed the maximum precision and thus switch to
      non-fixed significant digits
      
      delta 3: Same as above, number of decmals and significant digits
      was not specified when t3 was created.
    mysql-test/t/temp_table.test:
      bug#24791
      
      Test case
    sql/field.h:
      bug#24791
      
      The method max_display_length is reimplemented as
      
      uint32 max_display_length() { return field_length; }
      
      in Field_double and Field_float. Since all subclasses of 
      Field_real now have the same implementation of this method, the
      implementation has been moved up the hierarchy to Field_real.
    sql/item.cc:
      bug#24791
      
      We switch to a non-fixed number of significant digits
      (by setting decimals=NOT_FIXED_DECIMAL) if the calculated 
      display length is greater than the display length of a value 
      with the maximum precision. These values differ for double and 
      float, obviously.
    sql/item_sum.cc:
      bug#24791
      
      We must increase the display length accordinly whenever we 
      change number of decimal places.
    aa323361
item.cc 181 KB