From: Date: June 19 2005 11:25pm Subject: bk commit into 5.0 tree (bell:1.1958) BUG#7448 List-Archive: http://lists.mysql.com/internals/26164 X-Bug: 7448 Message-Id: <20050619212531.E18B1455D84@sanja.is.com.ua> Below is the list of changes that have just been committed into a local 5.0 repository of bell. When bell does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.1958 05/06/20 00:25:24 bell@stripped +8 -0 fixed view fields names check and generation (BUG#7448) sql/sql_yacc.yy 1.400 05/06/20 00:25:19 bell@stripped +6 -5 add flag indicates that name of item was auto-generated and so can be changed in view sql/sql_view.cc 1.48 05/06/20 00:25:19 bell@stripped +54 -4 fixed view field dublicates check: 1) used case system charset/collation to compare view filds 2) in case if duplicate field was auto-generated we build unique name sql/sql_show.cc 1.253 05/06/20 00:25:19 bell@stripped +9 -9 add flag indicates that name of item was auto-generated and so can be changed in view sql/item_func.cc 1.223 05/06/20 00:25:19 bell@stripped +3 -2 add flag indicates that name of item was auto-generated and so can be changed in view sql/item.h 1.141 05/06/20 00:25:19 bell@stripped +8 -5 add flag indicates that name of item was auto-generated and so can be changed in view sql/item.cc 1.137 05/06/20 00:25:19 bell@stripped +4 -2 add flag indicates that name of item was auto-generated and so can be changed in view mysql-test/t/view.test 1.72 05/06/20 00:25:19 bell@stripped +41 -0 test of view field names generation mysql-test/r/view.result 1.83 05/06/20 00:25:19 bell@stripped +43 -0 test of view field names generation # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: bell # Host: sanja.is.com.ua # Root: /home/bell/mysql/bk/work-bug4-5.0 --- 1.136/sql/item.cc Wed Jun 15 16:58:52 2005 +++ 1.137/sql/item.cc Mon Jun 20 00:25:19 2005 @@ -314,7 +314,7 @@ Item::Item(): rsize(0), name(0), orig_name(0), name_length(0), fixed(0), - collation(&my_charset_bin, DERIVATION_COERCIBLE) + autogenerated_name(TRUE), collation(&my_charset_bin, DERIVATION_COERCIBLE) { marker= 0; maybe_null=null_value=with_sum_func=unsigned_flag=0; @@ -544,8 +544,10 @@ } -void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) +void Item::set_name(const char *str, uint length, CHARSET_INFO *cs, + bool generated) { + autogenerated_name= generated; if (!length) { /* Empty string, used by AS or internal function like last_insert_id() */ --- 1.140/sql/item.h Fri Jun 17 20:30:06 2005 +++ 1.141/sql/item.h Mon Jun 20 00:25:19 2005 @@ -269,6 +269,8 @@ my_bool unsigned_flag; my_bool with_sum_func; my_bool fixed; /* If item fixed with fix_fields */ + my_bool 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 @@ -288,7 +290,8 @@ name=0; #endif } /*lint -e1509 */ - void set_name(const char *str,uint length, CHARSET_INFO *cs); + void set_name(const char *str, uint length, CHARSET_INFO *cs, + bool generated); void rename(char *new_name); void init_make_field(Send_field *tmp_field,enum enum_field_types type); virtual void cleanup(); @@ -642,9 +645,9 @@ Item *it= this_item(); if (name) - it->set_name(name, (uint) strlen(name), system_charset_info); + it->set_name(name, (uint) strlen(name), system_charset_info, TRUE); else - it->set_name(m_name.str, m_name.length, system_charset_info); + it->set_name(m_name.str, m_name.length, system_charset_info, TRUE); it->make_field(field); } @@ -1159,7 +1162,7 @@ divide the max_length with mbmaxlen). */ max_length= str_value.numchars()*cs->mbmaxlen; - set_name(str, length, cs); + set_name(str, length, cs, TRUE); decimals=NOT_FIXED_DEC; // it is constant => can be used without fix_fields (and frequently used) fixed= 1; @@ -1170,7 +1173,7 @@ collation.set(cs, dv); str_value.set_or_copy_aligned(str,length,cs); max_length= str_value.numchars()*cs->mbmaxlen; - set_name(name_par,0,cs); + set_name(name_par, 0, cs, TRUE); decimals=NOT_FIXED_DEC; // it is constant => can be used without fix_fields (and frequently used) fixed= 1; --- 1.222/sql/item_func.cc Fri Jun 17 20:30:06 2005 +++ 1.223/sql/item_func.cc Mon Jun 20 00:25:19 2005 @@ -4601,7 +4601,7 @@ pos+= base_name->length; // set_name() will allocate the name - item->set_name(buff,(uint) (pos-buff), system_charset_info); + item->set_name(buff,(uint) (pos-buff), system_charset_info, TRUE); return item; } @@ -4620,7 +4620,8 @@ if (!(item=var->item(thd, var_type, &null_lex_string))) return 0; // Impossible thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT); - item->set_name(item_name, 0, system_charset_info); // Will use original name + item->set_name(item_name, 0, system_charset_info, + TRUE); // Will use original name return item; } --- 1.252/sql/sql_show.cc Thu Jun 16 11:27:17 2005 +++ 1.253/sql/sql_show.cc Mon Jun 20 00:25:19 2005 @@ -3197,7 +3197,7 @@ } item->max_length= fields_info->field_length * cs->mbmaxlen; item->set_name(fields_info->field_name, - strlen(fields_info->field_name), cs); + strlen(fields_info->field_name), cs, TRUE); break; } field_list.push_back(item); @@ -3249,7 +3249,7 @@ { field->set_name(field_info->old_name, strlen(field_info->old_name), - system_charset_info); + system_charset_info, TRUE); if (add_item_to_list(thd, field)) return 1; } @@ -3280,7 +3280,7 @@ buffer.append(lex->wild->ptr()); buffer.append(")"); } - field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + field->set_name(buffer.ptr(), buffer.length(), system_charset_info, TRUE); } return 0; } @@ -3305,16 +3305,16 @@ Item_field *field= new Item_field(NullS, NullS, field_info->field_name); if (add_item_to_list(thd, field)) return 1; - field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + field->set_name(buffer.ptr(), buffer.length(), system_charset_info, TRUE); if (thd->lex->verbose) { - field->set_name(buffer.ptr(), buffer.length(), system_charset_info); + field->set_name(buffer.ptr(), buffer.length(), system_charset_info, TRUE); field_info= &schema_table->fields_info[3]; field= new Item_field(NullS, NullS, field_info->field_name); if (add_item_to_list(thd, field)) return 1; field->set_name(field_info->old_name, strlen(field_info->old_name), - system_charset_info); + system_charset_info, TRUE); } return 0; } @@ -3337,7 +3337,7 @@ { field->set_name(field_info->old_name, strlen(field_info->old_name), - system_charset_info); + system_charset_info, TRUE); if (add_item_to_list(thd, field)) return 1; } @@ -3359,7 +3359,7 @@ { field->set_name(field_info->old_name, strlen(field_info->old_name), - system_charset_info); + system_charset_info, TRUE); if (add_item_to_list(thd, field)) return 1; } @@ -3381,7 +3381,7 @@ { field->set_name(field_info->old_name, strlen(field_info->old_name), - system_charset_info); + system_charset_info, TRUE); if (add_item_to_list(thd, field)) return 1; } --- 1.399/sql/sql_yacc.yy Fri Jun 17 22:27:21 2005 +++ 1.400/sql/sql_yacc.yy Mon Jun 20 00:25:19 2005 @@ -4107,12 +4107,12 @@ if (add_item_to_list(YYTHD, $2)) YYABORT; if ($4.str) - $2->set_name($4.str,$4.length,system_charset_info); + $2->set_name($4.str, $4.length, system_charset_info, FALSE); else if (!$2->name) { char *str = $1; if (str[-1] == '`') str--; - $2->set_name(str,(uint) ($3 - str), YYTHD->charset()); + $2->set_name(str,(uint) ($3 - str), YYTHD->charset(), TRUE); } }; @@ -4913,9 +4913,9 @@ remember_name expr remember_end select_alias { if ($4.str) - $2->set_name($4.str,$4.length,system_charset_info); + $2->set_name($4.str, $4.length, system_charset_info, FALSE); else - $2->set_name($1,(uint) ($3 - $1), YYTHD->charset()); + $2->set_name($1, (uint) ($3 - $1), YYTHD->charset(), TRUE); $$= $2; } ; @@ -5691,7 +5691,8 @@ if (add_proc_to_list(lex->thd, $2)) YYABORT; if (!$2->name) - $2->set_name($1,(uint) ((char*) lex->tok_end - $1), YYTHD->charset()); + $2->set_name($1,(uint) ((char*) lex->tok_end - $1), + YYTHD->charset(), TRUE); } ; --- 1.82/mysql-test/r/view.result Fri Jun 17 17:27:42 2005 +++ 1.83/mysql-test/r/view.result Mon Jun 20 00:25:19 2005 @@ -1743,3 +1743,46 @@ 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; +s1 My_exp_s1 +drop view v1; +create view v1 as select 's1', s1, 1 as My_exp_s1 from t1; +select * from v1; +s1 My_exp_1_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 s1 My_exp_1_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; +drop table t1; +create view v1(k, K) as select 1,2; +ERROR 42S21: Duplicate column name 'K' --- 1.71/mysql-test/t/view.test Fri Jun 17 17:27:42 2005 +++ 1.72/mysql-test/t/view.test Mon Jun 20 00:25:19 2005 @@ -1587,3 +1587,44 @@ 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; +drop table t1; +# set names differ by case only +-- error 1060 +create view v1(k, K) as select 1,2; --- 1.47/sql/sql_view.cc Wed Jun 15 20:58:23 2005 +++ 1.48/sql/sql_view.cc Mon Jun 20 00:25:19 2005 @@ -35,6 +35,49 @@ }; +static void make_unique_view_name(Item *target, + List &item_list, + Item *last_element) +{ + int name_len; + char buff[NAME_LEN+1]; + bool attempt= 0; + for (;; attempt++) + { + Item *check; + List_iterator_fast itc(item_list); + bool ok= TRUE; + + if (attempt) + name_len= my_snprintf(buff, NAME_LEN, "My_exp_%d_%s", + attempt, + (target->orig_name ? + target->orig_name : + target->name)); + else + name_len= my_snprintf(buff, NAME_LEN, "My_exp_%s", + (target->orig_name ? + target->orig_name : + target->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, TRUE); +} + /* Creating/altering VIEW procedure @@ -240,7 +283,7 @@ goto err; } while ((item= it++, name= nm++)) - item->set_name(name->str, name->length, system_charset_info); + item->set_name(name->str, name->length, system_charset_info, FALSE); } /* Test absence of duplicates names */ @@ -254,10 +297,17 @@ List_iterator_fast itc(select_lex->item_list); 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->autogenerated_name) + make_unique_view_name(item, select_lex->item_list, item); + else if (check->autogenerated_name) + make_unique_view_name(check, select_lex->item_list, item); + else + { + my_error(ER_DUP_FIELDNAME, MYF(0), item->name); + DBUG_RETURN(TRUE); + } } } }