1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Bug #45262: Bad effects with CREATE TABLE and DECIMAL

Using DECIMAL constants with more than 65 digits in CREATE 
TABLE ... SELECT led to bogus errors in release builds or 
assertion failures in debug builds. 
 
The problem was in inconsistency in how DECIMAL constants and 
fields are handled internally. We allow arbitrarily long 
DECIMAL constants, whereas DECIMAL(M,D) columns are limited to 
M<=65 and D<=30. my_decimal_precision_to_length() was used in 
both Item and Field code and truncated precision to 
DECIMAL_MAX_PRECISION when calculating value length without 
adjusting precision and decimals. As a result, a DECIMAL 
constant with more than 65 digits ended up having length less 
than precision or decimals which led to assertion failures. 
 
Fixed by modifying my_decimal_precision_to_length() so that 
precision is truncated to DECIMAL_MAX_PRECISION only for Field 
object which is indicated by the new 'truncate' parameter. 
 
Another inconsistency fixed by this patch is how DECIMAL 
constants and expressions are handled for CREATE ... SELECT. 
create_tmp_field_from_item() (which is used for constants) was 
changed as a part of the bugfix for bug #24907 to handle long 
DECIMAL constants gracefully. Item_func::tmp_table_field() 
(which is used for expressions) on the other hand was still 
using a simplistic approach when creating a Field_new_decimal 
from a DECIMAL expression. 

mysql-test/r/type_newdecimal.result:
  Added a test case for bug #45262.
mysql-test/t/type_newdecimal.test:
  Added a test case for bug #45262.
sql/item.cc:
  Use the new 'truncate' parameter in 
  my_decimal_precision_to_length().
sql/item_cmpfunc.cc:
  Use the new 'truncate' parameter in 
  my_decimal_precision_to_length().
sql/item_func.cc:
  1. Use the new 'truncate' parameter in 
  my_decimal_precision_to_length().
  
  2. Do not truncate decimal precision to DECIMAL_MAX_PRECISION
  for additive expressions involving long DECIMAL constants.
  
  3. Fixed an incosistency in how DECIMAL constants and 
  expressions are handled for CREATE ... SELECT.
sql/item_func.h:
  Use the new 'truncate' parameter in 
  my_decimal_precision_to_length().
sql/item_sum.cc:
  Use the new 'truncate' parameter in 
  my_decimal_precision_to_length().
sql/my_decimal.h:
  Do not truncate precision to DECIMAL_MAX_PRECISION
  when calculating length in 
  my_decimal_precision_to_length() if 'truncate' parameter
  is FALSE.
sql/sql_select.cc:
  1. Use the new 'truncate' parameter in 
  my_decimal_precision_to_length().
  
  2. Use a more correct logic when adjusting value's length.
This commit is contained in:
Alexey Kopytov
2009-07-03 11:41:19 +04:00
parent 96c069142d
commit 096c12b2c4
9 changed files with 205 additions and 51 deletions

View File

@ -1514,10 +1514,10 @@ Warnings:
Warning 1264 Out of range value adjusted for column 'f1' at row 1
DESC t1;
Field Type Null Key Default Extra
f1 decimal(59,30) NO 0.000000000000000000000000000000
f1 decimal(65,30) NO 0.000000000000000000000000000000
SELECT f1 FROM t1;
f1
99999999999999999999999999999.999999999999999999999999999999
99999999999999999999999999999999999.999999999999999999999999999999
DROP TABLE t1;
select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
1.01500000 * 1.01500000 * 0.99500000);
@ -1539,4 +1539,57 @@ select * from t1;
5.05 / 0.014
360.714286
DROP TABLE t1;
#
# Bug #45262: Bad effects with CREATE TABLE and DECIMAL
#
CREATE TABLE t1 SELECT .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
my_col decimal(30,30) NO 0.000000000000000000000000000000
SELECT my_col FROM t1;
my_col
0.123456789123456789123456789123
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 + .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
my_col decimal(65,30) NO 0.000000000000000000000000000000
SELECT my_col FROM t1;
my_col
1.123456789123456789123456789123
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 * .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
my_col decimal(65,30) NO 0.000000000000000000000000000000
SELECT my_col FROM t1;
my_col
0.123456789123456789123456789123
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
my_col decimal(65,4) YES NULL
SELECT my_col FROM t1;
my_col
8.1000
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
Warnings:
Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
my_col decimal(65,30) YES NULL
SELECT my_col FROM t1;
my_col
0.012345687012345687012345687012
DROP TABLE t1;
End of 5.0 tests

View File

@ -1235,4 +1235,33 @@ show create table t1;
select * from t1;
DROP TABLE t1;
--echo #
--echo # Bug #45262: Bad effects with CREATE TABLE and DECIMAL
--echo #
CREATE TABLE t1 SELECT .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 + .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 * .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 % .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
DESCRIBE t1;
SELECT my_col FROM t1;
DROP TABLE t1;
--echo End of 5.0 tests