[MDEV-17325] NULL-ability problems with LEAST() in combination with NO_ZERO_DATE and NO_ZERO_IN_DATE Created: 2018-09-28  Updated: 2019-08-05  Resolved: 2018-10-01

Status: Closed
Project: MariaDB Server
Component/s: Data types, Temporal Types
Affects Version/s: 10.0, 10.1, 10.2, 10.3, 10.4
Fix Version/s: 10.4.0

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

Issue Links:
Blocks
blocks MDEV-4912 Data type plugin API version 1 Closed
Duplicate
is duplicated by MDEV-18456 Assertion `item->maybe_null' failed i... Closed
Relates
relates to MDEV-16991 Rounding vs truncation for TIME, DATE... Closed
relates to MDEV-17299 Assertion `maybe_null' failed in mak... Closed

 Description   

I start ``mysql --column-type-info test'' and run the following script:

SET sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE';
SELECT
  LEAST('0000-00-00',DATE'2001-01-01') AS c1,
  LEAST('0001-00-01',DATE'2001-01-01') AS c2;

It returns the following metadata and results::

Field   1:  `c1`
Catalog:    `def`
Database:   ``
Table:      ``
Org_table:  ``
Type:       DATE
Collation:  binary (63)
Length:     10
Max_length: 0
Decimals:   0
Flags:      NOT_NULL BINARY 
 
Field   2:  `c2`
Catalog:    `def`
Database:   ``
Table:      ``
Org_table:  ``
Type:       DATE
Collation:  binary (63)
Length:     10
Max_length: 0
Decimals:   0
Flags:      NOT_NULL BINARY 

+----+----+
| c1 | c2 |
+----+----+
| NULL | NULL |
+----+----+
1 row in set, 4 warnings (0.00 sec)

Notice, metadata says the columns are NOT_NULL, but the result is NULL for both columns. Additionally, the result table is not well-formatted.

Now if I run this script:

SET sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE';
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 AS SELECT
  LEAST('0000-00-00',DATE'2001-01-01') AS c1,
  LEAST('0001-00-01',DATE'2001-01-01') AS c2;
SELECT * FROM t1;

+------------+------------+
| c1         | c2         |
+------------+------------+
| 0000-00-00 | 0000-00-00 |
+------------+------------+

it wrote two zero dates into the table instead of two NULLs.

SHOW tells that columns were created with the "NOT NULL" attribute:

SHOW CREATE TABLE t1;

+-------+-------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                          |
+-------+-------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `c1` date NOT NULL,
  `c2` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------+

Looks wrong. Columns should be NULL-able.

The same problem is repeatable with a mixture of integer and date:

SET sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE';
SELECT
  LEAST(0,DATE'2001-01-01') AS c1,
  LEAST(20010001,DATE'2001-01-01') AS c2;

+----+----+
| c1 | c2 |
+----+----+
| NULL | NULL |
+----+----+

SET sql_mode='NO_ZERO_DATE,NO_ZERO_IN_DATE';
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 AS SELECT
  LEAST(0,DATE'2001-01-01') AS c1,
  LEAST(20010001,DATE'2001-01-01') AS c2;
SELECT * FROM t1;

+------------+------------+
| c1         | c2         |
+------------+------------+
| 0000-00-00 | 0000-00-00 | <-- expect NULLs here
+------------+------------+

SHOW CREATE TABLE t1;

+-------+-------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                          |
+-------+-------------------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `c1` date NOT NULL,
  `c2` date NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------+

Expect NULL-able columns.

The same problem is repeatable with a mixture of integer and time:

SET sql_mode='';
SELECT LEAST(999,TIME'10:20:30') AS c1;

+----+
| c1 |
+----+
| NULL |
+----+

SET sql_mode='';
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 AS SELECT LEAST(999,TIME'10:20:30') AS c1;
SELECT * FROM t1;

+----------+
| c1       |
+----------+
| 00:00:00 |
+----------+

Expect NULL.

SHOW CREATE TABLE t1;

+-------+---------------------------------------------------------------------------------+
| Table | Create Table                                                                    |
+-------+---------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `c1` time NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+---------------------------------------------------------------------------------+

Expect a NULL-able column.


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