Loading mysql-test/r/view.result +55 −0 Original line number Diff line number Diff line Loading @@ -1757,3 +1757,58 @@ select * from v1; cast(1 as decimal) 1.00 drop view v1; create view v1 as select '\\','\\shazam'; select * from v1; \ \shazam \ \shazam drop view v1; create view v1 as select '\'','\shazam'; select * from v1; ' shazam ' shazam drop view v1; create view v1 as select 'k','K'; select * from v1; k My_exp_K k K drop view v1; create table t1 (s1 int); create view v1 as select s1, 's1' from t1; select * from v1; s1 My_exp_s1 drop view v1; create view v1 as select 's1', s1 from t1; select * from v1; My_exp_s1 s1 drop view v1; create view v1 as select 's1', s1, 1 as My_exp_s1 from t1; select * from v1; My_exp_1_s1 s1 My_exp_s1 drop view v1; create view v1 as select 1 as My_exp_s1, 's1', s1 from t1; select * from v1; My_exp_s1 My_exp_1_s1 s1 drop view v1; create view v1 as select 1 as s1, 's1', 's1' from t1; select * from v1; s1 My_exp_s1 My_exp_1_s1 drop view v1; create view v1 as select 's1', 's1', 1 as s1 from t1; select * from v1; My_exp_1_s1 My_exp_s1 s1 drop view v1; create view v1 as select s1, 's1', 's1' from t1; select * from v1; s1 My_exp_s1 My_exp_1_s1 drop view v1; create view v1 as select 's1', 's1', s1 from t1; select * from v1; My_exp_1_s1 My_exp_s1 s1 drop view v1; create view v1 as select 1 as s1, 's1', s1 from t1; ERROR 42S21: Duplicate column name 's1' create view v1 as select 's1', s1, 1 as s1 from t1; ERROR 42S21: Duplicate column name 's1' drop table t1; create view v1(k, K) as select 1,2; ERROR 42S21: Duplicate column name 'K' mysql-test/t/view.test +53 −0 Original line number Diff line number Diff line Loading @@ -1599,3 +1599,56 @@ drop table t1; create view v1 as select cast(1 as decimal); select * from v1; drop view v1; # # Generation unique names for columns, and correct names check (BUG#7448) # # names with ' and \ create view v1 as select '\\','\\shazam'; select * from v1; drop view v1; create view v1 as select '\'','\shazam'; select * from v1; drop view v1; # autogenerated names differ by case only create view v1 as select 'k','K'; select * from v1; drop view v1; create table t1 (s1 int); # same autogenerated names create view v1 as select s1, 's1' from t1; select * from v1; drop view v1; create view v1 as select 's1', s1 from t1; select * from v1; drop view v1; # set name as one of expected autogenerated create view v1 as select 's1', s1, 1 as My_exp_s1 from t1; select * from v1; drop view v1; create view v1 as select 1 as My_exp_s1, 's1', s1 from t1; select * from v1; drop view v1; # set name conflict with autogenerated names create view v1 as select 1 as s1, 's1', 's1' from t1; select * from v1; drop view v1; create view v1 as select 's1', 's1', 1 as s1 from t1; select * from v1; drop view v1; # underlying field name conflict with autogenerated names create view v1 as select s1, 's1', 's1' from t1; select * from v1; drop view v1; create view v1 as select 's1', 's1', s1 from t1; select * from v1; drop view v1; # underlying field name conflict with set name -- error 1060 create view v1 as select 1 as s1, 's1', s1 from t1; -- error 1060 create view v1 as select 's1', s1, 1 as s1 from t1; drop table t1; # set names differ by case only -- error 1060 create view v1(k, K) as select 1,2; sql/item.cc +1 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,7 @@ void *Item::operator new(size_t size, Item *reuse, uint *rsize) Item::Item(): rsize(0), name(0), orig_name(0), name_length(0), fixed(0), is_autogenerated_name(TRUE), collation(&my_charset_bin, DERIVATION_COERCIBLE) { marker= 0; Loading sql/item.h +4 −2 Original line number Diff line number Diff line Loading @@ -269,6 +269,8 @@ class Item { my_bool unsigned_flag; my_bool with_sum_func; my_bool fixed; /* If item fixed with fix_fields */ my_bool is_autogenerated_name; /* indicate was name of this Item autogenerated or set by user */ DTCollation collation; // alloc & destruct is done as start of select using sql_alloc Loading sql/sql_view.cc +71 −4 Original line number Diff line number Diff line Loading @@ -35,6 +35,61 @@ TYPELIB updatable_views_with_limit_typelib= }; /* Make a unique name for an anonymous view column SYNOPSIS target reference to the item for which a new name has to be made item_list list of items within which we should check uniqueness of the created name last_element the last element of the list above NOTE Unique names are generated by adding 'My_exp_' to the old name of the column. In case the name that was created this way already exists, we add a numeric postfix to its end (i.e. "1") and increase the number until the name becomes unique. If the generated name is longer than NAME_LEN, it is truncated. */ static void make_unique_view_field_name(Item *target, List<Item> &item_list, Item *last_element) { char *name= (target->orig_name ? target->orig_name : target->name); uint name_len; uint attempt= 0; char buff[NAME_LEN+1]; for (;; attempt++) { Item *check; List_iterator_fast<Item> itc(item_list); bool ok= TRUE; if (attempt) name_len= my_snprintf(buff, NAME_LEN, "My_exp_%d_%s", attempt, name); else name_len= my_snprintf(buff, NAME_LEN, "My_exp_%s", name); do { check= itc++; if (check != target && my_strcasecmp(system_charset_info, buff, check->name) == 0) { ok= FALSE; break; } } while (check != last_element); if (ok) break; } target->orig_name= target->name; target->set_name(buff, name_len, system_charset_info); } /* Creating/altering VIEW procedure Loading Loading @@ -240,21 +295,32 @@ bool mysql_create_view(THD *thd, goto err; } while ((item= it++, name= nm++)) { item->set_name(name->str, name->length, system_charset_info); item->is_autogenerated_name= FALSE; } } /* Test absence of duplicates names */ { Item *item; List_iterator_fast<Item> it(select_lex->item_list); it++; while ((item= it++)) { Item *check; List_iterator_fast<Item> itc(select_lex->item_list); /* treat underlying fields like set by user names */ if (item->real_item()->type() == Item::FIELD_ITEM) item->is_autogenerated_name= FALSE; while ((check= itc++) && check != item) { if (strcmp(item->name, check->name) == 0) 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); Loading @@ -262,6 +328,7 @@ bool mysql_create_view(THD *thd, } } } } #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Loading Loading
mysql-test/r/view.result +55 −0 Original line number Diff line number Diff line Loading @@ -1757,3 +1757,58 @@ select * from v1; cast(1 as decimal) 1.00 drop view v1; create view v1 as select '\\','\\shazam'; select * from v1; \ \shazam \ \shazam drop view v1; create view v1 as select '\'','\shazam'; select * from v1; ' shazam ' shazam drop view v1; create view v1 as select 'k','K'; select * from v1; k My_exp_K k K drop view v1; create table t1 (s1 int); create view v1 as select s1, 's1' from t1; select * from v1; s1 My_exp_s1 drop view v1; create view v1 as select 's1', s1 from t1; select * from v1; My_exp_s1 s1 drop view v1; create view v1 as select 's1', s1, 1 as My_exp_s1 from t1; select * from v1; My_exp_1_s1 s1 My_exp_s1 drop view v1; create view v1 as select 1 as My_exp_s1, 's1', s1 from t1; select * from v1; My_exp_s1 My_exp_1_s1 s1 drop view v1; create view v1 as select 1 as s1, 's1', 's1' from t1; select * from v1; s1 My_exp_s1 My_exp_1_s1 drop view v1; create view v1 as select 's1', 's1', 1 as s1 from t1; select * from v1; My_exp_1_s1 My_exp_s1 s1 drop view v1; create view v1 as select s1, 's1', 's1' from t1; select * from v1; s1 My_exp_s1 My_exp_1_s1 drop view v1; create view v1 as select 's1', 's1', s1 from t1; select * from v1; My_exp_1_s1 My_exp_s1 s1 drop view v1; create view v1 as select 1 as s1, 's1', s1 from t1; ERROR 42S21: Duplicate column name 's1' create view v1 as select 's1', s1, 1 as s1 from t1; ERROR 42S21: Duplicate column name 's1' drop table t1; create view v1(k, K) as select 1,2; ERROR 42S21: Duplicate column name 'K'
mysql-test/t/view.test +53 −0 Original line number Diff line number Diff line Loading @@ -1599,3 +1599,56 @@ drop table t1; create view v1 as select cast(1 as decimal); select * from v1; drop view v1; # # Generation unique names for columns, and correct names check (BUG#7448) # # names with ' and \ create view v1 as select '\\','\\shazam'; select * from v1; drop view v1; create view v1 as select '\'','\shazam'; select * from v1; drop view v1; # autogenerated names differ by case only create view v1 as select 'k','K'; select * from v1; drop view v1; create table t1 (s1 int); # same autogenerated names create view v1 as select s1, 's1' from t1; select * from v1; drop view v1; create view v1 as select 's1', s1 from t1; select * from v1; drop view v1; # set name as one of expected autogenerated create view v1 as select 's1', s1, 1 as My_exp_s1 from t1; select * from v1; drop view v1; create view v1 as select 1 as My_exp_s1, 's1', s1 from t1; select * from v1; drop view v1; # set name conflict with autogenerated names create view v1 as select 1 as s1, 's1', 's1' from t1; select * from v1; drop view v1; create view v1 as select 's1', 's1', 1 as s1 from t1; select * from v1; drop view v1; # underlying field name conflict with autogenerated names create view v1 as select s1, 's1', 's1' from t1; select * from v1; drop view v1; create view v1 as select 's1', 's1', s1 from t1; select * from v1; drop view v1; # underlying field name conflict with set name -- error 1060 create view v1 as select 1 as s1, 's1', s1 from t1; -- error 1060 create view v1 as select 's1', s1, 1 as s1 from t1; drop table t1; # set names differ by case only -- error 1060 create view v1(k, K) as select 1,2;
sql/item.cc +1 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,7 @@ void *Item::operator new(size_t size, Item *reuse, uint *rsize) Item::Item(): rsize(0), name(0), orig_name(0), name_length(0), fixed(0), is_autogenerated_name(TRUE), collation(&my_charset_bin, DERIVATION_COERCIBLE) { marker= 0; Loading
sql/item.h +4 −2 Original line number Diff line number Diff line Loading @@ -269,6 +269,8 @@ class Item { my_bool unsigned_flag; my_bool with_sum_func; my_bool fixed; /* If item fixed with fix_fields */ my_bool is_autogenerated_name; /* indicate was name of this Item autogenerated or set by user */ DTCollation collation; // alloc & destruct is done as start of select using sql_alloc Loading
sql/sql_view.cc +71 −4 Original line number Diff line number Diff line Loading @@ -35,6 +35,61 @@ TYPELIB updatable_views_with_limit_typelib= }; /* Make a unique name for an anonymous view column SYNOPSIS target reference to the item for which a new name has to be made item_list list of items within which we should check uniqueness of the created name last_element the last element of the list above NOTE Unique names are generated by adding 'My_exp_' to the old name of the column. In case the name that was created this way already exists, we add a numeric postfix to its end (i.e. "1") and increase the number until the name becomes unique. If the generated name is longer than NAME_LEN, it is truncated. */ static void make_unique_view_field_name(Item *target, List<Item> &item_list, Item *last_element) { char *name= (target->orig_name ? target->orig_name : target->name); uint name_len; uint attempt= 0; char buff[NAME_LEN+1]; for (;; attempt++) { Item *check; List_iterator_fast<Item> itc(item_list); bool ok= TRUE; if (attempt) name_len= my_snprintf(buff, NAME_LEN, "My_exp_%d_%s", attempt, name); else name_len= my_snprintf(buff, NAME_LEN, "My_exp_%s", name); do { check= itc++; if (check != target && my_strcasecmp(system_charset_info, buff, check->name) == 0) { ok= FALSE; break; } } while (check != last_element); if (ok) break; } target->orig_name= target->name; target->set_name(buff, name_len, system_charset_info); } /* Creating/altering VIEW procedure Loading Loading @@ -240,21 +295,32 @@ bool mysql_create_view(THD *thd, goto err; } while ((item= it++, name= nm++)) { item->set_name(name->str, name->length, system_charset_info); item->is_autogenerated_name= FALSE; } } /* Test absence of duplicates names */ { Item *item; List_iterator_fast<Item> it(select_lex->item_list); it++; while ((item= it++)) { Item *check; List_iterator_fast<Item> itc(select_lex->item_list); /* treat underlying fields like set by user names */ if (item->real_item()->type() == Item::FIELD_ITEM) item->is_autogenerated_name= FALSE; while ((check= itc++) && check != item) { if (strcmp(item->name, check->name) == 0) 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); Loading @@ -262,6 +328,7 @@ bool mysql_create_view(THD *thd, } } } } #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Loading