mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Bug #24791: Union with AVG-groups generates wrong results
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.
This commit is contained in:
@@ -152,3 +152,24 @@ SELECT * FROM t1;
|
||||
i
|
||||
DROP TABLE t1;
|
||||
End of 4.1 tests.
|
||||
CREATE TABLE t1 ( c FLOAT( 20, 14 ) );
|
||||
INSERT INTO t1 VALUES( 12139 );
|
||||
CREATE TABLE t2 ( c FLOAT(30,18) );
|
||||
INSERT INTO t2 VALUES( 123456 );
|
||||
SELECT AVG( c ) FROM t1 UNION SELECT 1;
|
||||
AVG( c )
|
||||
12139
|
||||
1
|
||||
SELECT 1 UNION SELECT AVG( c ) FROM t1;
|
||||
1
|
||||
1
|
||||
12139
|
||||
SELECT 1 UNION SELECT * FROM t2 UNION SELECT 1;
|
||||
1
|
||||
1
|
||||
123456
|
||||
SELECT c/1 FROM t1 UNION SELECT 1;
|
||||
c/1
|
||||
12139
|
||||
1
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
Reference in New Issue
Block a user