[MDEV-12617] CASE and CASE-alike hybrid functions do not preserve exact data types Created: 2017-04-28  Updated: 2017-05-22  Resolved: 2017-05-04

Status: Closed
Project: MariaDB Server
Component/s: OTHER
Affects Version/s: 10.1, 10.2, 10.3
Fix Version/s: 10.3.1

Type: Bug Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: datatype

Issue Links:
Blocks
blocks MDEV-4912 Data type plugin API version 1 Closed
Relates
relates to MDEV-12861 FIRST_VALUE() does not preserve the e... Closed

 Description   

This problem is repeatable with CASE, COALESCE, IF, NULLIF, LEAST, GREATEST.
This problem is not repeatable with IFNULL, which does preserve exact data types.

FLOAT is converted to DOUBLE

CREATE OR REPLACE TABLE t1 (a FLOAT(10,2));
CREATE OR REPLACE TABLE t2 AS SELECT COALESCE(a) FROM t1;
DESCRIBE t2;

+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| COALESCE(a) | double(10,2) | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+

CREATE OR REPLACE TABLE t1 (a FLOAT(10,2));
CREATE OR REPLACE TABLE t2 AS SELECT LEAST(a,a) FROM t1;
DESCRIBE t2;

+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| LEAST(a,a) | double(19,2) | YES  |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+

TINYINT is converted to INT

CREATE OR REPLACE TABLE t1 (a TINYINT(1));
CREATE OR REPLACE TABLE t2 AS SELECT COALESCE(a) FROM t1;
DESCRIBE t2;

+-------------+--------+------+-----+---------+-------+
| Field       | Type   | Null | Key | Default | Extra |
+-------------+--------+------+-----+---------+-------+
| COALESCE(a) | int(4) | YES  |     | NULL    |       |
+-------------+--------+------+-----+---------+-------+

CREATE OR REPLACE TABLE t1 (a TINYINT(1));
CREATE OR REPLACE TABLE t2 AS SELECT LEAST(a,a) FROM t1;
DESCRIBE t2;

+------------+--------+------+-----+---------+-------+
| Field      | Type   | Null | Key | Default | Extra |
+------------+--------+------+-----+---------+-------+
| LEAST(a,a) | int(4) | YES  |     | NULL    |       |
+------------+--------+------+-----+---------+-------+

UNION

Unlike hybrid functions, UNION correctly preserves the exact data types:

CREATE OR REPLACE TABLE t1 (a FLOAT(10,2));
CREATE OR REPLACE TABLE t2 AS SELECT a FROM t1 UNION SELECT a FROM t1;
DESCRIBE t2;

+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| a     | float(10,2) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

CREATE OR REPLACE TABLE t1 (a TINYINT(1));
CREATE OR REPLACE TABLE t2 AS SELECT a FROM t1 UNION SELECT a FROM t1;
DESCRIBE t2;

+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| a     | tinyint(4) | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

Hybrid functions should be fixed to preserve the exact data types, like UNION does.

Note, UNION is probably wrong with returning tinyint(4) instead of tinyint(1). But this problem will be addressed separately.



 Comments   
Comment by Oleksandr Byelkin [ 2017-05-03 ]

OK to push

Comment by Alexander Barkov [ 2017-05-04 ]

Pushed to bb-10.2.ext

Generated at Thu Feb 08 07:59:07 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.