diff options
author | unknown <evgen@moonbone.local> | 2005-08-10 17:45:00 +0400 |
---|---|---|
committer | unknown <evgen@moonbone.local> | 2005-08-10 17:45:00 +0400 |
commit | e66cd71698e033c788adb6364fdf261143fb5601 (patch) | |
tree | 9daa110455c864e4bfbf2f5a8c350de43a71686e /sql | |
parent | aa337b1d5e0de234458b15d4eeead1ff5df45822 (diff) | |
download | mariadb-git-e66cd71698e033c788adb6364fdf261143fb5601.tar.gz |
Fix bug #11864 non unique names are allowed in subquery
Column names weren't checked for uniqueness for subqueries.
Code for names uniqueness checking used for view creation moved into
separate function named check_duplicate_names(). It's called on
preparation of subqueries to check uniqueness of names. If duplicate names
are found then error is raised.
sql/sql_derived.cc:
Fix bug #11864 non unique names are allowed in subquery
Added check for names uniqueness in select list.
sql/sql_view.cc:
Fix bug #11864 non unique names are allowed in subquery
Code for checking uniqueness of names in item list moved into separate function to make in available for use from other places.
sql/sql_view.h:
Fix bug #11864 non unique names are allowed in subquery
Added check_duplicate_names() function prototype.
mysql-test/t/derived.test:
Fixed test case results after bug fix #11864
Added test case for bug#11864 non unique names are allowed in subquery.
mysql-test/t/select_safe.test:
Fixed test case results after bug fix #11864
mysql-test/r/derived.result:
Added test case for bug #11864 non unique names are allowed in subquery.
Fixed test case results after bug fix #11864
mysql-test/r/select_safe.result:
Fixed test case results after bug fix #11864
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_derived.cc | 5 | ||||
-rw-r--r-- | sql/sql_view.cc | 96 | ||||
-rw-r--r-- | sql/sql_view.h | 2 |
3 files changed, 74 insertions, 29 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index fc9d15e94c4..7b9191cd841 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 aedff648e5c..ecaab9db0cd 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) |