diff options
author | evgen@moonbone.local <> | 2005-08-15 13:21:55 +0400 |
---|---|---|
committer | evgen@moonbone.local <> | 2005-08-15 13:21:55 +0400 |
commit | 5dc75a559d41358cf01d6b2a27d58c609c54febc (patch) | |
tree | 7562b2623c103e6a4bd19999af2883e2b61d8b76 | |
parent | 562786bc3649737bf43b14f5b278faa12000e7ee (diff) | |
parent | baf0c9ad084a915f785b91608ecdf0e3f0122d30 (diff) | |
download | mariadb-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.result | 7 | ||||
-rw-r--r-- | mysql-test/r/select_safe.result | 2 | ||||
-rw-r--r-- | mysql-test/t/derived.test | 11 | ||||
-rw-r--r-- | mysql-test/t/select_safe.test | 2 | ||||
-rw-r--r-- | sql/sql_derived.cc | 5 | ||||
-rw-r--r-- | sql/sql_view.cc | 96 | ||||
-rw-r--r-- | sql/sql_view.h | 2 |
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) |