sql语法与mysql8兼容性

【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】进入到 TiDB Dashboard -集群信息 (Cluster Info) -主机(Hosts) 截图此页面
【附件:截图/日志/监控】

有条sql,在mysql 8 可以跑,在tidb中报错,涉及到语法兼容性问题?

WITH cte1 AS 
(
SELECT 5 AS num, 1 AS id
),
cte2 AS 
(
SELECT '*' AS op
),
cte3 AS
(
SELECT *
FROM cte1,cte2),
cte4 AS
(
SELECT a.*,t.id AS id2,t.num AS num2
FROM cte3 a
LEFT JOIN LATERAL (
SELECT *
FROM cte1 b
WHERE a.id <> b.id) AS t ON 1=1
)
,cte5 AS 
(
SELECT a.*,b.op AS op2
FROM cte4 a,cte2 b
)
,
cte6 AS(
SELECT a.*,t.id AS id3,t.num AS num3
FROM cte5 a
LEFT JOIN LATERAL (
SELECT *
FROM cte1 b
WHERE b.id <> a.id AND b.id <> a.id2) AS t ON 1=1
)
,cte7 AS 
(
SELECT a.*,b.op AS op3
FROM cte6 a,cte2 b
)
,
cte8 AS(
SELECT a.*,t.id AS id4,t.num AS num4
FROM cte7 a
LEFT JOIN LATERAL (
SELECT *
FROM cte1 b
WHERE b.id <> a.id AND b.id <> a.id2 AND b.id <> a.id3) AS t ON 1=1
)
SELECT 1;

mysql 8.0.32:

+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

tidb 7.5:

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 17 column 20 near "(

LEFT JOIN LATERAL
感觉是这个语法不支持吧~ 相关issues


https://docs.pingcap.com/zh/tidb/dev/mysql-compatibility

4 个赞

从孔大佬发的issue来看,兼容需求已经在路上了

从MySQL 8.0.14 开始,派生表支持LATERAL关键字前缀,表示允许派生表引用它所在的FROM子句中的其他表。
这个tidb没支持

LATERAL subquery 删掉后,实际上没有了 t,
but, 在 mysql中不会报错,在tidb中报错,这又是为啥呢?

mysql:

mysql> WITH cte1 AS
    -> (
    -> SELECT 5 AS num, 1 AS id
    -> ),
    -> cte2 AS
    -> (
    -> SELECT '*' AS op
    -> ),
    -> cte3 AS
    -> (
    -> SELECT *
    -> FROM cte1,cte2),
    -> cte4 AS
    -> (
    -> SELECT a.*, t.id AS id2,t.num AS num2
    -> FROM cte3 a
    -> )
    -> SELECT 1;
+---+
| 1 |
+---+
| 1 |
+---+
1 row in set (0.00 sec)

tidb:

MySQL [s1]> WITH cte1 AS
    -> (
    -> SELECT 5 AS num, 1 AS id
    -> ),
    -> cte2 AS
    -> (
    -> SELECT '*' AS op
    -> ),
    -> cte3 AS
    -> (
    -> SELECT *
    -> FROM cte1,cte2),
    -> cte4 AS
    -> (
    -> SELECT a.*, t.id AS id2,t.num AS num2
    -> FROM cte3 a
    -> )
    -> SELECT 1;
ERROR 1054 (42S22): Unknown column 't.id' in 'field list'

对啊,都没t表了,为啥mysql不报错嘞,你mysql那查下cte4看下结果

应该是mysql做了预处理,select 1不报错,select * from cte4也是报一样的错误。

WITH cte1 AS ( SELECT 5 AS num, 1 AS id )
,cte2 AS ( SELECT '*' AS op )
,cte3 AS ( SELECT * FROM cte1,cte2)
,cte4 AS ( SELECT a.*, t.id AS id2,t.num AS num2 FROM cte3 a )
SELECT * FROM cte4;

SQL 错误 [1054] [42S22]: Unknown column 't.id' in 'field list'

你的tidb集群版本是多少

目前所有发帖都会有这个版本标签。v7.5.0
image

报错是合乎逻辑的,这回应该只是mysql的问题

:yum:确实,这里应该报错。mysql这种处理机制总体来说是弊大于利的。

1 个赞

mysql下面show tables确认过吗,确认没有t表?

是的,已提bug

确认过,没有的。

可能mysql优化器改写后,把前面那些查询都忽略了

不好意思没看清楚,这个版本不是兼容mysql8了吗

是兼容了,但是mysql8后加的一些功能也在逐步实现,但也不是完全照搬,比如外键,某些sql_mode

不支持LEFT JOIN LATERAL语法

嗯,向大佬看齐

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。