List:Commits« Previous MessageNext Message »
From:Sergei Golubchik Date:November 27 2008 5:08pm
Subject:Re: bzr commit into mysql-6.0-bugteam branch
(mattias.jonsson:2753) Bug#32430
View as plain text  
Hi, Mattias!

On Sep 03, Mattias Jonsson wrote:
> #At file:///Users/mattiasj/clones/bzrroot/b32430_2-60-bugteam/
> 
>  2753 Mattias Jonsson	2008-09-03
>       Bug#32430:'show innodb status' causes errors Invalid (old?) table
>       or database name in logs
>       
>       Problem was that InnoDB used filename_to_tablename,
>       which do not handle partitions (due to the '#' in
>       the filename).
>       
>       Solution is to add a new function to use to explain
>       what the filename means, explain_filename
>       It expands to Database, Table, [Temporary|Renamed] Partition,
>       Subpartition and uses errmsg.txt for localization.
>       
>       This will first go through review in Sun for the server part,
>       and if approved, go through review by Oracle/InnoBASE and if
>       approved it will then be included in both server and InnoDB.

Pretty good.
There're a few comments though, please see below
 
> === modified file 'sql/sql_table.cc'
> --- a/sql/sql_table.cc	2008-07-26 16:38:20 +0000
> +++ b/sql/sql_table.cc	2008-09-03 20:07:50 +0000
...
> +/**
> +  @brief Explain a file name by split it to [database,]tablename[,partname...] 
> +  
> +  @details Break down the filename to its logic parts and add the partname
> +  (database, table, partition, subpartition).
> +  filename_to_tablename cannot be used on partitions, due to the #P# part.
> +  There can be up to 6 '#', #P# for partition, #SP# for subpartition
> +  and #TMP# or #REN# for temporary or renamed partitions.

Please explain where this function should be used (in generating
diagnostic / error messages about something happened in a file, e.g.
read error, corruption, whatever).

> +   @param      from      The file name in my_charset_filename.
> +   @param      to        The explained name in my_charset_filename.
> +   @param      to_length size of to buffer
> +   @param      lpt       alter table data structure
> +
> +   @retval     length of returned string
> +*/
> +
> +uint explain_filename(const char *from, char *to, uint to_length)
> +{
> +  uint res= 0;
> +  char *to_p= to;
> +  char *end_p= to_p + to_length;
> +  const char *db_name= NULL;
> +  int  db_name_len= 0;
> +  const char *table_name;
> +  int  table_name_len= 0;
> +  const char *part_name= NULL;
> +  int  part_name_len= 0;
> +  const char *subpart_name= NULL;
> +  int  subpart_name_len= 0;
> +  int temp_or_renamed= 0; /* 1= temp, 2= renamed */

make it a

    enum { NORMAL, TEMP, RENAMED} status;

please

> +  const char *tmp_p;
> +  DBUG_ENTER("explain_filename");
> +  DBUG_PRINT("enter", ("from '%s'", from));
> +  /*
> +    if '/' then take last directory part as database
> +    Compose the explained name as
> +    [Database %s, ]Table %s[,[ Temporary| Renamed] Partition %s
> +    [, Subpartition %s]]
> +  */
> +  tmp_p= from;
> +  table_name= from;
> +  while ((tmp_p= strchr(tmp_p, '/')))

I'm not sure the name is normalized here, perhaps you need to use
FN_LIBCHAR and not '/'. Try it on Windows.

> +  {
> +    db_name= table_name;
> +    /* calculate the length */
> +    db_name_len= tmp_p - db_name;
> +    tmp_p++;
> +    table_name= tmp_p;
> +  }
> +  tmp_p= table_name;
> +  while (!res && (tmp_p= strchr(tmp_p, '#')))
> +  {
> +    tmp_p++;
> +    switch (tmp_p[0]) {
> +    case 'P':
> +    case 'p':
> +      if (tmp_p[1] == '#')
> +        part_name= tmp_p + 2;
> +      else
> +        res= 1;
> +      tmp_p+= 2;
> +      break;
> +    case 'S':
> +    case 's':
> +      if (tmp_p[2] == '#' && (tmp_p[1] == 'P' || tmp_p[1] == 'p'))
> +      {
> +        part_name_len= tmp_p - part_name - 1;
> +        subpart_name= tmp_p + 3;
> +      }
> +      else
> +        res= 2;
> +      tmp_p+= 3;
> +      break;
> +    case 'T':
> +    case 't':
> +      if (tmp_p[3] == '#' && (tmp_p[1] == 'M' || tmp_p[1] == 'm')
> &&
> +          (tmp_p[1] == 'P' || tmp_p[1] == 'p') && !tmp_p[4])

here, above and below - you need to make sure you don't look beyond the
end of the string, it may be unallocated memory.

So, you should always test for

      tmp_p[1] == ...
   && tmp_p[2] == ...
   && tmp_p[3] == ...
    etc

that is, do it in order, and never look at tmp_p[3] before you made sure
that tmp_p[2] and tmp_p[1] aren't '\0'.

> +        temp_or_renamed= 1; /* 1= temp, 2= renamed */
> +      else
> +        res= 3;
> +      tmp_p+= 4;
> +      break;
> +    case 'R':
> +    case 'r':
> +      if (tmp_p[3] == '#' && (tmp_p[1] == 'E' || tmp_p[1] == 'e')
> &&
> +          (tmp_p[1] == 'N' || tmp_p[1] == 'n') && !tmp_p[4])
> +        temp_or_renamed= 2; /* 1= temp, 2= renamed */

see, enums were introduced in the language exactly for this purpose :)

> +      else
> +        res= 4;
> +      tmp_p+= 4;
> +      break;

Regards / Mit vielen Grüßen,
Sergei

-- 
   __  ___     ___ ____  __
  /  |/  /_ __/ __/ __ \/ /   Sergei Golubchik <serg@stripped>
 / /|_/ / // /\ \/ /_/ / /__  Principal Software Engineer/Server Architect
/_/  /_/\_, /___/\___\_\___/  Sun Microsystems GmbH, HRB München 161028
       <___/                  Sonnenallee 1, 85551 Kirchheim-Heimstetten
Geschäftsführer: Thomas Schroeder, Wolfgang Engels, Dr. Roland Boemer
Vorsitzender des Aufsichtsrates: Martin Häring
Thread
bzr commit into mysql-6.0-bugteam branch (mattias.jonsson:2753)Bug#32430Mattias Jonsson3 Sep
  • Re: bzr commit into mysql-6.0-bugteam branch(mattias.jonsson:2753) Bug#32430Sergei Golubchik27 Nov