summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorevgen@moonbone.local <>2005-08-15 13:21:55 +0400
committerevgen@moonbone.local <>2005-08-15 13:21:55 +0400
commit5dc75a559d41358cf01d6b2a27d58c609c54febc (patch)
tree7562b2623c103e6a4bd19999af2883e2b61d8b76
parent562786bc3649737bf43b14f5b278faa12000e7ee (diff)
parentbaf0c9ad084a915f785b91608ecdf0e3f0122d30 (diff)
downloadmariadb-git-5dc75a559d41358cf01d6b2a27d58c609c54febc.tar.gz
Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0
into moonbone.local:/work/mysql-5.0-bug-11864
-rw-r--r--mysql-test/r/derived.result7
-rw-r--r--mysql-test/r/select_safe.result2
-rw-r--r--mysql-test/t/derived.test11
-rw-r--r--mysql-test/t/select_safe.test2
-rw-r--r--sql/sql_derived.cc5
-rw-r--r--sql/sql_view.cc96
-rw-r--r--sql/sql_view.h2
7 files changed, 92 insertions, 33 deletions
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index 586be94301f..7c9d88acf90 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -111,7 +111,7 @@ a b
1 a
2 b
3 c
-explain select * from (select * from t1,t2 where t1.a=t2.a) t1;
+explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1
2 DERIVED t2 system NULL NULL NULL NULL 1
@@ -363,3 +363,8 @@ a
3
3
drop table t1, t2, t3;
+create table t1 (a int);
+create table t2 (a int);
+select * from (select * from t1,t2) foo;
+ERROR 42S21: Duplicate column name 'a'
+drop table t1,t2;
diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result
index 5d458c40f34..feac9efcb13 100644
--- a/mysql-test/r/select_safe.result
+++ b/mysql-test/r/select_safe.result
@@ -84,7 +84,7 @@ set local max_join_size=8;
select * from (select * from t1) x;
ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay
set local max_join_size=1;
-select * from (select * from t1 a, t1 b) x;
+select * from (select a.a as aa, b.a as ba from t1 a, t1 b) x;
ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay
set local max_join_size=1;
select * from (select 1 union select 2 union select 3) x;
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index 8d51b4666e7..f52e12849e4 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -42,7 +42,7 @@ CREATE TABLE t2 (a int not null);
insert into t2 values(1);
select * from (select * from t1 where t1.a=(select a from t2 where t2.a=t1.a)) a;
select * from (select * from t1 where t1.a=(select t2.a from t2 where t2.a=t1.a) union select t1.a, t1.b from t1) a;
-explain select * from (select * from t1,t2 where t1.a=t2.a) t1;
+explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
drop table t1, t2;
create table t1(a int not null, t char(8), index(a));
disable_query_log;
@@ -249,4 +249,13 @@ select * from t1 union distinct select * from t2 union all select * from t3;
select * from (select * from t1 union distinct select * from t2 union all select * from t3) X;
drop table t1, t2, t3;
+#
+# Bug #11864 non unique names are allowed in subquery
+#
+create table t1 (a int);
+create table t2 (a int);
+--error 1060
+select * from (select * from t1,t2) foo;
+drop table t1,t2;
+
# End of 4.1 tests
diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test
index 1da700c9adf..481779e76d7 100644
--- a/mysql-test/t/select_safe.test
+++ b/mysql-test/t/select_safe.test
@@ -78,7 +78,7 @@ select * from (select * from t1) x;
set local max_join_size=1;
--error 1104
-select * from (select * from t1 a, t1 b) x;
+select * from (select a.a as aa, b.a as ba from t1 a, t1 b) x;
set local max_join_size=1;
--error 1104
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index afcf7dbd93f..da1525fc133 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -125,6 +125,11 @@ int mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *orig_table_list)
if ((res= unit->prepare(thd, derived_result, 0, orig_table_list->alias)))
goto exit;
+ if (check_duplicate_names(unit->types, 0))
+ {
+ res= -1;
+ goto exit;
+ }
derived_result->tmp_table_param.init();
derived_result->tmp_table_param.field_count= unit->types.elements;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index c958185b622..c3222f951bb 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -94,6 +94,71 @@ static void make_unique_view_field_name(Item *target,
target->set_name(buff, name_len, system_charset_info);
}
+
+/*
+ Check if items with same names are present in list and possibly
+ generate unique names for them.
+
+ SYNOPSIS
+ item_list list of Items which should be checked for duplicates
+ gen_unique_view_name flag: generate unique name or return with error when
+ duplicate names are found.
+
+ DESCRIPTION
+ This function is used on view creation and preparation of derived tables.
+ It checks item_list for items with duplicate names. If it founds two
+ items with same name and conversion to unique names isn't allowed, or
+ names for both items are set by user - function fails.
+ Otherwise it generates unique name for one item with autogenerated name
+ using make_unique_view_field_name()
+
+ RETURN VALUE
+ FALSE no duplicate names found, or they are converted to unique ones
+ TRUE duplicate names are found and they can't be converted or conversion
+ isn't allowed
+*/
+
+bool check_duplicate_names(List<Item> &item_list, bool gen_unique_view_name)
+{
+ DBUG_ENTER("check_duplicate_names");
+ /* Test absence of duplicates names */
+ {
+ Item *item;
+ List_iterator_fast<Item> it(item_list);
+ List_iterator_fast<Item> itc(item_list);
+ while ((item= it++))
+ {
+ Item *check;
+ /* treat underlying fields like set by user names */
+ if (item->real_item()->type() == Item::FIELD_ITEM)
+ item->is_autogenerated_name= FALSE;
+ itc.rewind();
+ while ((check= itc++) && check != item)
+ {
+ if (my_strcasecmp(system_charset_info, item->name, check->name) == 0)
+ {
+ if (!gen_unique_view_name)
+ {
+ my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
+ DBUG_RETURN(TRUE);
+ }
+ else if (item->is_autogenerated_name)
+ make_unique_view_field_name(item, item_list, item);
+ else if (check->is_autogenerated_name)
+ make_unique_view_field_name(check, item_list, item);
+ else
+ {
+ my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
+ DBUG_RETURN(TRUE);
+ }
+ }
+ }
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
+
/*
Creating/altering VIEW procedure
@@ -308,35 +373,8 @@ bool mysql_create_view(THD *thd,
}
}
- /* Test absence of duplicates names */
- {
- Item *item;
- List_iterator_fast<Item> it(select_lex->item_list);
- List_iterator_fast<Item> itc(select_lex->item_list);
- while ((item= it++))
- {
- Item *check;
- /* treat underlying fields like set by user names */
- if (item->real_item()->type() == Item::FIELD_ITEM)
- item->is_autogenerated_name= FALSE;
- itc.rewind();
- while ((check= itc++) && check != item)
- {
- if (my_strcasecmp(system_charset_info, item->name, check->name) == 0)
- {
- if (item->is_autogenerated_name)
- make_unique_view_field_name(item, select_lex->item_list, item);
- else if (check->is_autogenerated_name)
- make_unique_view_field_name(check, select_lex->item_list, item);
- else
- {
- my_error(ER_DUP_FIELDNAME, MYF(0), item->name);
- DBUG_RETURN(TRUE);
- }
- }
- }
- }
- }
+ if (check_duplicate_names(select_lex->item_list, 1))
+ DBUG_RETURN(TRUE);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/*
diff --git a/sql/sql_view.h b/sql/sql_view.h
index 3246dbae383..9d961feb143 100644
--- a/sql/sql_view.h
+++ b/sql/sql_view.h
@@ -33,5 +33,7 @@ int view_checksum(THD *thd, TABLE_LIST *view);
extern TYPELIB updatable_views_with_limit_typelib;
+bool check_duplicate_names(List<Item>& item_list, bool gen_unique_view_names);
+
#define VIEW_ANY_ACL (SELECT_ACL | UPDATE_ACL | INSERT_ACL | DELETE_ACL)