Commit d63645c8 authored by Nisha Gopalakrishnan's avatar Nisha Gopalakrishnan

BUG#18405221: SHOW CREATE VIEW OUTPUT INCORRECT

Fix:
---
The issue reported is same as the BUG#14117018.
Hence backporting the patch from mysql-trunk
to mysql-5.5 and mysql-5.6
parent 410b1dd8
...@@ -4109,3 +4109,40 @@ DROP TABLE t1; ...@@ -4109,3 +4109,40 @@ DROP TABLE t1;
DROP DATABASE IF EXISTS nodb; DROP DATABASE IF EXISTS nodb;
CREATE VIEW nodb.a AS SELECT 1; CREATE VIEW nodb.a AS SELECT 1;
ERROR 42000: Unknown database 'nodb' ERROR 42000: Unknown database 'nodb'
#
# BUG#14117018 - MYSQL SERVER CREATES INVALID VIEW DEFINITION
# BUG#18405221 - SHOW CREATE VIEW OUTPUT INCORRECT
#
CREATE VIEW v1 AS (SELECT '' FROM DUAL);
CREATE VIEW v2 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
(SELECT '' FROM DUAL);
CREATE VIEW v3 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
(SELECT '' FROM DUAL) UNION ALL
(SELECT '' FROM DUAL);
CREATE VIEW v4 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
(SELECT '' AS col2 FROM DUAL) UNION ALL
(SELECT '' FROM DUAL);
# Name for the column in select1 is set properly with or
# without this fix.
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS (select '' AS `Name_exp_1`) latin1 latin1_swedish_ci
# Name for the column in select2 is set with this fix.
# Without this fix, name would not have set for the
# columns in select2.
SHOW CREATE VIEW v2;
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS (select 'BUG#14117018' AS `col1`) union all (select '' AS `Name_exp_2`) latin1 latin1_swedish_ci
# Name for the field item in select2 & select3 is set with this fix.
# Without this fix, name would not have set for the
# columns in select2 & select3.
SHOW CREATE VIEW v3;
View Create View character_set_client collation_connection
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS (select 'BUG#14117018' AS `col1`) union all (select '' AS `Name_exp_2`) union all (select '' AS `Name_exp_3`) latin1 latin1_swedish_ci
# Name for the field item in select3 is set with this fix.
# Without this fix, name would not have set for the
# columns in select3.
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;
...@@ -4147,6 +4147,43 @@ DROP DATABASE IF EXISTS nodb; ...@@ -4147,6 +4147,43 @@ DROP DATABASE IF EXISTS nodb;
--error ER_BAD_DB_ERROR --error ER_BAD_DB_ERROR
CREATE VIEW nodb.a AS SELECT 1; CREATE VIEW nodb.a AS SELECT 1;
--echo #
--echo # BUG#14117018 - MYSQL SERVER CREATES INVALID VIEW DEFINITION
--echo # BUG#18405221 - SHOW CREATE VIEW OUTPUT INCORRECT
--echo #
CREATE VIEW v1 AS (SELECT '' FROM DUAL);
CREATE VIEW v2 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
(SELECT '' FROM DUAL);
CREATE VIEW v3 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
(SELECT '' FROM DUAL) UNION ALL
(SELECT '' FROM DUAL);
CREATE VIEW v4 AS (SELECT 'BUG#14117018' AS col1 FROM DUAL) UNION ALL
(SELECT '' AS col2 FROM DUAL) UNION ALL
(SELECT '' FROM DUAL);
--echo # Name for the column in select1 is set properly with or
--echo # without this fix.
SHOW CREATE VIEW v1;
--echo # Name for the column in select2 is set with this fix.
--echo # Without this fix, name would not have set for the
--echo # columns in select2.
SHOW CREATE VIEW v2;
--echo # Name for the field item in select2 & select3 is set with this fix.
--echo # Without this fix, name would not have set for the
--echo # columns in select2 & select3.
SHOW CREATE VIEW v3;
--echo # Name for the field item in select3 is set with this fix.
--echo # Without this fix, name would not have set for the
--echo # columns in select3.
SHOW CREATE VIEW v4;
DROP VIEW v1, v2, v3, v4;
# Check that all connections opened by test cases in this file are really # 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. # gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
/* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
...@@ -163,27 +163,61 @@ err: ...@@ -163,27 +163,61 @@ err:
Check if auto generated column names are conforming and Check if auto generated column names are conforming and
possibly generate a conforming name for them if not. possibly generate a conforming name for them if not.
@param item_list List of Items which should be checked @param lex Lex for this thread.
@retval false Operation was a success.
@retval true An error occurred.
*/ */
static void make_valid_column_names(List<Item> &item_list) static bool make_valid_column_names(LEX *lex)
{ {
Item *item; Item *item;
uint name_len; uint name_len;
List_iterator_fast<Item> it(item_list);
char buff[NAME_LEN]; char buff[NAME_LEN];
uint column_no= 1;
DBUG_ENTER("make_valid_column_names"); DBUG_ENTER("make_valid_column_names");
for (uint column_no= 1; (item= it++); column_no++) for (SELECT_LEX *sl= &lex->select_lex; sl; sl= sl->next_select())
{ {
if (!item->is_autogenerated_name || !check_column_name(item->name)) for (List_iterator_fast<Item> it(sl->item_list); (item= it++); column_no++)
continue; {
name_len= my_snprintf(buff, NAME_LEN, "Name_exp_%u", column_no); if (!item->is_autogenerated_name || !check_column_name(item->name))
item->orig_name= item->name; continue;
item->set_name(buff, name_len, system_charset_info); name_len= my_snprintf(buff, NAME_LEN, "Name_exp_%u", column_no);
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_VOID_RETURN; DBUG_RETURN(false);
} }
...@@ -590,9 +624,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, ...@@ -590,9 +624,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
} }
/* Check if the auto generated column names are conforming. */ /* Check if the auto generated column names are conforming. */
make_valid_column_names(select_lex->item_list); if (make_valid_column_names(lex))
if (check_duplicate_names(select_lex->item_list, 1))
{ {
res= TRUE; res= TRUE;
goto err; goto err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment