diff options
author | bell@sanja.is.com.ua <> | 2005-06-21 20:30:48 +0300 |
---|---|---|
committer | bell@sanja.is.com.ua <> | 2005-06-21 20:30:48 +0300 |
commit | a7ca9cb38eb21e098499a62033986baef7bb4131 (patch) | |
tree | 5e88fd6af3f6db63d9563fcc5bea3634320b1321 /sql/sql_view.cc | |
parent | 63a351ea4f04c4023c7fc42b6df2eb54bb0e98fb (diff) | |
download | mariadb-git-a7ca9cb38eb21e098499a62033986baef7bb4131.tar.gz |
fixed view fields names check and generation (changed after Trudy review: underlying field names treat as user set ones) (BUG#7448)
Diffstat (limited to 'sql/sql_view.cc')
-rw-r--r-- | sql/sql_view.cc | 75 |
1 files changed, 71 insertions, 4 deletions
diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 5152619fd85..0b351407c13 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -36,6 +36,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 SYNOPSIS @@ -240,24 +295,36 @@ 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) { - my_error(ER_DUP_FIELDNAME, MYF(0), item->name); - DBUG_RETURN(TRUE); + 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); + } } } } |