Commit 689ee0be authored by vva@eagle.mysql.r18.ru's avatar vva@eagle.mysql.r18.ru

Merge vvagin@bk-internal.mysql.com:/home/bk/mysql-4.1

into eagle.mysql.r18.ru:/home/vva/work/BUG_2593/mysql-4.1
parents 0ac37473 50076a5d
...@@ -265,3 +265,51 @@ c decimal(4,3) YES NULL ...@@ -265,3 +265,51 @@ c decimal(4,3) YES NULL
d double(4,3) YES NULL d double(4,3) YES NULL
f float(4,3) YES NULL f float(4,3) YES NULL
drop table t1; drop table t1;
SET sql_mode='';
SET sql_quote_show_create=OFF;
CREATE TABLE ```ab``cd``` (i INT);
SHOW CREATE TABLE ```ab``cd```;
Table Create Table
`ab`cd` CREATE TABLE ```ab``cd``` (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE ```ab``cd```;
CREATE TABLE ```ab````cd``` (i INT);
SHOW CREATE TABLE ```ab````cd```;
Table Create Table
`ab``cd` CREATE TABLE ```ab````cd``` (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE ```ab````cd```;
CREATE TABLE ```a` (i INT);
SHOW CREATE TABLE ```a`;
Table Create Table
`a CREATE TABLE ```a` (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE ```a`;
SET sql_mode='ANSI_QUOTES';
CREATE TABLE """a" (i INT);
SHOW CREATE TABLE """a";
Table Create Table
"a CREATE TABLE """a" (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE """a";
SET sql_mode='';
SET sql_quote_show_create=OFF;
CREATE TABLE t1 (i INT);
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE t1 (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE `table` (i INT);
SHOW CREATE TABLE `table`;
Table Create Table
table CREATE TABLE `table` (
i int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE `table`;
SET sql_quote_show_create=ON;
...@@ -142,3 +142,43 @@ drop table t1; ...@@ -142,3 +142,43 @@ drop table t1;
create table t1 (c decimal(3,3), d double(3,3), f float(3,3)); create table t1 (c decimal(3,3), d double(3,3), f float(3,3));
show columns from t1; show columns from t1;
drop table t1; drop table t1;
#
# Test for Bug #2593 "SHOW CREATE TABLE doesn't properly double quotes"
#
SET sql_mode='';
SET sql_quote_show_create=OFF;
CREATE TABLE ```ab``cd``` (i INT);
SHOW CREATE TABLE ```ab``cd```;
DROP TABLE ```ab``cd```;
CREATE TABLE ```ab````cd``` (i INT);
SHOW CREATE TABLE ```ab````cd```;
DROP TABLE ```ab````cd```;
CREATE TABLE ```a` (i INT);
SHOW CREATE TABLE ```a`;
DROP TABLE ```a`;
SET sql_mode='ANSI_QUOTES';
CREATE TABLE """a" (i INT);
SHOW CREATE TABLE """a";
DROP TABLE """a";
# to test quotes around keywords.. :
SET sql_mode='';
SET sql_quote_show_create=OFF;
CREATE TABLE t1 (i INT);
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE `table` (i INT);
SHOW CREATE TABLE `table`;
DROP TABLE `table`;
SET sql_quote_show_create=ON;
...@@ -761,6 +761,8 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match); ...@@ -761,6 +761,8 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match);
uint check_word(TYPELIB *lib, const char *val, const char *end, uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word); const char **end_of_word);
bool is_keyword(const char *name, uint len);
/* sql_parse.cc */ /* sql_parse.cc */
void free_items(Item *item); void free_items(Item *item);
void cleanup_items(Item *item); void cleanup_items(Item *item);
......
...@@ -181,6 +181,23 @@ static int find_keyword(LEX *lex, uint len, bool function) ...@@ -181,6 +181,23 @@ static int find_keyword(LEX *lex, uint len, bool function)
return 0; return 0;
} }
/*
Check if name is a keyword
SYNOPSIS
is_keyword()
name checked name
len length of checked name
RETURN VALUES
0 name is a keyword
1 name isn't a keyword
*/
bool is_keyword(const char *name, uint len)
{
return get_hash_symbol(name,len,0)!=0;
}
/* make a copy of token before ptr and set yytoklen */ /* make a copy of token before ptr and set yytoklen */
...@@ -427,7 +444,6 @@ inline static uint int_token(const char *str,uint length) ...@@ -427,7 +444,6 @@ inline static uint int_token(const char *str,uint length)
return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger; return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
} }
/* /*
yylex remember the following states from the following yylex() yylex remember the following states from the following yylex()
......
...@@ -1085,8 +1085,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) ...@@ -1085,8 +1085,7 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* possible TODO: call find_keyword() from sql_lex.cc here */ static inline const char *require_quotes(const char *name, uint length)
static bool require_quotes(const char *name, uint length)
{ {
uint i, d, c; uint i, d, c;
for (i=0; i<length; i+=d) for (i=0; i<length; i+=d)
...@@ -1094,7 +1093,37 @@ static bool require_quotes(const char *name, uint length) ...@@ -1094,7 +1093,37 @@ static bool require_quotes(const char *name, uint length)
c=((uchar *)name)[i]; c=((uchar *)name)[i];
d=my_mbcharlen(system_charset_info, c); d=my_mbcharlen(system_charset_info, c);
if (d==1 && !system_charset_info->ident_map[c]) if (d==1 && !system_charset_info->ident_map[c])
return 1; return name+i;
}
return 0;
}
/*
Looking for char in multibyte string
SYNOPSIS
look_for_char()
name string for looking at
length length of name
q '\'' or '\"' for looking for
RETURN VALUES
# pointer to found char in string
0 string doesn't contain required char
*/
static inline const char *look_for_char(const char *name,
uint length, char q)
{
const char *cur= name;
const char *end= cur+length;
uint symbol_length;
for (; cur<end; cur+= symbol_length)
{
char c= *cur;
symbol_length= my_mbcharlen(system_charset_info, c);
if (symbol_length==1 && c==q)
return cur;
} }
return 0; return 0;
} }
...@@ -1103,21 +1132,52 @@ void ...@@ -1103,21 +1132,52 @@ void
append_identifier(THD *thd, String *packet, const char *name, uint length) append_identifier(THD *thd, String *packet, const char *name, uint length)
{ {
char qtype; char qtype;
uint part_len;
const char *qplace;
if (thd->variables.sql_mode & MODE_ANSI_QUOTES) if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
qtype= '\"'; qtype= '\"';
else else
qtype= '`'; qtype= '`';
if ((thd->options & OPTION_QUOTE_SHOW_CREATE) || if (is_keyword(name,length))
require_quotes(name, length))
{ {
packet->append(&qtype, 1); packet->append(&qtype, 1, system_charset_info);
packet->append(name, length, system_charset_info); packet->append(name, length, system_charset_info);
packet->append(&qtype, 1); packet->append(&qtype, 1, system_charset_info);
} }
else else
{ {
packet->append(name, length, system_charset_info); if (!(qplace= require_quotes(name, length)))
{
if (!(thd->options & OPTION_QUOTE_SHOW_CREATE))
packet->append(name, length, system_charset_info);
else
{
packet->append(&qtype, 1, system_charset_info);
packet->append(name, length, system_charset_info);
packet->append(&qtype, 1, system_charset_info);
}
}
else
{
packet->shrink(packet->length()+length+2);
packet->append(&qtype, 1, system_charset_info);
if (*qplace != qtype)
qplace= look_for_char(qplace+1,length-(qplace-name)-1,qtype);
while (qplace)
{
if ((part_len= qplace-name))
{
packet->append(name, part_len, system_charset_info);
length-= part_len;
}
packet->append(qplace, 1, system_charset_info);
name= qplace;
qplace= look_for_char(name+1,length-1,qtype);
}
packet->append(name, length, system_charset_info);
packet->append(&qtype, 1, system_charset_info);
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment