mysqldump used to have problems generating SQL for views (see MDEV-8028). Looks like they remain for complex views involving CTE and CASE expression deeply nested in the view definition. Consider the following, purely artifical test case based on a structure of a really useful view from one of the customers:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 10.5.12-MariaDB MariaDB Server
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database db;
Query OK, 1 row affected (0.001 sec)
MariaDB [(none)]> use db;
Database changed
MariaDB [db]> create or replace view dhv as
-> (select * from (
-> with recursive h(user, hosts) as
-> (select user,
-> cast('' as char(500)) from
-> ( select user, host from mysql.user
-> ) as firstgen where user = ''
-> union all
-> select nextgen.user,
-> cast(case when parent.hosts = ''
-> then (concat ('.', cast(nextgen.host as char)))
-> else (concat(parent.hosts, '.', cast(nextgen.host as char)))
-> end as char)
-> from
-> ( select user, host from mysql.user where user != ''
-> ) as nextgen
-> inner join h as parent
-> on nextgen.user = parent.user
-> )
-> select * from h
-> ) as dt);
Query OK, 0 rows affected (0.037 sec)
Do not mind the completely stupid view definition - it's used in purpose to simplify and obfuscate the real one, so it's easy to reproduce the problem.
So, we have this stupid view with proper column names:
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`openxs`@`localhost` SQL SECURITY DEFINER VIEW `dhv` AS (select `dt`.`user` AS `user`,`dt`.`hosts` AS `hosts` from (with recursive h(`user`,`hosts`) as (select `firstgen`.`user` AS `user`,cast('' as char(500) charset utf8) AS `hosts` from (select `user`.`User` AS `user`,`user`.`Host` AS `host` from `mysql`.`user`) `firstgen` where `firstgen`.`user` = '' union all select `nextgen`.`user` AS `user`,cast(case when `parent`.`hosts` = '' then concat('.',cast(`nextgen`.`host` as char charset utf8)) else concat(`parent`.`hosts`,'.',cast(`nextgen`.`host` as char charset utf8)) end as char charset utf8) AS `cast(case when parent.hosts = ''
then (concat ('.', cast(nextgen.host as char)))
else (concat(parent.hosts, '.', cast(nextgen.host as char)))
end as char)` from ((select `user`.`User` AS `user`,`user`.`Host` AS `host` from `mysql`.`user` where `user`.`User` <> '') `nextgen` join `h` `parent` on(`nextgen`.`user` = `parent`.`user`)))select `h`.`user` AS `user`,`h`.`hosts` AS `hosts` from `h`) `dt`)
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.002 sec)
But you can already spot the problem above, see this column alias generated for some reason:
AS `cast(case when parent.hosts = ''
then (concat ('.', cast(nextgen.host as char)))
else (concat(parent.hosts, '.', cast(nextgen.host as char)))
end as char)`
Surely if we dump and try to reload, it fails:
[openxs@fc33 maria10.5]$ bin/mysqldump --socket=/tmp/mariadb.sock db > /tmp/db.sql
[openxs@fc33 maria10.5]$ vi /tmp/db.sql
[openxs@fc33 maria10.5]$ bin/mysql --socket=/tmp/mariadb.sock db < /tmp/db.sql
ERROR 1166 (42000) at line 44: Incorrect column name 'cast(case when parent.hosts = ''
then (concat ('.', cast(nextgen.host as char))) '
[openxs@fc33 maria10.5]$
It seems to be more a server problem, as we can see from SHOW CREATE VIEW. Simpler cases seems to be covered by the fix to MySQL bug #65388 we merged, but not this complex one.
MDEV-26299: Some views force server (and mysqldump) to generate invalid SQL for their definitions
Do not print illegal table field names for non-top-level SELECT list,
they will not be refered in any case but create problem for parsing
of printed result.
Oleksandr Byelkin
added a comment -
commit fcf2c5fff14875a1b9e1ac554ada95db3223a4a9 (HEAD -> bb-10.2-MDEV-26299, origin/bb-10.2-MDEV-26299)
Author: Oleksandr Byelkin <sanja@mariadb.com>
Date: Fri Oct 1 14:46:22 2021 +0200
MDEV-26299: Some views force server (and mysqldump) to generate invalid SQL for their definitions
Do not print illegal table field names for non-top-level SELECT list,
they will not be refered in any case but create problem for parsing
of printed result.
I checked if it is easy to fix automatic names, IMHO in 10.2 it can interfer with many other code including Item comparison
Oleksandr Byelkin
added a comment - I checked if it is easy to fix automatic names, IMHO in 10.2 it can interfer with many other code including Item comparison
MDEV-26299: Some views force server (and mysqldump) to generate invalid SQL for their definitions
Do not print illegal table field names for non-top-level SELECT list,
they will not be refered in any case but create problem for parsing
of printed result.
Oleksandr Byelkin
added a comment - branch bb-10.2- MDEV-26299
commit bdaf94d5a21c3a974d2c7d6d586289d4375dce92 (HEAD -> bb-10.2-MDEV-26299, origin/bb-10.2-MDEV-26299)
Author: Oleksandr Byelkin <sanja@mariadb.com>
Date: Fri Oct 1 14:46:22 2021 +0200
MDEV-26299: Some views force server (and mysqldump) to generate invalid SQL for their definitions
Do not print illegal table field names for non-top-level SELECT list,
they will not be refered in any case but create problem for parsing
of printed result.
commit fcf2c5fff14875a1b9e1ac554ada95db3223a4a9 (HEAD -> bb-10.2-MDEV-26299, origin/bb-10.2-MDEV-26299)
Author: Oleksandr Byelkin <sanja@mariadb.com>
Date: Fri Oct 1 14:46:22 2021 +0200
MDEV-26299: Some views force server (and mysqldump) to generate invalid SQL for their definitions
Do not print illegal table field names for non-top-level SELECT list,
they will not be refered in any case but create problem for parsing
of printed result.