Commit 6a594ffd authored by unknown's avatar unknown

Fix for BUG#25082: default database change on trigger

execution breaks replication.

When a stored routine is executed, we switch current
database to the database, in which the routine
has been created. When the stored routine finishes,
we switch back to the original database.

The problem was that if the original database does not
exist (anymore) after routine execution, we raised an error.

The fix is to report a warning, and switch to the NULL database.


mysql-test/r/sp.result:
  Updated result file.
mysql-test/t/sp.test:
  Added test case for BUG#25082.
sql/mysql_priv.h:
  1. Change mysql_change_db() prototype;
  2. Polishing.
sql/sp.cc:
  Polishing.
sql/sp_head.cc:
  Polishing.
sql/sql_db.cc:
  1. Polishing.
  2. Fix mysql_change_db().
sql/sql_parse.cc:
  Polishing.
sql/sql_show.cc:
  Polishing.
parent 21af9a55
...@@ -5969,6 +5969,21 @@ SUM(f2) bug25373(f1) ...@@ -5969,6 +5969,21 @@ SUM(f2) bug25373(f1)
21.300000071526 NULL 21.300000071526 NULL
DROP FUNCTION bug25373| DROP FUNCTION bug25373|
DROP TABLE t3| DROP TABLE t3|
DROP DATABASE IF EXISTS mysqltest1|
DROP DATABASE IF EXISTS mysqltest2|
CREATE DATABASE mysqltest1|
CREATE DATABASE mysqltest2|
CREATE PROCEDURE mysqltest1.p1()
DROP DATABASE mysqltest2|
use mysqltest2|
CALL mysqltest1.p1()|
Warnings:
Note 1049 Unknown database 'mysqltest2'
SELECT DATABASE()|
DATABASE()
NULL
DROP DATABASE mysqltest1|
use test|
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM; CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM;
CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb; CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb;
......
...@@ -6929,6 +6929,47 @@ INSERT INTO t3 VALUES (1, 3.4), (1, 2), (1, 0.9), (2, 8), (2, 7)| ...@@ -6929,6 +6929,47 @@ INSERT INTO t3 VALUES (1, 3.4), (1, 2), (1, 0.9), (2, 8), (2, 7)|
SELECT SUM(f2), bug25373(f1) FROM t3 GROUP BY bug25373(f1) WITH ROLLUP| SELECT SUM(f2), bug25373(f1) FROM t3 GROUP BY bug25373(f1) WITH ROLLUP|
DROP FUNCTION bug25373| DROP FUNCTION bug25373|
DROP TABLE t3| DROP TABLE t3|
#
# BUG#25082: Default database change on trigger execution breaks replication.
#
# As it turned out, this bug has actually two bugs. So, here we have two test
# cases -- one in sp.test, the other in sp-security.test.
#
#
# Test case 1: error on dropping the current database.
#
# Prepare.
--disable_warnings
DROP DATABASE IF EXISTS mysqltest1|
DROP DATABASE IF EXISTS mysqltest2|
--enable_warnings
CREATE DATABASE mysqltest1|
CREATE DATABASE mysqltest2|
# Test.
CREATE PROCEDURE mysqltest1.p1()
DROP DATABASE mysqltest2|
use mysqltest2|
CALL mysqltest1.p1()|
SELECT DATABASE()|
# Cleanup.
DROP DATABASE mysqltest1|
use test|
# #
# NOTE: The delimiter is `|`, and not `;`. It is changed to `;` # NOTE: The delimiter is `|`, and not `;`. It is changed to `;`
# at the end of the file! # at the end of the file!
......
...@@ -693,7 +693,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); ...@@ -693,7 +693,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db,
char *new_table_name, char *new_table_alias, char *new_table_name, char *new_table_alias,
bool skip_error); bool skip_error);
bool mysql_change_db(THD *thd,const char *name,bool no_access_check); bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name,
bool force_switch);
void mysql_parse(THD *thd,char *inBuf,uint length); void mysql_parse(THD *thd,char *inBuf,uint length);
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length); bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
bool is_update_query(enum enum_sql_command command); bool is_update_query(enum enum_sql_command command);
...@@ -937,7 +938,7 @@ void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user, ...@@ -937,7 +938,7 @@ void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
/* information schema */ /* information schema */
extern LEX_STRING information_schema_name; extern LEX_STRING INFORMATION_SCHEMA_NAME;
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str, LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
const char* str, uint length, const char* str, uint length,
bool allocate_lex_string); bool allocate_lex_string);
...@@ -955,7 +956,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond); ...@@ -955,7 +956,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
bool get_schema_tables_result(JOIN *join, bool get_schema_tables_result(JOIN *join,
enum enum_schema_table_state executed_place); enum enum_schema_table_state executed_place);
#define is_schema_db(X) \ #define is_schema_db(X) \
!my_strcasecmp(system_charset_info, information_schema_name.str, (X)) !my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, (X))
/* sql_prepare.cc */ /* sql_prepare.cc */
......
...@@ -441,14 +441,14 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ...@@ -441,14 +441,14 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
{ {
sp_head *sp= newlex.sphead; sp_head *sp= newlex.sphead;
if (dbchanged && (ret= mysql_change_db(thd, old_db.str, 1))) if (dbchanged && (ret= mysql_change_db(thd, &old_db, TRUE)))
goto end; goto end;
delete sp; delete sp;
ret= SP_PARSE_ERROR; ret= SP_PARSE_ERROR;
} }
else else
{ {
if (dbchanged && (ret= mysql_change_db(thd, old_db.str, 1))) if (dbchanged && (ret= mysql_change_db(thd, &old_db, TRUE)))
goto end; goto end;
*sphp= newlex.sphead; *sphp= newlex.sphead;
(*sphp)->set_definer(&definer_user_name, &definer_host_name); (*sphp)->set_definer(&definer_user_name, &definer_host_name);
...@@ -1896,7 +1896,7 @@ sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db, ...@@ -1896,7 +1896,7 @@ sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
ret= mysql_change_db(thd, new_db.str, no_access_check); ret= mysql_change_db(thd, &new_db, no_access_check);
*dbchangedp= ret == 0; *dbchangedp= ret == 0;
DBUG_RETURN(ret); DBUG_RETURN(ret);
......
...@@ -1130,7 +1130,7 @@ sp_head::execute(THD *thd) ...@@ -1130,7 +1130,7 @@ sp_head::execute(THD *thd)
(It would generate an error from mysql_change_db() when old_db=="") (It would generate an error from mysql_change_db() when old_db=="")
*/ */
if (! thd->killed) if (! thd->killed)
err_status|= mysql_change_db(thd, old_db.str, 1); err_status|= mysql_change_db(thd, &old_db, TRUE);
} }
m_flags&= ~IS_INVOKED; m_flags&= ~IS_INVOKED;
DBUG_PRINT("info", DBUG_PRINT("info",
......
...@@ -461,7 +461,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, ...@@ -461,7 +461,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
DBUG_ENTER("mysql_create_db"); DBUG_ENTER("mysql_create_db");
/* do not create 'information_schema' db */ /* do not create 'information_schema' db */
if (!my_strcasecmp(system_charset_info, db, information_schema_name.str)) if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
{ {
my_error(ER_DB_CREATE_EXISTS, MYF(0), db); my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -1126,154 +1126,256 @@ static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, ...@@ -1126,154 +1126,256 @@ static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp,
} }
/* /**
Change the current database. @brief Internal implementation: switch current database to a valid one.
SYNOPSIS @param thd Thread context.
mysql_change_db() @param new_db_name Name of the database to switch to. The function will
thd thread handle take ownership of the name (the caller must not free
name database name the allocated memory). If the name is NULL, we're
no_access_check if TRUE, don't do access check. In this going to switch to NULL db.
case name may be "" @param new_db_access Privileges of the new database.
@param new_db_charset Character set of the new database.
*/
DESCRIPTION static void mysql_change_db_impl(THD *thd,
Check that the database name corresponds to a valid and LEX_STRING *new_db_name,
existent database, check access rights (unless called with ulong new_db_access,
no_access_check), and set the current database. This function CHARSET_INFO *new_db_charset)
is called to change the current database upon user request {
(COM_CHANGE_DB command) or temporarily, to execute a stored /* 1. Change current database in THD. */
routine.
NOTES if (new_db_name == NULL)
This function is not the only way to switch the database that {
is currently employed. When the replication slave thread /*
switches the database before executing a query, it calls THD::set_db() does all the job -- it frees previous database name and
thd->set_db directly. However, if the query, in turn, uses sets the new one.
a stored routine, the stored routine will use this function, */
even if it's run on the slave.
This function allocates the name of the database on the system
heap: this is necessary to be able to uniformly change the
database from any module of the server. Up to 5.0 different
modules were using different memory to store the name of the
database, and this led to memory corruption: a stack pointer
set by Stored Procedures was used by replication after the
stack address was long gone.
This function does not send anything, including error
messages, to the client. If that should be sent to the client,
call net_send_error after this function.
RETURN VALUES thd->set_db(NULL, 0);
0 OK }
1 error else if (new_db_name == &INFORMATION_SCHEMA_NAME)
{
/*
Here we must use THD::set_db(), because we want to copy
INFORMATION_SCHEMA_NAME constant.
*/
thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
}
else
{
/*
Here we already have a copy of database name to be used in THD. So,
we just call THD::reset_db(). Since THD::reset_db() does not releases
the previous database name, we should do it explicitly.
*/
x_free(thd->db);
thd->reset_db(new_db_name->str, new_db_name->length);
}
/* 2. Update security context. */
#ifndef NO_EMBEDDED_ACCESS_CHECKS
thd->security_ctx->db_access= new_db_access;
#endif
/* 3. Update db-charset environment variables. */
thd->db_charset= new_db_charset;
thd->variables.collation_database= new_db_charset;
}
/**
@brief Change the current database.
@param thd thread handle
@param name database name
@param force_switch if this flag is set (TRUE), mysql_change_db() will
switch to NULL db if the specified database is not
available anymore. Corresponding warning will be
thrown in this case. This flag is used to change
database in stored-routine-execution code.
@details Check that the database name corresponds to a valid and existent
database, check access rights (unless called with no_access_check), and
set the current database. This function is called to change the current
database upon user request (COM_CHANGE_DB command) or temporarily, to
execute a stored routine.
This function is not the only way to switch the database that is
currently employed. When the replication slave thread switches the
database before executing a query, it calls thd->set_db directly.
However, if the query, in turn, uses a stored routine, the stored routine
will use this function, even if it's run on the slave.
This function allocates the name of the database on the system heap: this
is necessary to be able to uniformly change the database from any module
of the server. Up to 5.0 different modules were using different memory to
store the name of the database, and this led to memory corruption:
a stack pointer set by Stored Procedures was used by replication after
the stack address was long gone.
@return Operation status
@retval FALSE Success
@retval TRUE Error
*/ */
bool mysql_change_db(THD *thd, const char *name, bool no_access_check) bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
{ {
int db_length; LEX_STRING new_db_file_name;
char *db_name;
bool system_db= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
Security_context *sctx= thd->security_ctx; Security_context *sctx= thd->security_ctx;
LINT_INIT(db_access); ulong db_access= sctx->db_access;
#endif
DBUG_ENTER("mysql_change_db"); DBUG_ENTER("mysql_change_db");
DBUG_PRINT("enter",("name: '%s'",name)); DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
if (name == NULL || name[0] == '\0' && no_access_check == FALSE) if (new_db_name == NULL ||
new_db_name->length == 0 ||
new_db_name->str == NULL)
{ {
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); if (force_switch)
DBUG_RETURN(1); /* purecov: inspected */ {
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR));
/* Change db to NULL. */
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
DBUG_RETURN(FALSE);
}
else
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
DBUG_RETURN(TRUE);
}
} }
else if (name[0] == '\0')
if (my_strcasecmp(system_charset_info, new_db_name->str,
INFORMATION_SCHEMA_NAME.str) == 0)
{ {
/* Called from SP to restore the original database, which was NULL */ /* Switch database to INFORMATION_SCHEMA. */
DBUG_ASSERT(no_access_check);
system_db= 1; mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, SELECT_ACL,
db_name= NULL; system_charset_info);
db_length= 0;
goto end; DBUG_RETURN(FALSE);
} }
/* /*
Now we need to make a copy because check_db_name requires a Now we need to make a copy because check_db_name requires a
non-constant argument. TODO: fix check_db_name. non-constant argument. Actually, it takes database file name.
TODO: fix check_db_name().
*/ */
if ((db_name= my_strdup(name, MYF(MY_WME))) == NULL)
DBUG_RETURN(1); /* the error is set */ new_db_file_name.str= my_strdup(new_db_name->str, MYF(MY_WME));
db_length= strlen(db_name); new_db_file_name.length= new_db_name->length;
if (check_db_name(db_name))
{ if (new_db_file_name.str == NULL)
my_error(ER_WRONG_DB_NAME, MYF(0), db_name); DBUG_RETURN(TRUE); /* the error is set */
my_free(db_name, MYF(0));
DBUG_RETURN(1); /*
} NOTE: if check_db_name() fails, we should throw an error in any case,
DBUG_PRINT("info",("Use database: %s", db_name)); even if we are called from sp_head::execute().
if (!my_strcasecmp(system_charset_info, db_name, information_schema_name.str))
It's next to impossible however to get this error when we are called
from sp_head::execute(). But let's switch database to NULL in this case
to be sure.
*/
if (check_db_name(new_db_file_name.str))
{ {
system_db= 1; my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
#ifndef NO_EMBEDDED_ACCESS_CHECKS my_free(new_db_file_name.str, MYF(0));
db_access= SELECT_ACL;
#endif if (force_switch)
goto end; {
/* Change db to NULL. */
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
}
DBUG_RETURN(TRUE);
} }
DBUG_PRINT("info",("Use database: %s", new_db_file_name.str));
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!no_access_check) if (!force_switch) /* FIXME: this is BUG#27337. */
{ {
if (test_all_bits(sctx->master_access, DB_ACLS)) db_access=
db_access=DB_ACLS; test_all_bits(sctx->master_access, DB_ACLS) ?
else DB_ACLS :
db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name, 0) | acl_get(sctx->host,
sctx->master_access); sctx->ip,
if (!(db_access & DB_ACLS) && (!grant_option || sctx->priv_user,
check_grant_db(thd,db_name))) new_db_file_name.str,
FALSE) | sctx->master_access;
if (!force_switch &&
!(db_access & DB_ACLS) &&
(!grant_option || check_grant_db(thd, new_db_file_name.str)))
{ {
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->priv_user,
sctx->priv_host, sctx->priv_host,
db_name); new_db_file_name.str);
mysql_log.write(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR), mysql_log.write(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
sctx->priv_user, sctx->priv_host, db_name); sctx->priv_user, sctx->priv_host, new_db_file_name.str);
my_free(db_name, MYF(0)); my_free(new_db_file_name.str, MYF(0));
DBUG_RETURN(1); DBUG_RETURN(TRUE);
} }
} }
#endif #endif
if (check_db_dir_existence(db_name)) if (check_db_dir_existence(new_db_file_name.str))
{ {
my_error(ER_BAD_DB_ERROR, MYF(0), db_name); if (force_switch)
my_free(db_name, MYF(0)); {
DBUG_RETURN(1); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
} ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
new_db_file_name.str);
end: my_free(new_db_file_name.str, MYF(0));
x_free(thd->db);
DBUG_ASSERT(db_name == NULL || db_name[0] != '\0'); /* Change db to NULL. */
thd->reset_db(db_name, db_length); // THD::~THD will free this
#ifndef NO_EMBEDDED_ACCESS_CHECKS mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
if (!no_access_check)
sctx->db_access= db_access; DBUG_RETURN(FALSE);
#endif }
if (system_db) else
{ {
thd->db_charset= system_charset_info; my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
thd->variables.collation_database= system_charset_info; my_free(new_db_file_name.str, MYF(0));
DBUG_RETURN(TRUE);
}
} }
else
/*
NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
attributes and will be freed in THD::~THD().
*/
{ {
HA_CREATE_INFO create; HA_CREATE_INFO db_options;
load_db_opt_by_name(thd, db_name, &create); load_db_opt_by_name(thd, new_db_name->str, &db_options);
thd->db_charset= create.default_table_charset ? mysql_change_db_impl(thd, &new_db_file_name, db_access,
create.default_table_charset : db_options.default_table_charset ?
thd->variables.collation_server; db_options.default_table_charset :
thd->variables.collation_database= thd->db_charset; thd->variables.collation_server);
} }
DBUG_RETURN(0);
DBUG_RETURN(FALSE);
} }
......
...@@ -290,7 +290,8 @@ int check_user(THD *thd, enum enum_server_command command, ...@@ -290,7 +290,8 @@ int check_user(THD *thd, enum enum_server_command command,
bool check_count) bool check_count)
{ {
DBUG_ENTER("check_user"); DBUG_ENTER("check_user");
LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
#ifdef NO_EMBEDDED_ACCESS_CHECKS #ifdef NO_EMBEDDED_ACCESS_CHECKS
thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
/* Change database if necessary */ /* Change database if necessary */
...@@ -301,7 +302,7 @@ int check_user(THD *thd, enum enum_server_command command, ...@@ -301,7 +302,7 @@ int check_user(THD *thd, enum enum_server_command command,
function returns 0 function returns 0
*/ */
thd->reset_db(NULL, 0); thd->reset_db(NULL, 0);
if (mysql_change_db(thd, db, FALSE)) if (mysql_change_db(thd, &db_str, FALSE))
{ {
/* Send the error to the client */ /* Send the error to the client */
net_send_error(thd); net_send_error(thd);
...@@ -443,7 +444,7 @@ int check_user(THD *thd, enum enum_server_command command, ...@@ -443,7 +444,7 @@ int check_user(THD *thd, enum enum_server_command command,
/* Change database if necessary */ /* Change database if necessary */
if (db && db[0]) if (db && db[0])
{ {
if (mysql_change_db(thd, db, FALSE)) if (mysql_change_db(thd, &db_str, FALSE))
{ {
/* Send error to the client */ /* Send error to the client */
net_send_error(thd); net_send_error(thd);
...@@ -1638,7 +1639,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1638,7 +1639,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
&LOCK_status); &LOCK_status);
thd->convert_string(&tmp, system_charset_info, thd->convert_string(&tmp, system_charset_info,
packet, strlen(packet), thd->charset()); packet, strlen(packet), thd->charset());
if (!mysql_change_db(thd, tmp.str, FALSE)) if (!mysql_change_db(thd, &tmp, FALSE))
{ {
mysql_log.write(thd,command,"%s",thd->db); mysql_log.write(thd,command,"%s",thd->db);
send_ok(thd); send_ok(thd);
...@@ -1862,7 +1863,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1862,7 +1863,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
packet= pend+1; packet= pend+1;
if (!my_strcasecmp(system_charset_info, table_list.db, if (!my_strcasecmp(system_charset_info, table_list.db,
information_schema_name.str)) INFORMATION_SCHEMA_NAME.str))
{ {
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias); ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
if (schema_table) if (schema_table)
...@@ -3753,9 +3754,14 @@ mysql_execute_command(THD *thd) ...@@ -3753,9 +3754,14 @@ mysql_execute_command(THD *thd)
} }
#endif #endif
case SQLCOM_CHANGE_DB: case SQLCOM_CHANGE_DB:
if (!mysql_change_db(thd,select_lex->db,FALSE)) {
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
if (!mysql_change_db(thd, &db_str, FALSE))
send_ok(thd); send_ok(thd);
break; break;
}
case SQLCOM_LOAD: case SQLCOM_LOAD:
{ {
...@@ -5436,7 +5442,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, ...@@ -5436,7 +5442,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
if (!no_errors) if (!no_errors)
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->priv_host, sctx->priv_user, sctx->priv_host,
information_schema_name.str); INFORMATION_SCHEMA_NAME.str);
return TRUE; return TRUE;
} }
/* /*
...@@ -6256,7 +6262,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ...@@ -6256,7 +6262,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES); ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->derived= table->sel; ptr->derived= table->sel;
if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db, if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
information_schema_name.str)) INFORMATION_SCHEMA_NAME.str))
{ {
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name); ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
if (!schema_table || if (!schema_table ||
...@@ -6264,7 +6270,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ...@@ -6264,7 +6270,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
lex->orig_sql_command == SQLCOM_END)) // not a 'show' command lex->orig_sql_command == SQLCOM_END)) // not a 'show' command
{ {
my_error(ER_UNKNOWN_TABLE, MYF(0), my_error(ER_UNKNOWN_TABLE, MYF(0),
ptr->table_name, information_schema_name.str); ptr->table_name, INFORMATION_SCHEMA_NAME.str);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
ptr->schema_table_name= ptr->table_name; ptr->schema_table_name= ptr->table_name;
......
...@@ -496,9 +496,9 @@ bool mysqld_show_create_db(THD *thd, char *dbname, ...@@ -496,9 +496,9 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
} }
#endif #endif
if (!my_strcasecmp(system_charset_info, dbname, if (!my_strcasecmp(system_charset_info, dbname,
information_schema_name.str)) INFORMATION_SCHEMA_NAME.str))
{ {
dbname= information_schema_name.str; dbname= INFORMATION_SCHEMA_NAME.str;
create.default_table_charset= system_charset_info; create.default_table_charset= system_charset_info;
} }
else else
...@@ -1823,7 +1823,8 @@ LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str, ...@@ -1823,7 +1823,8 @@ LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
/* INFORMATION_SCHEMA name */ /* INFORMATION_SCHEMA name */
LEX_STRING information_schema_name= {(char*)"information_schema", 18}; LEX_STRING INFORMATION_SCHEMA_NAME=
{ (char *) STRING_WITH_LEN("information_schema") };
/* This is only used internally, but we need it here as a forward reference */ /* This is only used internally, but we need it here as a forward reference */
extern ST_SCHEMA_TABLE schema_tables[]; extern ST_SCHEMA_TABLE schema_tables[];
...@@ -2039,11 +2040,11 @@ int make_db_list(THD *thd, List<char> *files, ...@@ -2039,11 +2040,11 @@ int make_db_list(THD *thd, List<char> *files,
*/ */
if (!idx_field_vals->db_value || if (!idx_field_vals->db_value ||
!wild_case_compare(system_charset_info, !wild_case_compare(system_charset_info,
information_schema_name.str, INFORMATION_SCHEMA_NAME.str,
idx_field_vals->db_value)) idx_field_vals->db_value))
{ {
*with_i_schema= 1; *with_i_schema= 1;
if (files->push_back(thd->strdup(information_schema_name.str))) if (files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str)))
return 1; return 1;
} }
return (find_files(thd, files, NullS, mysql_data_home, return (find_files(thd, files, NullS, mysql_data_home,
...@@ -2058,11 +2059,11 @@ int make_db_list(THD *thd, List<char> *files, ...@@ -2058,11 +2059,11 @@ int make_db_list(THD *thd, List<char> *files,
*/ */
if (lex->orig_sql_command != SQLCOM_END) if (lex->orig_sql_command != SQLCOM_END)
{ {
if (!my_strcasecmp(system_charset_info, information_schema_name.str, if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
idx_field_vals->db_value)) idx_field_vals->db_value))
{ {
*with_i_schema= 1; *with_i_schema= 1;
return files->push_back(thd->strdup(information_schema_name.str)); return files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str));
} }
return files->push_back(thd->strdup(idx_field_vals->db_value)); return files->push_back(thd->strdup(idx_field_vals->db_value));
} }
...@@ -2071,7 +2072,7 @@ int make_db_list(THD *thd, List<char> *files, ...@@ -2071,7 +2072,7 @@ int make_db_list(THD *thd, List<char> *files,
Create list of existing databases. It is used in case Create list of existing databases. It is used in case
of select from information schema table of select from information schema table
*/ */
if (files->push_back(thd->strdup(information_schema_name.str))) if (files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str)))
return 1; return 1;
*with_i_schema= 1; *with_i_schema= 1;
return (find_files(thd, files, NullS, return (find_files(thd, files, NullS,
...@@ -3927,8 +3928,8 @@ int make_schema_select(THD *thd, SELECT_LEX *sel, ...@@ -3927,8 +3928,8 @@ int make_schema_select(THD *thd, SELECT_LEX *sel,
We have to make non const db_name & table_name We have to make non const db_name & table_name
because of lower_case_table_names because of lower_case_table_names
*/ */
make_lex_string(thd, &db, information_schema_name.str, make_lex_string(thd, &db, INFORMATION_SCHEMA_NAME.str,
information_schema_name.length, 0); INFORMATION_SCHEMA_NAME.length, 0);
make_lex_string(thd, &table, schema_table->table_name, make_lex_string(thd, &table, schema_table->table_name,
strlen(schema_table->table_name), 0); strlen(schema_table->table_name), 0);
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */ if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
......
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