From 1d2aeb3da2dedc81a294629b50a6f47a3b377949 Mon Sep 17 00:00:00 2001
From: Sergey Vojtovich <svoj@sun.com>
Date: Wed, 3 Mar 2010 14:49:03 +0400
Subject: BUG#48265 - MRG_MYISAM problem (works in 5.0.85, does't            
 work in 5.1.40)

MERGE engine fails to open child table from a different
database if child table/database name contains characters
that are subject for table name to filename encoding
(WL1324).

Another problem is that MERGE engine didn't properly open
child table from the same database if child table name
contains characters like '/', '#'.

The problem was that table name to file name encoding was
applied inconsistently:
* On CREATE: encode table name + database name if child
  table is in different database; do not encode table
  name if child table is in the same database;
* No decoding on open.

With this fix child table/database names are always
encoded on CREATE and decoded on open. Compatibility
with older tables preserved.

Along with this patch comes fix for SHOW CREATE TABLE,
which used to show child table/database path instead
of child table/database names.

mysql-test/r/merge.result:
  A test case for BUG#48265.
mysql-test/std_data/bug48265.frm:
  MERGE table from 5.0 to test fix for BUG#48265 compatibility.
mysql-test/t/merge.test:
  A test case for BUG#48265.
storage/myisammrg/ha_myisammrg.cc:
  On CREATE always write child table/database name encoded
  by table name to filename encoding to dot-MRG file.

  On open decode child table/database name.
  Compatibilty with previous versions preserved.

  Fixed ::append_create_info() to return child
  table/database name instead of path.
storage/myisammrg/myrg_open.c:
  Move if (has_path) branch from myrg_parent_open() to
  myisammrg_parent_open_callback. The callback function
  needs to know if child table was written along with
  database name to dot-MRG file. Needed for compatibility
  reasons.
---
 storage/myisammrg/ha_myisammrg.cc | 126 ++++++++++++++++++++++++--------------
 storage/myisammrg/myrg_open.c     |   8 ---
 2 files changed, 81 insertions(+), 53 deletions(-)

(limited to 'storage/myisammrg')

diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 8af776f5c5e..bf1b757a5c8 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -214,36 +214,14 @@ const char *ha_myisammrg::index_type(uint key_number)
 static int myisammrg_parent_open_callback(void *callback_param,
                                           const char *filename)
 {
-  ha_myisammrg  *ha_myrg;
-  TABLE         *parent;
+  ha_myisammrg  *ha_myrg= (ha_myisammrg*) callback_param;
+  TABLE         *parent= ha_myrg->table_ptr();
   TABLE_LIST    *child_l;
-  const char    *db;
-  const char    *table_name;
   size_t        dirlen;
   char          dir_path[FN_REFLEN];
+  char          name_buf[NAME_LEN];
   DBUG_ENTER("myisammrg_parent_open_callback");
 
-  /* Extract child table name and database name from filename. */
-  dirlen= dirname_length(filename);
-  if (dirlen >= FN_REFLEN)
-  {
-    /* purecov: begin inspected */
-    DBUG_PRINT("error", ("name too long: '%.64s'", filename));
-    my_errno= ENAMETOOLONG;
-    DBUG_RETURN(1);
-    /* purecov: end */
-  }
-  table_name= filename + dirlen;
-  dirlen--; /* Strip off trailing '/'. */
-  memcpy(dir_path, filename, dirlen);
-  dir_path[dirlen]= '\0';
-  db= base_name(dir_path);
-  dirlen-= db - dir_path; /* This is now the length of 'db'. */
-  DBUG_PRINT("myrg", ("open: '%s'.'%s'", db, table_name));
-
-  ha_myrg= (ha_myisammrg*) callback_param;
-  parent= ha_myrg->table_ptr();
-
   /* Get a TABLE_LIST object. */
   if (!(child_l= (TABLE_LIST*) alloc_root(&parent->mem_root,
                                           sizeof(TABLE_LIST))))
@@ -255,13 +233,69 @@ static int myisammrg_parent_open_callback(void *callback_param,
   }
   bzero((char*) child_l, sizeof(TABLE_LIST));
 
-  /* Set database (schema) name. */
-  child_l->db_length= dirlen;
-  child_l->db= strmake_root(&parent->mem_root, db, dirlen);
-  /* Set table name. */
-  child_l->table_name_length= strlen(table_name);
-  child_l->table_name= strmake_root(&parent->mem_root, table_name,
-                                    child_l->table_name_length);
+  /*
+    Depending on MySQL version, filename may be encoded by table name to
+    file name encoding or not. Always encoded if parent table is created
+    by 5.1.46+. Encoded if parent is created by 5.1.6+ and child table is
+    in different database.
+  */
+  if (!has_path(filename))
+  {
+    /* Child is in the same database as parent. */
+    child_l->db_length= parent->s->db.length;
+    child_l->db= strmake_root(&parent->mem_root, parent->s->db.str,
+                              child_l->db_length);
+    /* Child table name is encoded in parent dot-MRG starting with 5.1.46. */
+    if (parent->s->mysql_version >= 50146)
+    {
+      child_l->table_name_length= filename_to_tablename(filename, name_buf,
+                                                        sizeof(name_buf));
+      child_l->table_name= strmake_root(&parent->mem_root, name_buf,
+                                        child_l->table_name_length);
+    }
+    else
+    {
+      child_l->table_name_length= strlen(filename);
+      child_l->table_name= strmake_root(&parent->mem_root, filename,
+                                        child_l->table_name_length);
+    }
+  }
+  else
+  {
+    DBUG_ASSERT(strlen(filename) < sizeof(dir_path));
+    fn_format(dir_path, filename, "", "", 0);
+    /* Extract child table name and database name from filename. */
+    dirlen= dirname_length(dir_path);
+    /* Child db/table name is encoded in parent dot-MRG starting with 5.1.6. */
+    if (parent->s->mysql_version >= 50106)
+    {
+      child_l->table_name_length= filename_to_tablename(dir_path + dirlen,
+                                                        name_buf,
+                                                        sizeof(name_buf));
+      child_l->table_name= strmake_root(&parent->mem_root, name_buf,
+                                        child_l->table_name_length);
+      dir_path[dirlen - 1]= 0;
+      dirlen= dirname_length(dir_path);
+      child_l->db_length= filename_to_tablename(dir_path + dirlen, name_buf,
+                                                sizeof(name_buf));
+      child_l->db= strmake_root(&parent->mem_root, name_buf, child_l->db_length);
+    }
+    else
+    {
+      child_l->table_name_length= strlen(dir_path + dirlen);
+      child_l->table_name= strmake_root(&parent->mem_root, dir_path + dirlen,
+                                        child_l->table_name_length);
+      dir_path[dirlen - 1]= 0;
+      dirlen= dirname_length(dir_path);
+      child_l->db_length= strlen(dir_path + dirlen);
+      child_l->db= strmake_root(&parent->mem_root, dir_path + dirlen,
+                                child_l->db_length);
+    }
+  }
+
+  DBUG_PRINT("myrg", ("open: '%.*s'.'%.*s'", child_l->db_length, child_l->db,
+                      child_l->table_name_length, child_l->table_name));
+
   /* Convert to lowercase if required. */
   if (lower_case_table_names && child_l->table_name_length)
     child_l->table_name_length= my_casedn_str(files_charset_info,
@@ -1132,7 +1166,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
   /* Create child path names. */
   for (pos= table_names; tables; tables= tables->next_local)
   {
-    const char *table_name;
+    const char *table_name= buff;
 
     /*
       Construct the path to the MyISAM table. Try to meet two conditions:
@@ -1158,10 +1192,12 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
       as the MyISAM tables are from the same database as the MERGE table.
     */
     if ((dirname_length(buff) == dirlgt) && ! memcmp(buff, name, dirlgt))
-      table_name= tables->table_name;
-    else
-      if (! (table_name= thd->strmake(buff, length)))
-        DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
+    {
+      table_name+= dirlgt;
+      length-= dirlgt;
+    }
+    if (!(table_name= thd->strmake(table_name, length)))
+      DBUG_RETURN(HA_ERR_OUT_OF_MEM); /* purecov: inspected */
 
     *pos++= table_name;
   }
@@ -1182,7 +1218,7 @@ void ha_myisammrg::append_create_info(String *packet)
   const char *current_db;
   size_t db_length;
   THD *thd= current_thd;
-  MYRG_TABLE *open_table, *first;
+  TABLE_LIST *open_table, *first;
 
   if (file->merge_insert_method != MERGE_INSERT_DISABLED)
   {
@@ -1200,14 +1236,11 @@ void ha_myisammrg::append_create_info(String *packet)
   current_db= table->s->db.str;
   db_length=  table->s->db.length;
 
-  for (first=open_table=file->open_tables ;
-       open_table != file->end_table ;
-       open_table++)
+  for (first= open_table= table->child_l;;
+       open_table= open_table->next_global)
   {
-    LEX_STRING db, name;
-    LINT_INIT(db.str);
+    LEX_STRING db= { open_table->db, open_table->db_length };
 
-    split_file_name(open_table->table->filename, &db, &name);
     if (open_table != first)
       packet->append(',');
     /* Report database for mapped table if it isn't in current database */
@@ -1218,7 +1251,10 @@ void ha_myisammrg::append_create_info(String *packet)
       append_identifier(thd, packet, db.str, db.length);
       packet->append('.');
     }
-    append_identifier(thd, packet, name.str, name.length);
+    append_identifier(thd, packet, open_table->table_name,
+                      open_table->table_name_length);
+    if (&open_table->next_global == table->child_last_l)
+      break;
   }
   packet->append(')');
 }
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index 7b310dc2eed..5fcbe0c3297 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -311,14 +311,6 @@ MYRG_INFO *myrg_parent_open(const char *parent_name,
     if (!child_name_buff[0] || (child_name_buff[0] == '#'))
       continue;
 
-    if (!has_path(child_name_buff))
-    {
-      VOID(strmake(parent_name_buff + dir_length, child_name_buff,
-                   sizeof(parent_name_buff) - 1 - dir_length));
-      VOID(cleanup_dirname(child_name_buff, parent_name_buff));
-    }
-    else
-      fn_format(child_name_buff, child_name_buff, "", "", 0);
     DBUG_PRINT("info", ("child: '%s'", child_name_buff));
 
     /* Callback registers child with handler table. */
-- 
cgit v1.2.1


From c7fad393fd73cc941190fde1b56a2f9e68e9d132 Mon Sep 17 00:00:00 2001
From: Staale Smedseng <staale.smedseng@sun.com>
Date: Sun, 14 Mar 2010 17:01:45 +0100
Subject: Bug #49829 Many "hides virtual function" warnings with SunStudio

SunStudio compilers of late warn about methods that might hide
methods in base classes due to the use of overloading combined
with overriding. SunStudio also warns about variables defined
in local socpe or method arguments that have the same name as
a member attribute of the class.

This patch renames methods that might hide base class methods,
to make it easier both for humans and compilers to see what is
actually called. It also renames variables in local scope.


sql/field.cc:
  Local scope variable or method argument same as class
  attribute.
sql/item_cmpfunc.cc:
  Local scope variable or method argument same as class
  attribute.
sql/item_create.cc:
  Renaming base class create() to create_func().
sql/item_create.h:
  Renaming base class create() to create_func().
sql/protocol.cc:
  Local scope variable or method argument same as class
  attribute.
sql/sql_profile.cc:
  Local scope variable or method argument same as class
  attribute.
sql/sql_select.cc:
  Local scope variable or method argument same as class
  attribute.
sql/sql_yacc.yy:
  Renaming base class create() to create_func().
storage/federated/ha_federated.cc:
  Local scope variable or method argument same as class
  attribute.
storage/myisammrg/ha_myisammrg.cc:
  Local scope variable or method argument same as class
  attribute.
---
 storage/myisammrg/ha_myisammrg.cc | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

(limited to 'storage/myisammrg')

diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index bf1b757a5c8..9ccb08a8d33 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2006 MySQL AB
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -427,24 +427,24 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param)
   @detail This function initializes the MERGE storage engine structures
     and adds a child list of TABLE_LIST to the parent TABLE.
 
-  @param[in]    name            MERGE table path name
-  @param[in]    mode            read/write mode, unused
-  @param[in]    test_if_locked  open flags
+  @param[in]    name                MERGE table path name
+  @param[in]    mode                read/write mode, unused
+  @param[in]    test_if_locked_arg  open flags
 
   @return       status
-    @retval     0               OK
-    @retval     -1              Error, my_errno gives reason
+    @retval     0                   OK
+    @retval     -1                  Error, my_errno gives reason
 */
 
 int ha_myisammrg::open(const char *name, int mode __attribute__((unused)),
-                       uint test_if_locked)
+                       uint test_if_locked_arg)
 {
   DBUG_ENTER("ha_myisammrg::open");
   DBUG_PRINT("myrg", ("name: '%s'  table: 0x%lx", name, (long) table));
-  DBUG_PRINT("myrg", ("test_if_locked: %u", test_if_locked));
+  DBUG_PRINT("myrg", ("test_if_locked_arg: %u", test_if_locked_arg));
 
   /* Save for later use. */
-  this->test_if_locked= test_if_locked;
+  test_if_locked= test_if_locked_arg;
 
   /* retrieve children table list. */
   my_errno= 0;
-- 
cgit v1.2.1