Commit e463ee94 authored by unknown's avatar unknown
Browse files

Bug#20404: SHOW CREATE TABLE fails with Turkish I

  
  Problem: SHOW CREATE TABLE printed garbage in table
  name for tables having TURKISH I
  (i.e. LATIN CAPITABLE LETTER I WITH DOT ABOVE)
  when lower-case-table-name=1.
  
  Reason: In some cases during lower/upper conversion in utf8,
  the result string can be shorter the original string
  (including the above letter). Old implementation of caseup_str()
  and casedn_str() didn't handle the result length properly,
  assuming that length cannot change.
  
  This fix changes the result type of cs->cset->casedn_str()
  and cs->cset->caseup_str() from VOID to UINT, to return
  the result length, as well as put '\0' terminator on a 
  proper place.
  
  Also, my_caseup_str_utf8() and my_casedn_str_utf8() were 
  rewritten not to use strlen() for performance purposes.
  It was done with help of adding of new functions - my_utf8_uni_no_range()
  and my_uni_utf8_no_range() - for null terminated strings.



include/m_ctype.h:
  Changeing return type from void to int for caseup_str() and casedn_str()
mysql-test/r/lowercase_table.result:
  Adding test case
mysql-test/t/lowercase_table.test:
  Adding test case
sql/sql_parse.cc:
  Set table->table.length to result of my_casedn_str().
strings/ctype-bin.c:
  Changeing return type from void to int for caseup_str() and casedn_str()
strings/ctype-mb.c:
  Changeing return type from void to int for caseup_str() and casedn_str()
strings/ctype-simple.c:
  Changeing return type from void to int for caseup_str() and casedn_str()
strings/ctype-ucs2.c:
  Changeing return type from void to int for caseup_str() and casedn_str()
strings/ctype-utf8.c:
  Changeing return type from void to int for caseup_str() and casedn_str().
      Optimization, to get rid of strlen():
      Adding my_utf8_uni_no_range() and my_uni_utf8_no_range() - for null
      terninated strings.
parent 4453dc48
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -178,8 +178,8 @@ typedef struct my_charset_handler_st
	       unsigned char *s,unsigned char *e);
  
  /* Functions for case and sort convertion */
  void    (*caseup_str)(struct charset_info_st *, char *);
  void    (*casedn_str)(struct charset_info_st *, char *);
  uint    (*caseup_str)(struct charset_info_st *, char *);
  uint    (*casedn_str)(struct charset_info_st *, char *);
  uint    (*caseup)(struct charset_info_st *, char *src, uint srclen,
                                              char *dst, uint dstlen);
  uint    (*casedn)(struct charset_info_st *, char *src, uint srclen,
@@ -311,8 +311,8 @@ extern uint my_instr_simple(struct charset_info_st *,


/* Functions for 8bit */
extern void my_caseup_str_8bit(CHARSET_INFO *, char *);
extern void my_casedn_str_8bit(CHARSET_INFO *, char *);
extern uint my_caseup_str_8bit(CHARSET_INFO *, char *);
extern uint my_casedn_str_8bit(CHARSET_INFO *, char *);
extern uint my_caseup_8bit(CHARSET_INFO *, char *src, uint srclen,
                                           char *dst, uint dstlen);
extern uint my_casedn_8bit(CHARSET_INFO *, char *src, uint srclen,
@@ -399,8 +399,8 @@ int my_mbcharlen_8bit(CHARSET_INFO *, uint c);


/* Functions for multibyte charsets */
extern void my_caseup_str_mb(CHARSET_INFO *, char *);
extern void my_casedn_str_mb(CHARSET_INFO *, char *);
extern uint my_caseup_str_mb(CHARSET_INFO *, char *);
extern uint my_casedn_str_mb(CHARSET_INFO *, char *);
extern uint my_caseup_mb(CHARSET_INFO *, char *src, uint srclen,
                                         char *dst, uint dstlen);
extern uint my_casedn_mb(CHARSET_INFO *, char *src, uint srclen,
+24 −0
Original line number Diff line number Diff line
@@ -84,3 +84,27 @@ create table t2 like T1;
drop table t1, t2;
show tables;
Tables_in_test
set names utf8;
drop table if exists İ,İİ;
create table İ (s1 int);
show create table İ;
Table	Create Table
İ	CREATE TABLE `i` (
  `s1` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show tables;
Tables_in_test
i
drop table İ;
create table İİ (s1 int);
show create table İİ;
Table	Create Table
İİ	CREATE TABLE `ii` (
  `s1` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show tables;
Tables_in_test
ii
drop table İİ;
set names latin1;
End of 5.0 tests
+20 −0
Original line number Diff line number Diff line
@@ -85,3 +85,23 @@ drop table t1, t2;
show tables;

# End of 4.1 tests


#
# Bug#20404: SHOW CREATE TABLE fails with Turkish I
#
set names utf8;
--disable_warnings
drop table if exists İ,İİ;
--enable_warnings
create table İ (s1 int);
show create table İ;
show tables;
drop table İ;
create table İİ (s1 int);
show create table İİ;
show tables;
drop table İİ;
set names latin1;

--echo End of 5.0 tests
+1 −1
Original line number Diff line number Diff line
@@ -6177,7 +6177,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,

  ptr->alias= alias_str;
  if (lower_case_table_names && table->table.length)
    my_casedn_str(files_charset_info, table->table.str);
    table->table.length= my_casedn_str(files_charset_info, table->table.str);
  ptr->table_name=table->table.str;
  ptr->table_name_length=table->table.length;
  ptr->lock_type=   lock_type;
+2 −1
Original line number Diff line number Diff line
@@ -211,9 +211,10 @@ static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),

/* This function is used for all conversion functions */

static void my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)),
static uint my_case_str_bin(CHARSET_INFO *cs __attribute__((unused)),
			    char *str __attribute__((unused)))
{
  return 0;
}

static uint my_case_bin(CHARSET_INFO *cs __attribute__((unused)),
Loading