使用了函数计算后,date字段返回了datetime, 同时使用了union all语法导致插入数据失败

使用了函数计算后,date字段返回了datetim, 同时使用了union all语法导致插入数据失败

【 Bug 的影响】

数据无法正常插入

【可能的问题复现步骤】
drop table if exists cux_test3;
drop table if exists cux_test4;
create table cux_test3(id bigint,rate double,date_1 date , date_2 date );
create table cux_test4(id bigint,rate double,date_1 date , date_2 date );
insert cux_test3 values
(1, 2.0, date ‘2021-01-03’, date ‘2021-02-03’)
,(2, 4.0, date ‘2021-05-23’, date ‘2021-02-02’);

– 成功
insert into cux_test4
select d1.id, d1.rate, least(d1.date_1, d1.date_2) date1, d1.date_2
from cux_test3 d1;

– 成功
insert into cux_test4
select d2.id,
d2.rate,
max(d2.date_2) over(partition by d2.id) date1,
d2.date_2
from cux_test3 d2;

– 失败
insert into cux_test4
select d1.id, d1.rate, least(d1.date_1, d1.date_2) date1, d1.date_2
from cux_test3 d1
union all
select d2.id,
d2.rate,
max(d2.date_2) over(partition by d2.id) date1,
d2.date_2
from cux_test3 d2;

– 成功
insert into cux_test4
(id)
select 1 from dual;

– 失败
insert into cux_test4
(id)
select 1
from (select d1.id,
d1.rate,
least(d1.date_1, d1.date_2) date1,
d1.date_2
from cux_test3 d1
union all
select d2.id,
d2.rate,
max(d2.date_2) over(partition by d2.id) date1,
d2.date_2
from cux_test3 d2);

【相关组件及具体版本】

tidb v5.1.1

1 个赞

这边在本地复现了这个问题,问题可能集中在 least() 函数上,后面有进展会跟进回复 ~

1 个赞

案例中的第一个失败的sql,没有使用least函数也失败了呢。
insert into cux_test4
select d1.id, d1.rate, least(d1.date_1, d1.date_2) date1, d1.date_2
from cux_test3 d1
union all
select d2.id,
d2.rate,
max(d2.date_2) over(partition by d2.id) date1,
d2.date_2
from cux_test3 d2;

1 个赞

这个 sql 看起来是包含 least() 函数的 ~

1 个赞

哦哦,不好意思看漏了

1 个赞

的确是个问题,在 MySQL 8.0 中可以成功插入 union all 的那个 SQL:

drop table if exists cux_test3;
drop table if exists cux_test4;
create table cux_test3(id bigint,rate double,date_1 date , date_2 date );
create table cux_test4(id bigint,rate double,date_1 date , date_2 date );
insert cux_test3 values
(1, 2.0, date '2021-01-03', date '2021-02-03'),
(2, 4.0, date '2021-05-23', date '2021-02-02');


insert into cux_test4
select d1.id, d1.rate, least(d1.date_1, d1.date_2) date1, d1.date_2
from cux_test3 d1
union all
select d2.id,
d2.rate,
max(d2.date_2) over(partition by d2.id) date1,
d2.date_2
from cux_test3 d2;

MySQL 8.0 版本:

MySQL 8.0(root@127.0.0.1:test) > select version();
+-----------+
| version() |
+-----------+
| 8.0.22    |
+-----------+
1 row in set (0.00 sec)

https://github.com/pingcap/tidb/pull/26533

该问题为已知问题,并在 master 分支 fix,待 cherry pick 到 4.0,5.0,5.1 版本 ~