Commit b5380e09 authored by Nisha Gopalakrishnan's avatar Nisha Gopalakrishnan

BUG#19886430: VIEW CREATION WITH NAMED COLUMNS, OVER UNION,

              IS REJECTED.

Analysis
========

View creation with named columns over UNION is rejected.
Consider the following view definition:

CREATE VIEW v1 (fld1, fld2) AS SELECT 1 AS a, 2 AS b
UNION ALL SELECT 1 AS a, 1 AS a;

A 'duplicate column' error was reported due to the duplicate
alias name in the secondary SELECT. The VIEW column names
are either explicitly specified or determined from the
first SELECT (which can be auto generated if not specified).
Since a duplicate column name check was performed even
for the secondary SELECTs, an error was reported.

Fix
====

Check for duplicate column names only for the named
columns if specified or only for the first SELECT.
parent 888fabd6
......@@ -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;
......@@ -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
/* 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;
......
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