List:Internals« Previous MessageNext Message »
From:sanja Date:June 19 2005 11:25pm
Subject:bk commit into 5.0 tree (bell:1.1958) BUG#7448
View as plain text  
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> &item_list,
+                                  Item *last_element)
+{
+  int name_len;
+  char buff[NAME_LEN+1];
+  bool attempt= 0;
+  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,
+                            (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<Item> 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);
+          }
         }
       }
     }
Thread
bk commit into 5.0 tree (bell:1.1958) BUG#7448sanja19 Jun