|
I also attach the python script I used to test the data types returned
|
|
MariaDB [test]> SELECT COALESCE(i_id,NULL),COALESCE(i_version,1),COALESCE(active, 1) FROM test_table WHERE i_id = 596686;
|
Field 1: `COALESCE(i_id,NULL)`
|
Catalog: `def`
|
Database: ``
|
Table: ``
|
Org_table: ``
|
Type: NEWDECIMAL
|
Collation: binary (63)
|
Length: 12
|
Max_length: 6
|
Decimals: 0
|
Flags: BINARY NUM
|
|
Field 2: `COALESCE(i_version,1)`
|
Catalog: `def`
|
Database: ``
|
Table: ``
|
Org_table: ``
|
Type: LONGLONG
|
Collation: binary (63)
|
Length: 4
|
Max_length: 1
|
Decimals: 0
|
Flags: NOT_NULL BINARY NUM
|
|
Field 3: `COALESCE(active, 1)`
|
Catalog: `def`
|
Database: ``
|
Table: ``
|
Org_table: ``
|
Type: NEWDECIMAL
|
Collation: binary (63)
|
Length: 5
|
Max_length: 1
|
Decimals: 0
|
Flags: NOT_NULL BINARY NUM
|
|
+---------------------+-----------------------+---------------------+
|
| COALESCE(i_id,NULL) | COALESCE(i_version,1) | COALESCE(active, 1) |
|
+---------------------+-----------------------+---------------------+
|
| 596686 | 0 | 1 |
|
+---------------------+-----------------------+---------------------+
|
1 row in set (0.00 sec)
|
|
|
MariaDB [test]> create table t1 as select COALESCE(i_id,NULL),COALESCE(i_version,1),COALESCE(active, 1) FROM test_table WHERE i_id = 596686;
|
MariaDB [test]> show create table t1;
|
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
| Table | Create Table |
|
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
| t1 | CREATE TABLE `t1` (
|
`COALESCE(i_id,NULL)` decimal(11,0) DEFAULT NULL,
|
`COALESCE(i_version,1)` int(4) NOT NULL,
|
`COALESCE(active, 1)` decimal(4,0) NOT NULL
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
|
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
|
|
There are two ways to mix "unsigned ?int" to "signed ?int":
1. either upgrade to the next bigger INT data type
2. or use a minimal DECIMAL(N,0)
From the storage point of view, #2 is more efficient.
For example, when mixing two 4-byte INTs of different signess, unsigned INT + INT, MariaDB creates a DECIMAL(10,0) column, which:
- covers the range -2147483648..4294967295
- needs 5 bytes on disk
The approach #1 with upgrade to the next bigger xINT would create a BIGINT column, which would need 8 bytes on disk.
This is OK from the SQL standard point of view:
sql:2016, 9.5 Result of data type combinations
Syntax Rules, 3) c) If any data type in DTS is numeric, then ... 3) Otherwise, exact numeric with implementation-defined precision and with scale equal to the maximum of the scales of the data types in DTS. .
|
|
Mixing literals, like in the above examples, can be optimized.
- NULL can be completely ignored during data type detection
- Integer literals can be checked for their range. So, for example, a column of type "TINYINT UNSIGNED" mixed with the literal 1 can choose "TINYINT UNSIGNED", because it fits the literal. Only "TINYINT UNSIGNED" mixed with the literal 128 and bigger needs some data type transformation.
We are thinking of adding this kind of optimization. But it can be done in 10.3 only, which implements a more convenient way to handle data types comparing to 10.2 (and earlier versions).
|