diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index c31b4f5216b..a3adf80c096 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -4146,3 +4146,38 @@ SHOW CREATE VIEW v4; View Create View character_set_client collation_connection v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS (select 'BUG#14117018' AS `col1`) union all (select '' AS `col2`) union all (select '' AS `Name_exp_3`) latin1 latin1_swedish_ci DROP VIEW v1, v2, v3, v4; +# +# BUG#19886430: VIEW CREATION WITH NAMED COLUMNS, OVER UNION, +# IS REJECTED +# Without the patch, reports an error. +CREATE VIEW v1 (fld1, fld2) AS +SELECT 1 AS a, 2 AS b +UNION ALL +SELECT 1 AS a, 1 AS a; +# The column names are explicitly specified and not duplicates, hence +# succeeds. +CREATE VIEW v2 (fld1, fld2) AS +SELECT 1 AS a, 2 AS a +UNION ALL +SELECT 1 AS a, 1 AS a; +# The column name in the first SELECT are not duplicates, hence succeeds. +CREATE VIEW v3 AS +SELECT 1 AS a, 2 AS b +UNION ALL +SELECT 1 AS a, 1 AS a; +# Should report an error, since the explicitly specified column names are +# duplicates. +CREATE VIEW v4 (fld1, fld1) AS +SELECT 1 AS a, 2 AS b +UNION ALL +SELECT 1 AS a, 1 AS a; +ERROR 42S21: Duplicate column name 'fld1' +# Should report an error, since duplicate column name is specified in the +# First SELECT. +CREATE VIEW v4 AS +SELECT 1 AS a, 2 AS a +UNION ALL +SELECT 1 AS a, 1 AS a; +ERROR 42S21: Duplicate column name 'a' +# Cleanup +DROP VIEW v1, v2, v3; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 959153ee851..f9c305831c2 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -4184,6 +4184,50 @@ SHOW CREATE VIEW v4; DROP VIEW v1, v2, v3, v4; + +--echo # +--echo # BUG#19886430: VIEW CREATION WITH NAMED COLUMNS, OVER UNION, +--echo # IS REJECTED + +--echo # Without the patch, reports an error. +CREATE VIEW v1 (fld1, fld2) AS + SELECT 1 AS a, 2 AS b + UNION ALL + SELECT 1 AS a, 1 AS a; + +--echo # The column names are explicitly specified and not duplicates, hence +--echo # succeeds. +CREATE VIEW v2 (fld1, fld2) AS + SELECT 1 AS a, 2 AS a + UNION ALL + SELECT 1 AS a, 1 AS a; + +--echo # The column name in the first SELECT are not duplicates, hence succeeds. +CREATE VIEW v3 AS + SELECT 1 AS a, 2 AS b + UNION ALL + SELECT 1 AS a, 1 AS a; + +--echo # Should report an error, since the explicitly specified column names are +--echo # duplicates. +--error ER_DUP_FIELDNAME +CREATE VIEW v4 (fld1, fld1) AS + SELECT 1 AS a, 2 AS b + UNION ALL + SELECT 1 AS a, 1 AS a; + +--echo # Should report an error, since duplicate column name is specified in the +--echo # First SELECT. +--error ER_DUP_FIELDNAME +CREATE VIEW v4 AS + SELECT 1 AS a, 2 AS a + UNION ALL + SELECT 1 AS a, 1 AS a; + +--echo # Cleanup +DROP VIEW v1, v2, v3; + + # Check that all connections opened by test cases in this file are really # gone so execution of other tests won't be affected by their presence. --source include/wait_until_count_sessions.inc diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 6bbc475565b..18eb03da866 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -164,18 +164,14 @@ err: possibly generate a conforming name for them if not. @param lex Lex for this thread. - - @retval false Operation was a success. - @retval true An error occurred. */ -static bool make_valid_column_names(LEX *lex) +static void make_valid_column_names(LEX *lex) { Item *item; uint name_len; char buff[NAME_LEN]; uint column_no= 1; - DBUG_ENTER("make_valid_column_names"); for (SELECT_LEX *sl= &lex->select_lex; sl; sl= sl->next_select()) { @@ -187,37 +183,7 @@ static bool make_valid_column_names(LEX *lex) item->orig_name= item->name; item->set_name(buff, name_len, system_charset_info); } - - /* - There is a possibility of generating same name for column in more than - one SELECT_LEX. For Example: - - CREATE TABLE t1 (Name_exp_1 INT, Name_exp_2 INT, Name_exp_3 INT); - CREATE TABLE t2 (Name_exp_1 INT, Name_exp_2 INT, Name_exp_3 INT); - - CREATE VIEW v1 AS SELECT '', t1.Name_exp_2 AS Name_exp_2 FROM t1 - UNION - SELECT '', t2.Name_exp_1 AS Name_exp_1 from t2; - - But, column names of the first SELECT_LEX is considered - for the output. - - mysql> SELECT * FROM v1; - +------------+------------+ - | Name_exp_1 | Name_exp_2 | - +------------+------------+ - | | 2 | - | | 3 | - +------------+------------+ - - So, checking for duplicate names in only "sl", current - SELECT_LEX. - */ - if (check_duplicate_names(sl->item_list, 1)) - DBUG_RETURN(true); } - - DBUG_RETURN(false); } @@ -624,7 +590,14 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } /* Check if the auto generated column names are conforming. */ - if (make_valid_column_names(lex)) + make_valid_column_names(lex); + + /* + Only column names of the first select_lex should be checked for + duplication; any further UNION-ed part isn't used for determining + names of the view's columns. + */ + if (check_duplicate_names(select_lex->item_list, 1)) { res= TRUE; goto err;