Bug #116974 SHOW CREATE VIEW produces invalid view if view contains CTE w/ an unaliased window function column
Description:
If you create view that contains a CTE, and the CTE SELECTs an unnamed/unaliased window function as a column, the creation of this view will succeed. However, if you run SHOW CREATE VIEW against the view, mysql will generate an invalid CREATE VIEW statement.
Mysql generates a column name for the window function, but this column name is invalid. e.g. with the following view:
CREATE VIEW invalid_view AS
WITH test_cte (col1) AS (
SELECT
RANK() OVER (
PARTITION BY id
ORDER BY id ASC
)
FROM test_table
)
SELECT * FROM test_cte
;
mysql will generate the following invalid view via SHOW CREATE VIEW:
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `invalid_view` AS with `test_cte` (`col1`) as (select rank() OVER (PARTITION BY `test_table`.`id` ORDER BY `test_table`.`id` ) AS `RANK() OVER (
PARTITION BY id
ORDER BY id ASC
)` from `test_table`) select `test_cte`.`col1` AS `col1` from `test_cte`
This error can result in silent failures that break backup/restore processes, etc.
How to repeat:
CREATE DATABASE test;
USE test;
-- Copy, paste, and execute results of SHOW CREATE VIEW here.
-- You can see that valid_view can be recreated from SHOW CREATE VIEW results
-- Moving on to invalid SHOW CREATE VIEW results
CREATE VIEW invalid_view AS
WITH test_cte (col1) AS (
SELECT
RANK() OVER (
PARTITION BY id
ORDER BY id ASC
)
FROM test_table
)
SELECT * FROM test_cte
;
SHOW CREATE VIEW invalid_view;
DROP VIEW invalid_view;
-- Copy, paste, and execute results of SHOW CREATE VIEW here.
-- You can see that invalid_view CANNOT be recreated from SHOW CREATE VIEW results
-- Moving onto workaround example
CREATE VIEW workaround_view AS
WITH test_cte AS (
SELECT
RANK() OVER (
PARTITION BY id
ORDER BY id ASC
) AS forced_name
FROM test_table
)
SELECT * FROM test_cte
;
SHOW CREATE VIEW workaround_view;
DROP VIEW workaround_view;
-- Copy, paste, and execute results of SHOW CREATE VIEW here.
-- You can see that workaround_view can be recreated from SHOW CREATE VIEW results
-- Giving the window function a column alias prevents mysql from generating a
-- column alias that is derived from the window function
-- However, the workaround only works if the column alias is at the SELECT-level
-- within the CTE. If the name is given as an argument to the CTE, then
-- SHOW CREATE VIEW fails:
CREATE VIEW invalid_workaround_view AS
WITH test_cte (forced_name) AS (
SELECT
RANK() OVER (
PARTITION BY id
ORDER BY id ASC
)
FROM test_table
)
SELECT * FROM test_cte
;
SHOW CREATE VIEW invalid_workaround_view;
DROP VIEW invalid_workaround_view;
-- Copy, paste, and execute results of SHOW CREATE VIEW here.
-- Result will fail
-- The issue seems specifically related to window functions because regular
-- functions with unaliased CTE columns will work just fine:
CREATE VIEW valid_view AS
WITH test_cte (col1) AS (
SELECT
LEFT(
'long text',
4
)
FROM test_table
)
SELECT * FROM test_cte
;
SHOW CREATE VIEW valid_view;
DROP VIEW valid_view;
-- Copy, paste, and execute results of SHOW CREATE VIEW here.
-- Result will succeed
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.039 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: If you create view that contains a CTE, and the CTE SELECTs an unnamed/unaliased window function as a column, the creation of this view will succeed. However, if you run SHOW CREATE VIEW against the view, mysql will generate an invalid CREATE VIEW statement. Mysql generates a column name for the window function, but this column name is invalid. e.g. with the following view: CREATE VIEW invalid_view AS WITH test_cte (col1) AS ( SELECT RANK() OVER ( PARTITION BY id ORDER BY id ASC ) FROM test_table ) SELECT * FROM test_cte ; mysql will generate the following invalid view via SHOW CREATE VIEW: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `invalid_view` AS with `test_cte` (`col1`) as (select rank() OVER (PARTITION BY `test_table`.`id` ORDER BY `test_table`.`id` ) AS `RANK() OVER ( PARTITION BY id ORDER BY id ASC )` from `test_table`) select `test_cte`.`col1` AS `col1` from `test_cte` This error can result in silent failures that break backup/restore processes, etc. How to repeat: CREATE DATABASE test; USE test; -- Copy, paste, and execute results of SHOW CREATE VIEW here. -- You can see that valid_view can be recreated from SHOW CREATE VIEW results -- Moving on to invalid SHOW CREATE VIEW results CREATE VIEW invalid_view AS WITH test_cte (col1) AS ( SELECT RANK() OVER ( PARTITION BY id ORDER BY id ASC ) FROM test_table ) SELECT * FROM test_cte ; SHOW CREATE VIEW invalid_view; DROP VIEW invalid_view; -- Copy, paste, and execute results of SHOW CREATE VIEW here. -- You can see that invalid_view CANNOT be recreated from SHOW CREATE VIEW results -- Moving onto workaround example CREATE VIEW workaround_view AS WITH test_cte AS ( SELECT RANK() OVER ( PARTITION BY id ORDER BY id ASC ) AS forced_name FROM test_table ) SELECT * FROM test_cte ; SHOW CREATE VIEW workaround_view; DROP VIEW workaround_view; -- Copy, paste, and execute results of SHOW CREATE VIEW here. -- You can see that workaround_view can be recreated from SHOW CREATE VIEW results -- Giving the window function a column alias prevents mysql from generating a -- column alias that is derived from the window function -- However, the workaround only works if the column alias is at the SELECT-level -- within the CTE. If the name is given as an argument to the CTE, then -- SHOW CREATE VIEW fails: CREATE VIEW invalid_workaround_view AS WITH test_cte (forced_name) AS ( SELECT RANK() OVER ( PARTITION BY id ORDER BY id ASC ) FROM test_table ) SELECT * FROM test_cte ; SHOW CREATE VIEW invalid_workaround_view; DROP VIEW invalid_workaround_view; -- Copy, paste, and execute results of SHOW CREATE VIEW here. -- Result will fail -- The issue seems specifically related to window functions because regular -- functions with unaliased CTE columns will work just fine: CREATE VIEW valid_view AS WITH test_cte (col1) AS ( SELECT LEFT( 'long text', 4 ) FROM test_table ) SELECT * FROM test_cte ; SHOW CREATE VIEW valid_view; DROP VIEW valid_view; -- Copy, paste, and execute results of SHOW CREATE VIEW here. -- Result will succeed