Commit 19dc01be authored by marko's avatar marko

branches/5.1: Port r6134 from branches/zip:

  ------------------------------------------------------------------------
  r6134 | marko | 2009-11-04 07:57:29 +0000 (Wed, 04 Nov 2009) | 5 lines

  branches/zip: innobase_convert_identifier(): Convert table names with
  explain_filename() to address Bug #32430: 'show innodb status'
  causes errors Invalid (old?) table or database name in logs.

  rb://134 approved by Sunny Bains
  ------------------------------------------------------------------------

innobase_print_identifier(): Replace with innobase_convert_name().

innobase_convert_identifier(): New function, called by innobase_convert_name().
parent ce0b6eaa
...@@ -1404,70 +1404,148 @@ innobase_invalidate_query_cache( ...@@ -1404,70 +1404,148 @@ innobase_invalidate_query_cache(
#endif #endif
} }
/********************************************************************* /*****************************************************************//**
Display an SQL identifier. */ Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
extern "C" and quote it if needed.
void @return pointer to the end of buf */
innobase_print_identifier( static
/*======================*/ char*
FILE* f, /* in: output stream */ innobase_convert_identifier(
trx_t* trx, /* in: transaction */ /*========================*/
ibool table_id,/* in: TRUE=print a table name, char* buf, /*!< out: buffer for converted identifier */
FALSE=print other identifier */ ulint buflen, /*!< in: length of buf, in bytes */
const char* name, /* in: name to print */ const char* id, /*!< in: identifier to convert */
ulint namelen)/* in: length of name */ ulint idlen, /*!< in: length of id, in bytes */
{ void* thd, /*!< in: MySQL connection thread, or NULL */
const char* s = name; ibool file_id)/*!< in: TRUE=id is a table or database name;
char* qname = NULL; FALSE=id is an UTF-8 string */
{
char nz[NAME_LEN + 1];
#if MYSQL_VERSION_ID >= 50141
char nz2[NAME_LEN + 1 + EXPLAIN_FILENAME_MAX_EXTRA_LENGTH];
#else /* MYSQL_VERSION_ID >= 50141 */
char nz2[NAME_LEN + 1 + sizeof srv_mysql50_table_name_prefix];
#endif /* MYSQL_VERSION_ID >= 50141 */
const char* s = id;
int q; int q;
if (table_id) { if (file_id) {
/* Decode the table name. The filename_to_tablename() /* Decode the table name. The MySQL function expects
function expects a NUL-terminated string. The input and a NUL-terminated string. The input and output strings
output strings buffers must not be shared. The function buffers must not be shared. */
only produces more output when the name contains other
characters than [0-9A-Z_a-z]. */ if (UNIV_UNLIKELY(idlen > (sizeof nz) - 1)) {
char* temp_name = (char*) my_malloc((uint) namelen + 1, MYF(MY_WME)); idlen = (sizeof nz) - 1;
uint qnamelen = (uint) (namelen
+ (1 + sizeof srv_mysql50_table_name_prefix));
if (temp_name) {
qname = (char*) my_malloc(qnamelen, MYF(MY_WME));
if (qname) {
memcpy(temp_name, name, namelen);
temp_name[namelen] = 0;
s = qname;
namelen = filename_to_tablename(temp_name,
qname, qnamelen);
}
my_free(temp_name, MYF(0));
} }
}
if (!trx || !trx->mysql_thd) { memcpy(nz, id, idlen);
nz[idlen] = 0;
s = nz2;
#if MYSQL_VERSION_ID >= 50141
idlen = explain_filename((THD*) thd, nz, nz2, sizeof nz2,
EXPLAIN_PARTITIONS_AS_COMMENT);
goto no_quote;
#else /* MYSQL_VERSION_ID >= 50141 */
idlen = filename_to_tablename(nz, nz2, sizeof nz2);
#endif /* MYSQL_VERSION_ID >= 50141 */
}
/* See if the identifier needs to be quoted. */
if (UNIV_UNLIKELY(!thd)) {
q = '"'; q = '"';
} else { } else {
q = get_quote_char_for_identifier((THD*) trx->mysql_thd, q = get_quote_char_for_identifier((THD*) thd, s, (int) idlen);
s, (int) namelen);
} }
if (q == EOF) { if (q == EOF) {
fwrite(s, 1, namelen, f); #if MYSQL_VERSION_ID >= 50141
} else { no_quote:
const char* e = s + namelen; #endif /* MYSQL_VERSION_ID >= 50141 */
putc(q, f); if (UNIV_UNLIKELY(idlen > buflen)) {
while (s < e) { idlen = buflen;
int c = *s++; }
if (c == q) { memcpy(buf, s, idlen);
putc(c, f); return(buf + idlen);
}
/* Quote the identifier. */
if (buflen < 2) {
return(buf);
}
*buf++ = q;
buflen--;
for (; idlen; idlen--) {
int c = *s++;
if (UNIV_UNLIKELY(c == q)) {
if (UNIV_UNLIKELY(buflen < 3)) {
break;
} }
putc(c, f);
*buf++ = c;
*buf++ = c;
buflen -= 2;
} else {
if (UNIV_UNLIKELY(buflen < 2)) {
break;
}
*buf++ = c;
buflen--;
} }
putc(q, f);
} }
my_free(qname, MYF(MY_ALLOW_ZERO_PTR)); *buf++ = q;
return(buf);
}
/*****************************************************************//**
Convert a table or index name to the MySQL system_charset_info (UTF-8)
and quote it if needed.
@return pointer to the end of buf */
extern "C"
char*
innobase_convert_name(
/*==================*/
char* buf, /*!< out: buffer for converted identifier */
ulint buflen, /*!< in: length of buf, in bytes */
const char* id, /*!< in: identifier to convert */
ulint idlen, /*!< in: length of id, in bytes */
void* thd, /*!< in: MySQL connection thread, or NULL */
ibool table_id)/*!< in: TRUE=id is a table or database name;
FALSE=id is an index name */
{
char* s = buf;
const char* bufend = buf + buflen;
if (table_id) {
const char* slash = (const char*) memchr(id, '/', idlen);
if (!slash) {
goto no_db_name;
}
/* Print the database name and table name separately. */
s = innobase_convert_identifier(s, bufend - s, id, slash - id,
thd, TRUE);
if (UNIV_LIKELY(s < bufend)) {
*s++ = '.';
s = innobase_convert_identifier(s, bufend - s,
slash + 1, idlen
- (slash - id) - 1,
thd, TRUE);
}
} else {
no_db_name:
s = innobase_convert_identifier(buf, buflen, id, idlen,
thd, table_id);
}
return(s);
} }
/************************************************************************** /**************************************************************************
......
...@@ -24,18 +24,21 @@ innobase_convert_string( ...@@ -24,18 +24,21 @@ innobase_convert_string(
CHARSET_INFO* from_cs, CHARSET_INFO* from_cs,
uint* errors); uint* errors);
/********************************************************************* /*****************************************************************//**
Display an SQL identifier. */ Convert a table or index name to the MySQL system_charset_info (UTF-8)
and quote it if needed.
@return pointer to the end of buf */
void char*
innobase_print_identifier( innobase_convert_name(
/*======================*/ /*==================*/
FILE* f, /* in: output stream */ char* buf, /*!< out: buffer for converted identifier */
trx_t* trx, /* in: transaction */ ulint buflen, /*!< in: length of buf, in bytes */
ibool table_id,/* in: TRUE=print a table name, const char* id, /*!< in: identifier to convert */
FALSE=print other identifier */ ulint idlen, /*!< in: length of id, in bytes */
const char* name, /* in: name to print */ void* thd, /*!< in: MySQL connection thread, or NULL */
ulint namelen);/* in: length of name */ ibool table_id);/*!< in: TRUE=id is a table or database name;
FALSE=id is an index name */
/********************************************************************** /**********************************************************************
Returns true if the thread is the replication thread on the slave Returns true if the thread is the replication thread on the slave
......
...@@ -19,6 +19,7 @@ Created 5/11/1994 Heikki Tuuri ...@@ -19,6 +19,7 @@ Created 5/11/1994 Heikki Tuuri
#include "ut0sort.h" #include "ut0sort.h"
#include "trx0trx.h" #include "trx0trx.h"
#include "ha_prototypes.h" #include "ha_prototypes.h"
#include "mysql_com.h" /* NAME_LEN */
ibool ut_always_false = FALSE; ibool ut_always_false = FALSE;
...@@ -484,26 +485,17 @@ ut_print_namel( ...@@ -484,26 +485,17 @@ ut_print_namel(
const char* name, /* in: name to print */ const char* name, /* in: name to print */
ulint namelen)/* in: length of name */ ulint namelen)/* in: length of name */
{ {
#ifdef UNIV_HOTBACKUP /* 2 * NAME_LEN for database and table name,
fwrite(name, 1, namelen, f); and some slack for the #mysql50# prefix and quotes */
#else char buf[3 * NAME_LEN];
if (table_id) { const char* bufend;
char* slash = memchr(name, '/', namelen);
if (!slash) {
goto no_db_name; bufend = innobase_convert_name(buf, sizeof buf,
} name, namelen,
trx ? trx->mysql_thd : NULL,
table_id);
/* Print the database name and table name separately. */ fwrite(buf, 1, bufend - buf, f);
innobase_print_identifier(f, trx, TRUE, name, slash - name);
putc('.', f);
innobase_print_identifier(f, trx, TRUE, slash + 1,
namelen - (slash - name) - 1);
} else {
no_db_name:
innobase_print_identifier(f, trx, table_id, name, namelen);
}
#endif
} }
/************************************************************************** /**************************************************************************
......
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