summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authoristruewing@stella.local <>2008-02-14 16:53:03 +0100
committeristruewing@stella.local <>2008-02-14 16:53:03 +0100
commit9a4d57e31964634785c6f941c3714ce5a46d7bd4 (patch)
treea49c7a5dd76561facfd53b760feaadf0369e787b /sql
parentfb20c9dd5e3f7fb5c45d649c30a2932d337bc35f (diff)
parent301ab0d8b72bea5a924cd996f0a0378b3175e9db (diff)
downloadmariadb-git-9a4d57e31964634785c6f941c3714ce5a46d7bd4.tar.gz
Merge stella.local:/home2/mydev/mysql-5.1-amain
into stella.local:/home2/mydev/mysql-5.1-axmrg
Diffstat (limited to 'sql')
-rw-r--r--sql/event_db_repository.cc69
-rw-r--r--sql/item.cc3
-rw-r--r--sql/log.cc23
-rw-r--r--sql/mysql_priv.h4
-rw-r--r--sql/mysqld.cc34
-rw-r--r--sql/rpl_rli.cc5
-rw-r--r--sql/rpl_rli.h4
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/slave.cc24
-rw-r--r--sql/sp.cc43
-rw-r--r--sql/sp_head.cc4
-rw-r--r--sql/sql_acl.cc9
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_binlog.cc3
-rw-r--r--sql/sql_bitmap.h2
-rw-r--r--sql/sql_cache.cc2
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_parse.cc75
-rw-r--r--sql/sql_plugin.cc2
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_show.cc8
-rw-r--r--sql/sql_trigger.cc2
-rw-r--r--sql/sql_view.cc6
-rw-r--r--sql/stacktrace.c64
-rw-r--r--sql/stacktrace.h8
25 files changed, 306 insertions, 102 deletions
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 9a33b33d8c9..401f76f5d26 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -111,7 +111,7 @@ const TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] =
"'ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES',"
"'STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES',"
"'ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER',"
- "'HIGH_NOT_PRECEDENCE')") },
+ "'HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')") },
{NULL, 0}
},
{
@@ -172,11 +172,13 @@ mysql_event_fill_row(THD *thd,
TABLE *table,
Event_parse_data *et,
sp_head *sp,
+ ulong sql_mode,
my_bool is_update)
{
CHARSET_INFO *scs= system_charset_info;
enum enum_events_table_field f_num;
Field **fields= table->field;
+ int rs= FALSE;
DBUG_ENTER("mysql_event_fill_row");
@@ -205,12 +207,9 @@ mysql_event_fill_row(THD *thd,
goto err_truncate;
/* both ON_COMPLETION and STATUS are NOT NULL thus not calling set_notnull()*/
- fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE);
-
- fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
-
- fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE);
-
+ rs|= fields[ET_FIELD_ON_COMPLETION]->store((longlong)et->on_completion, TRUE);
+ rs|= fields[ET_FIELD_STATUS]->store((longlong)et->status, TRUE);
+ rs|= fields[ET_FIELD_ORIGINATOR]->store((longlong)et->originator, TRUE);
/*
Change the SQL_MODE only if body was present in an ALTER EVENT and of course
@@ -220,7 +219,7 @@ mysql_event_fill_row(THD *thd,
{
DBUG_ASSERT(sp->m_body.str);
- fields[ET_FIELD_SQL_MODE]->store((longlong)thd->variables.sql_mode, TRUE);
+ rs|= fields[ET_FIELD_SQL_MODE]->store((longlong)sql_mode, TRUE);
if (fields[f_num= ET_FIELD_BODY]->store(sp->m_body.str,
sp->m_body.length,
@@ -236,16 +235,16 @@ mysql_event_fill_row(THD *thd,
if (!is_update || !et->starts_null)
{
fields[ET_FIELD_TIME_ZONE]->set_notnull();
- fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(),
- tz_name->charset());
+ rs|= fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(),
+ tz_name->charset());
}
fields[ET_FIELD_INTERVAL_EXPR]->set_notnull();
- fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE);
+ rs|= fields[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, TRUE);
fields[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
- fields[ET_FIELD_TRANSIENT_INTERVAL]->
+ rs|= fields[ET_FIELD_TRANSIENT_INTERVAL]->
store(interval_type_to_name[et->interval].str,
interval_type_to_name[et->interval].length,
scs);
@@ -274,8 +273,8 @@ mysql_event_fill_row(THD *thd,
{
const String *tz_name= thd->variables.time_zone->get_name();
fields[ET_FIELD_TIME_ZONE]->set_notnull();
- fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(),
- tz_name->charset());
+ rs|= fields[ET_FIELD_TIME_ZONE]->store(tz_name->ptr(), tz_name->length(),
+ tz_name->charset());
fields[ET_FIELD_INTERVAL_EXPR]->set_null();
fields[ET_FIELD_TRANSIENT_INTERVAL]->set_null();
@@ -308,13 +307,13 @@ mysql_event_fill_row(THD *thd,
}
fields[ET_FIELD_CHARACTER_SET_CLIENT]->set_notnull();
- fields[ET_FIELD_CHARACTER_SET_CLIENT]->store(
+ rs|= fields[ET_FIELD_CHARACTER_SET_CLIENT]->store(
thd->variables.character_set_client->csname,
strlen(thd->variables.character_set_client->csname),
system_charset_info);
fields[ET_FIELD_COLLATION_CONNECTION]->set_notnull();
- fields[ET_FIELD_COLLATION_CONNECTION]->store(
+ rs|= fields[ET_FIELD_COLLATION_CONNECTION]->store(
thd->variables.collation_connection->name,
strlen(thd->variables.collation_connection->name),
system_charset_info);
@@ -323,15 +322,23 @@ mysql_event_fill_row(THD *thd,
CHARSET_INFO *db_cl= get_default_db_collation(thd, et->dbname.str);
fields[ET_FIELD_DB_COLLATION]->set_notnull();
- fields[ET_FIELD_DB_COLLATION]->store(
- db_cl->name, strlen(db_cl->name), system_charset_info);
+ rs|= fields[ET_FIELD_DB_COLLATION]->store(db_cl->name,
+ strlen(db_cl->name),
+ system_charset_info);
}
if (et->body_changed)
{
fields[ET_FIELD_BODY_UTF8]->set_notnull();
- fields[ET_FIELD_BODY_UTF8]->store(
- sp->m_body_utf8.str, sp->m_body_utf8.length, system_charset_info);
+ rs|= fields[ET_FIELD_BODY_UTF8]->store(sp->m_body_utf8.str,
+ sp->m_body_utf8.length,
+ system_charset_info);
+ }
+
+ if (rs)
+ {
+ my_error(ER_EVENT_STORE_FAILED, MYF(0), fields[f_num]->field_name, rs);
+ DBUG_RETURN(TRUE);
}
DBUG_RETURN(FALSE);
@@ -585,12 +592,16 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
int ret= 1;
TABLE *table= NULL;
sp_head *sp= thd->lex->sphead;
+ ulong saved_mode= thd->variables.sql_mode;
DBUG_ENTER("Event_db_repository::create_event");
DBUG_PRINT("info", ("open mysql.event for update"));
DBUG_ASSERT(sp);
+ /* Reset sql_mode during data dictionary operations. */
+ thd->variables.sql_mode= 0;
+
if (open_event_table(thd, TL_WRITE, &table))
goto end;
@@ -646,7 +657,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
mysql_event_fill_row() calls my_error() in case of error so no need to
handle it here
*/
- if (mysql_event_fill_row(thd, table, parse_data, sp, FALSE))
+ if (mysql_event_fill_row(thd, table, parse_data, sp, saved_mode, FALSE))
goto end;
table->field[ET_FIELD_STATUS]->store((longlong)parse_data->status, TRUE);
@@ -661,6 +672,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
end:
if (table)
close_thread_tables(thd);
+ thd->variables.sql_mode= saved_mode;
DBUG_RETURN(test(ret));
}
@@ -691,6 +703,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
CHARSET_INFO *scs= system_charset_info;
TABLE *table= NULL;
sp_head *sp= thd->lex->sphead;
+ ulong saved_mode= thd->variables.sql_mode;
int ret= 1;
DBUG_ENTER("Event_db_repository::update_event");
@@ -698,6 +711,9 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
/* None or both must be set */
DBUG_ASSERT(new_dbname && new_name || new_dbname == new_name);
+ /* Reset sql_mode during data dictionary operations. */
+ thd->variables.sql_mode= 0;
+
if (open_event_table(thd, TL_WRITE, &table))
goto end;
@@ -736,7 +752,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
mysql_event_fill_row() calls my_error() in case of error so no need to
handle it here
*/
- if (mysql_event_fill_row(thd, table, parse_data, sp, TRUE))
+ if (mysql_event_fill_row(thd, table, parse_data, sp, saved_mode, TRUE))
goto end;
if (new_dbname)
@@ -755,6 +771,7 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
end:
if (table)
close_thread_tables(thd);
+ thd->variables.sql_mode= saved_mode;
DBUG_RETURN(test(ret));
}
@@ -950,13 +967,17 @@ bool
Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname,
LEX_STRING name, Event_basic *etn)
{
- TABLE *table= NULL;
bool ret;
+ TABLE *table= NULL;
+ ulong saved_mode= thd->variables.sql_mode;
DBUG_ENTER("Event_db_repository::load_named_event");
DBUG_PRINT("enter",("thd: 0x%lx name: %*s", (long) thd,
(int) name.length, name.str));
+ /* Reset sql_mode during data dictionary operations. */
+ thd->variables.sql_mode= 0;
+
if (!(ret= open_event_table(thd, TL_READ, &table)))
{
if ((ret= find_named_event(dbname, name, table)))
@@ -967,7 +988,7 @@ Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname,
close_thread_tables(thd);
}
-
+ thd->variables.sql_mode= saved_mode;
DBUG_RETURN(ret);
}
diff --git a/sql/item.cc b/sql/item.cc
index c546badd8e7..ab9243fcaf5 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2628,6 +2628,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
if (entry && entry->value)
{
item_result_type= entry->type;
+ unsigned_flag= entry->unsigned_flag;
if (strict_type && required_result_type != item_result_type)
DBUG_RETURN(1);
switch (item_result_type) {
@@ -2925,7 +2926,7 @@ const String *Item_param::query_val_str(String* str) const
{
switch (state) {
case INT_VALUE:
- str->set(value.integer, &my_charset_bin);
+ str->set_int(value.integer, unsigned_flag, &my_charset_bin);
break;
case REAL_VALUE:
str->set_real(value.real, NOT_FIXED_DEC, &my_charset_bin);
diff --git a/sql/log.cc b/sql/log.cc
index fce1eb076db..9b5b2ae5a6c 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -73,23 +73,28 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all);
*/
class Silence_log_table_errors : public Internal_error_handler
{
+ char m_message[MYSQL_ERRMSG_SIZE];
public:
Silence_log_table_errors()
- {}
+ {
+ m_message[0]= '\0';
+ }
virtual ~Silence_log_table_errors() {}
virtual bool handle_error(uint sql_errno, const char *message,
MYSQL_ERROR::enum_warning_level level,
THD *thd);
+ const char *message() const { return m_message; }
};
bool
Silence_log_table_errors::handle_error(uint /* sql_errno */,
- const char * /* message */,
+ const char *message_arg,
MYSQL_ERROR::enum_warning_level /* level */,
THD * /* thd */)
{
+ strmake(m_message, message_arg, sizeof(m_message)-1);
return TRUE;
}
@@ -436,8 +441,9 @@ bool Log_to_csv_event_handler::
result= FALSE;
err:
- if (result)
- sql_print_error("Failed to write to mysql.general_log");
+ if (result && !thd->killed)
+ sql_print_error("Failed to write to mysql.general_log: %s",
+ error_handler.message());
if (need_rnd_end)
{
@@ -495,11 +501,13 @@ bool Log_to_csv_event_handler::
bool result= TRUE;
bool need_close= FALSE;
bool need_rnd_end= FALSE;
+ Silence_log_table_errors error_handler;
Open_tables_state open_tables_backup;
CHARSET_INFO *client_cs= thd->variables.character_set_client;
bool save_time_zone_used;
DBUG_ENTER("Log_to_csv_event_handler::log_slow");
+ thd->push_internal_handler(& error_handler);
/*
CSV uses TIME_to_timestamp() internally if table needs to be repaired
which will set thd->time_zone_used
@@ -629,8 +637,11 @@ bool Log_to_csv_event_handler::
result= FALSE;
err:
- if (result)
- sql_print_error("Failed to write to mysql.slow_log");
+ thd->pop_internal_handler();
+
+ if (result && !thd->killed)
+ sql_print_error("Failed to write to mysql.slow_log: %s",
+ error_handler.message());
if (need_rnd_end)
{
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 1d6990b36f1..ea7482ca067 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1034,7 +1034,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
bool check_access(THD *thd, ulong access, const char *db, ulong *save_priv,
bool no_grant, bool no_errors, bool schema_db);
bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
- bool no_errors);
+ uint number, bool no_errors);
bool check_global_access(THD *thd, ulong want_access);
#else
inline bool check_access(THD *thd, ulong access, const char *db,
@@ -1046,7 +1046,7 @@ inline bool check_access(THD *thd, ulong access, const char *db,
return false;
}
inline bool check_table_access(THD *thd, ulong want_access, TABLE_LIST *tables,
- bool no_errors)
+ uint number, bool no_errors)
{ return false; }
inline bool check_global_access(THD *thd, ulong want_access)
{ return false; }
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 61f3735fe62..08ecc025332 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -221,6 +221,11 @@ extern "C" int gethostname(char *name, int namelen);
/* Constants */
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
+/*
+ WARNING: When adding new SQL modes don't forget to update the
+ tables definitions that stores it's value.
+ (ie: mysql.event, mysql.proc)
+*/
static const char *sql_mode_names[]=
{
"REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
@@ -2179,6 +2184,16 @@ static void check_data_home(const char *path)
#define UNSAFE_DEFAULT_LINUX_THREADS 200
#endif
+
+#if BACKTRACE_DEMANGLE
+#include <cxxabi.h>
+extern "C" char *my_demangle(const char *mangled_name, int *status)
+{
+ return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
+}
+#endif
+
+
extern "C" sig_handler handle_segfault(int sig)
{
time_t curr_time;
@@ -2250,10 +2265,29 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
}
if (thd)
{
+ const char *kreason= "UNKNOWN";
+ switch (thd->killed) {
+ case THD::NOT_KILLED:
+ kreason= "NOT_KILLED";
+ break;
+ case THD::KILL_BAD_DATA:
+ kreason= "KILL_BAD_DATA";
+ break;
+ case THD::KILL_CONNECTION:
+ kreason= "KILL_CONNECTION";
+ break;
+ case THD::KILL_QUERY:
+ kreason= "KILL_QUERY";
+ break;
+ case THD::KILLED_NO_VALUE:
+ kreason= "KILLED_NO_VALUE";
+ break;
+ }
fprintf(stderr, "Trying to get some variables.\n\
Some pointers may be invalid and cause the dump to abort...\n");
safe_print_str("thd->query", thd->query, 1024);
fprintf(stderr, "thd->thread_id=%lu\n", (ulong) thd->thread_id);
+ fprintf(stderr, "thd->killed=%s\n", kreason);
}
fprintf(stderr, "\
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 3e9a484126a..03f790b934f 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -33,7 +33,10 @@ Relay_log_info::Relay_log_info()
:Slave_reporting_capability("SQL"),
no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id),
info_fd(-1), cur_log_fd(-1), save_temporary_tables(0),
- group_relay_log_pos(0),
+ group_relay_log_pos(0), event_relay_log_pos(0),
+#if HAVE_purify
+ is_fake(FALSE),
+#endif
cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0),
ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0),
abort_pos_wait(0), slave_run_id(0), sql_thd(0),
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index a3a57ad4ce9..36daffae1af 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -154,6 +154,10 @@ public:
ulonglong event_relay_log_pos;
ulonglong future_event_relay_log_pos;
+#ifdef HAVE_purify
+ bool is_fake; /* Mark that this is a fake relay log info structure */
+#endif
+
/*
Original log name and position of the group we're currently executing
(whose coordinates are group_relay_log_name/pos in the relay log)
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 410608f154f..4c77cbfff82 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1021,7 +1021,7 @@ bool sys_var_set::update(THD *thd, set_var *var)
{
*value= var->save_result.ulong_value;
return 0;
-};
+}
uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
diff --git a/sql/slave.cc b/sql/slave.cc
index 4ffc2023e85..9dd52c60dad 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1892,14 +1892,21 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
if (exec_res == 0)
{
int error= ev->update_pos(rli);
- char buf[22];
- DBUG_PRINT("info", ("update_pos error = %d", error));
- DBUG_PRINT("info", ("group %s %s",
- llstr(rli->group_relay_log_pos, buf),
- rli->group_relay_log_name));
- DBUG_PRINT("info", ("event %s %s",
- llstr(rli->event_relay_log_pos, buf),
- rli->event_relay_log_name));
+#ifdef HAVE_purify
+ if (!rli->is_fake)
+#endif
+ {
+#ifndef DBUG_OFF
+ char buf[22];
+#endif
+ DBUG_PRINT("info", ("update_pos error = %d", error));
+ DBUG_PRINT("info", ("group %s %s",
+ llstr(rli->group_relay_log_pos, buf),
+ rli->group_relay_log_name));
+ DBUG_PRINT("info", ("event %s %s",
+ llstr(rli->event_relay_log_pos, buf),
+ rli->event_relay_log_name));
+ }
/*
The update should not fail, so print an error message and
return an error code.
@@ -1909,6 +1916,7 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli,
*/
if (error)
{
+ char buf[22];
rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
"It was not possible to update the positions"
" of the relay log information: the slave may"
diff --git a/sql/sp.cc b/sql/sp.cc
index 99ffc18deea..83995e9b753 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -388,7 +388,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
uint length;
char buff[65];
String str(buff, sizeof(buff), &my_charset_bin);
- ulong sql_mode;
+ ulong sql_mode, saved_mode= thd->variables.sql_mode;
Open_tables_state open_tables_state_backup;
Stored_program_creation_ctx *creation_ctx;
@@ -400,6 +400,9 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
+ /* Reset sql_mode during data dictionary operations. */
+ thd->variables.sql_mode= 0;
+
if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
goto done;
@@ -503,10 +506,36 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
done:
if (table)
close_system_tables(thd, &open_tables_state_backup);
+ thd->variables.sql_mode= saved_mode;
DBUG_RETURN(ret);
}
+/**
+ Silence DEPRECATED SYNTAX warnings when loading a stored procedure
+ into the cache.
+*/
+struct Silence_deprecated_warning : public Internal_error_handler
+{
+public:
+ virtual bool handle_error(uint sql_errno, const char *message,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd);
+};
+
+bool
+Silence_deprecated_warning::handle_error(uint sql_errno, const char *message,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd)
+{
+ if (sql_errno == ER_WARN_DEPRECATED_SYNTAX &&
+ level == MYSQL_ERROR::WARN_LEVEL_WARN)
+ return TRUE;
+
+ return FALSE;
+}
+
+
static int
db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
ulong sql_mode, const char *params, const char *returns,
@@ -523,7 +552,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
ulong old_sql_mode= thd->variables.sql_mode;
ha_rows old_select_limit= thd->variables.select_limit;
sp_rcontext *old_spcont= thd->spcont;
-
+ Silence_deprecated_warning warning_handler;
+
char definer_user_name_holder[USERNAME_LENGTH + 1];
LEX_STRING definer_user_name= { definer_user_name_holder,
USERNAME_LENGTH };
@@ -583,7 +613,9 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
lex_start(thd);
+ thd->push_internal_handler(&warning_handler);
ret= parse_sql(thd, &lip, creation_ctx) || newlex.sphead == NULL;
+ thd->pop_internal_handler();
/*
Force switching back to the saved current database (if changed),
@@ -675,6 +707,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
int ret;
TABLE *table;
char definer[USER_HOST_BUFF_SIZE];
+ ulong saved_mode= thd->variables.sql_mode;
CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
@@ -689,6 +722,9 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
type == TYPE_ENUM_FUNCTION);
+ /* Reset sql_mode during data dictionary operations. */
+ thd->variables.sql_mode= 0;
+
/*
This statement will be replicated as a statement, even when using
row-based replication. The flag will be reset at the end of the
@@ -790,7 +826,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_SQL_MODE]->
- store((longlong)thd->variables.sql_mode, TRUE);
+ store((longlong)saved_mode, TRUE);
if (sp->m_chistics->comment.str)
{
@@ -890,6 +926,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
done:
thd->count_cuted_fields= saved_count_cuted_fields;
+ thd->variables.sql_mode= saved_mode;
close_thread_tables(thd);
DBUG_RETURN(ret);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 0edb566ed9f..8e6f5a96640 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -2309,7 +2309,7 @@ bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
bzero((char*) &tables,sizeof(tables));
tables.db= (char*) "mysql";
tables.table_name= tables.alias= (char*) "proc";
- *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1) ||
+ *full_access= (!check_table_access(thd, SELECT_ACL, &tables, 1, TRUE) ||
(!strcmp(sp->m_definer_user.str,
thd->security_ctx->priv_user) &&
!strcmp(sp->m_definer_host.str,
@@ -2753,7 +2753,7 @@ int sp_instr::exec_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
Check whenever we have access to tables for this statement
and open and lock them before executing instructions core function.
*/
- if (check_table_access(thd, SELECT_ACL, tables, 0)
+ if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE)
|| open_and_lock_tables(thd, tables))
result= -1;
else
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 0d563ab9051..b04f624f746 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -3041,6 +3041,12 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
}
#endif
+ /*
+ The lock api is depending on the thd->lex variable which needs to be
+ re-initialized.
+ */
+ Query_tables_list backup;
+ thd->lex->reset_n_backup_query_tables_list(&backup);
if (simple_open_n_lock_tables(thd,tables))
{ // Should never happen
close_thread_tables(thd); /* purecov: deadcode */
@@ -3173,6 +3179,7 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
send_ok(thd);
/* Tables are automatically closed */
+ thd->lex->restore_backup_query_tables_list(&backup);
DBUG_RETURN(result);
}
@@ -3862,7 +3869,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
of other queries). For simple queries first_not_own_table is 0.
*/
for (i= 0, table= tables;
- table != first_not_own_table && i < number;
+ i < number && table != first_not_own_table;
table= table->next_global, i++)
{
/* Remove SHOW_VIEW_ACL, because it will be checked during making view */
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 799cb673a0e..e5a5b51fcf6 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -799,7 +799,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild)
table_list.table_name= share->table_name.str;
table_list.grant.privilege=0;
- if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list,1))
+ if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list, 1, TRUE))
continue;
/* need to check if we haven't already listed it */
for (table= open_list ; table ; table=table->next)
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 04f408453ea..f1fbe6eb4b7 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -56,6 +56,9 @@ void mysql_client_binlog_statement(THD* thd)
if (!thd->rli_fake)
{
thd->rli_fake= new Relay_log_info;
+#ifdef HAVE_purify
+ thd->rli_fake->is_fake= TRUE;
+#endif
have_fd_event= FALSE;
}
if (thd->rli_fake && !thd->rli_fake->relay_log.description_event_for_exec)
diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h
index 9a765120895..97accefe8aa 100644
--- a/sql/sql_bitmap.h
+++ b/sql/sql_bitmap.h
@@ -65,7 +65,7 @@ public:
my_bool is_clear_all() const { return bitmap_is_clear_all(&map); }
my_bool is_set_all() const { return bitmap_is_set_all(&map); }
my_bool is_subset(const Bitmap& map2) const { return bitmap_is_subset(&map, &map2.map); }
- my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, map2.map); }
+ my_bool is_overlapping(const Bitmap& map2) const { return bitmap_is_overlapping(&map, &map2.map); }
my_bool operator==(const Bitmap& map2) const { return bitmap_cmp(&map, &map2.map); }
char *print(char *buf) const
{
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 7e54f87fe14..ae6765c7934 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1384,7 +1384,7 @@ def_week_frmt: %lu",
table_list.db = table->db();
table_list.alias= table_list.table_name= table->table();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_table_access(thd,SELECT_ACL,&table_list,1))
+ if (check_table_access(thd,SELECT_ACL,&table_list, 1, TRUE))
{
DBUG_PRINT("qcache",
("probably no SELECT access to %s.%s => return to normal processing",
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 75376c53f68..5180cafc774 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -406,7 +406,7 @@ Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg,
m_affected_rows= affected_rows_arg;
m_last_insert_id= last_insert_id_arg;
if (message_arg)
- strmake(m_message, message_arg, sizeof(m_message));
+ strmake(m_message, message_arg, sizeof(m_message) - 1);
else
m_message[0]= '\0';
m_status= DA_OK;
@@ -456,7 +456,7 @@ Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg,
DBUG_ASSERT(! is_set() || can_overwrite_status);
m_sql_errno= sql_errno_arg;
- strmake(m_message, message_arg, sizeof(m_message));
+ strmake(m_message, message_arg, sizeof(m_message) - 1);
m_status= DA_ERROR;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index c535d6a714b..031ceddde9a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -503,7 +503,7 @@ static bool check_merge_table_access(THD *thd, char *db,
tlist->db= db; /* purecov: inspected */
}
error= check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
- table_list,0);
+ table_list, UINT_MAX, FALSE);
}
return error;
}
@@ -2046,7 +2046,7 @@ mysql_execute_command(THD *thd)
res= check_table_access(thd,
lex->exchange ? SELECT_ACL | FILE_ACL :
SELECT_ACL,
- all_tables, 0);
+ all_tables, UINT_MAX, FALSE);
}
else
res= check_access(thd,
@@ -2071,7 +2071,7 @@ mysql_execute_command(THD *thd)
break;
}
case SQLCOM_DO:
- if (check_table_access(thd, SELECT_ACL, all_tables, 0) ||
+ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
open_and_lock_tables(thd, all_tables))
goto error;
@@ -2181,7 +2181,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_BACKUP_TABLE:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_table_access(thd, SELECT_ACL, all_tables, 0) ||
+ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
@@ -2193,7 +2193,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_RESTORE_TABLE:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_table_access(thd, INSERT_ACL, all_tables, 0) ||
+ if (check_table_access(thd, INSERT_ACL, all_tables, UINT_MAX, FALSE) ||
check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
@@ -2270,14 +2270,14 @@ mysql_execute_command(THD *thd)
#endif /* HAVE_REPLICATION */
case SQLCOM_SHOW_ENGINE_STATUS:
{
- if (check_global_access(thd, SUPER_ACL))
+ if (check_global_access(thd, PROCESS_ACL))
goto error;
res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
break;
}
case SQLCOM_SHOW_ENGINE_MUTEX:
{
- if (check_global_access(thd, SUPER_ACL))
+ if (check_global_access(thd, PROCESS_ACL))
goto error;
res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
break;
@@ -2734,7 +2734,8 @@ end_with_restore_list:
case SQLCOM_CHECKSUM:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables, 0))
+ if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables,
+ UINT_MAX, FALSE))
goto error; /* purecov: inspected */
res = mysql_checksum_table(thd, first_table, &lex->check_opt);
break;
@@ -2742,7 +2743,8 @@ end_with_restore_list:
case SQLCOM_REPAIR:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0))
+ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
+ UINT_MAX, FALSE))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res= mysql_repair_table(thd, first_table, &lex->check_opt);
@@ -2761,7 +2763,8 @@ end_with_restore_list:
case SQLCOM_CHECK:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables, 0))
+ if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables,
+ UINT_MAX, FALSE))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_check_table(thd, first_table, &lex->check_opt);
@@ -2772,7 +2775,8 @@ end_with_restore_list:
case SQLCOM_ANALYZE:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0))
+ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
+ UINT_MAX, FALSE))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
@@ -2792,7 +2796,8 @@ end_with_restore_list:
case SQLCOM_OPTIMIZE:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables, 0))
+ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
+ UINT_MAX, FALSE))
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
@@ -3121,7 +3126,7 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (!lex->drop_temporary)
{
- if (check_table_access(thd, DROP_ACL, all_tables, 0))
+ if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE))
goto error; /* purecov: inspected */
if (end_active_trans(thd))
goto error;
@@ -3225,7 +3230,7 @@ end_with_restore_list:
if (lex->autocommit && end_active_trans(thd))
goto error;
- if ((check_table_access(thd, SELECT_ACL, all_tables, 0) ||
+ if ((check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
open_and_lock_tables(thd, all_tables)))
goto error;
if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
@@ -3267,7 +3272,8 @@ end_with_restore_list:
/* we must end the trasaction first, regardless of anything */
if (end_active_trans(thd))
goto error;
- if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0))
+ if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
+ UINT_MAX, FALSE))
goto error;
thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK;
@@ -3761,7 +3767,7 @@ end_with_restore_list:
#endif
case SQLCOM_HA_OPEN:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
- if (check_table_access(thd, SELECT_ACL, all_tables, 0))
+ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))
goto error;
res= mysql_ha_open(thd, first_table, 0);
break;
@@ -4009,7 +4015,7 @@ create_sp_error:
This will cache all SP and SF and open and lock all tables
required for execution.
*/
- if (check_table_access(thd, SELECT_ACL, all_tables, 0) ||
+ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
open_and_lock_tables(thd, all_tables))
goto error;
@@ -4356,7 +4362,7 @@ create_sp_error:
}
case SQLCOM_DROP_VIEW:
{
- if (check_table_access(thd, DROP_ACL, all_tables, 0) ||
+ if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE) ||
end_active_trans(thd))
goto error;
/* Conditionally writes to binlog. */
@@ -4832,7 +4838,7 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
subselects_tables= subselects_tables->next_global;
}
if (subselects_tables &&
- (check_table_access(thd, SELECT_ACL, subselects_tables, 0)))
+ (check_table_access(thd, SELECT_ACL, subselects_tables, UINT_MAX, FALSE)))
return 1;
}
return 0;
@@ -5066,11 +5072,12 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
/**
Check the privilege for all used tables.
- @param thd Thread context
- @param want_access Privileges requested
- @param tables List of tables to be checked
- @param no_errors FALSE/TRUE - report/don't report error to
- the client (using my_error() call).
+ @param thd Thread context
+ @param want_access Privileges requested
+ @param tables List of tables to be checked
+ @param number Check at most this number of tables.
+ @param no_errors FALSE/TRUE - report/don't report error to
+ the client (using my_error() call).
@note
Table privileges are cached in the table list for GRANT checking.
@@ -5079,25 +5086,25 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
(the latter should be either 0 or point to next_global member
of one of elements of this table list).
- @retval
- FALSE OK
- @retval
- TRUE Access denied
+ @retval FALSE OK
+ @retval TRUE Access denied
*/
bool
check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
- bool no_errors)
+ uint number, bool no_errors)
{
TABLE_LIST *org_tables= tables;
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
+ uint i= 0;
Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
/*
The check that first_not_own_table is not reached is for the case when
the given table list refers to the list for prelocking (contains tables
of other queries). For simple queries first_not_own_table is 0.
*/
- for (; tables != first_not_own_table; tables= tables->next_global)
+ for (; i < number && tables != first_not_own_table;
+ tables= tables->next_global, i++)
{
if (tables->security_ctx)
sctx= tables->security_ctx;
@@ -5147,7 +5154,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
}
thd->security_ctx= backup_ctx;
return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
- test(want_access & EXTRA_ACL), UINT_MAX, no_errors);
+ test(want_access & EXTRA_ACL), number, no_errors);
deny:
thd->security_ctx= backup_ctx;
return TRUE;
@@ -6876,7 +6883,7 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
/* sql_yacc guarantees that tables and aux_tables are not zero */
DBUG_ASSERT(aux_tables != 0);
- if (check_table_access(thd, SELECT_ACL, tables, 0))
+ if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
DBUG_RETURN(TRUE);
/*
@@ -6885,7 +6892,7 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
call check_table_access() safely.
*/
thd->lex->query_tables_own_last= 0;
- if (check_table_access(thd, DELETE_ACL, aux_tables, 0))
+ if (check_table_access(thd, DELETE_ACL, aux_tables, UINT_MAX, FALSE))
{
thd->lex->query_tables_own_last= save_query_tables_own_last;
DBUG_RETURN(TRUE);
@@ -7124,7 +7131,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
}
}
#endif
- if (tables && check_table_access(thd, SELECT_ACL, tables,0))
+ if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
goto err;
}
else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index bae4a85fd8a..74c99b5773d 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1638,7 +1638,7 @@ bool mysql_install_plugin(THD *thd, const LEX_STRING *name, const LEX_STRING *dl
bzero(&tables, sizeof(tables));
tables.db= (char *)"mysql";
tables.table_name= tables.alias= (char *)"plugin";
- if (check_table_access(thd, INSERT_ACL, &tables, 0))
+ if (check_table_access(thd, INSERT_ACL, &tables, 1, FALSE))
DBUG_RETURN(TRUE);
/* need to open before acquiring LOCK_plugin or it will deadlock */
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index c0178a231c9..5a903a4fe1c 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1280,7 +1280,7 @@ static int mysql_test_select(Prepared_statement *stmt,
ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL;
if (tables)
{
- if (check_table_access(thd, privilege, tables,0))
+ if (check_table_access(thd, privilege, tables, UINT_MAX, FALSE))
goto error;
}
else if (check_access(thd, privilege, any_db,0,0,0,0))
@@ -1349,7 +1349,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt,
THD *thd= stmt->thd;
DBUG_ENTER("mysql_test_do_fields");
- if (tables && check_table_access(thd, SELECT_ACL, tables, 0))
+ if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
DBUG_RETURN(TRUE);
if (open_normal_and_derived_tables(thd, tables, 0))
@@ -1380,7 +1380,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt,
THD *thd= stmt->thd;
set_var_base *var;
- if (tables && check_table_access(thd, SELECT_ACL, tables, 0) ||
+ if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE) ||
open_normal_and_derived_tables(thd, tables, 0))
goto error;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index ee0a6d3c2ab..6d817cb0620 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -4059,7 +4059,7 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
proc_tables.table_name= proc_tables.alias= (char*) "proc";
proc_tables.table_name_length= 4;
proc_tables.lock_type= TL_READ;
- full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1);
+ full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1, TRUE);
if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
{
DBUG_RETURN(1);
@@ -4447,10 +4447,8 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
Table_triggers_list *triggers= tables->table->triggers;
int event, timing;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_table_access(thd, TRIGGER_ACL, tables, 1))
+ if (check_table_access(thd, TRIGGER_ACL, tables, 1, TRUE))
goto ret;
-#endif
for (event= 0; event < (int)TRG_EVENT_MAX; event++)
{
@@ -4488,9 +4486,7 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
}
}
}
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
ret:
-#endif
DBUG_RETURN(0);
}
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 4bf23dc52f9..4cd1d542375 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -422,7 +422,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
thd->lex->query_tables_own_last= 0;
- err_status= check_table_access(thd, TRIGGER_ACL, tables, 0);
+ err_status= check_table_access(thd, TRIGGER_ACL, tables, 1, FALSE);
thd->lex->query_tables_own_last= save_query_tables_own_last;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index da301b37484..1a4d7d515a8 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1123,8 +1123,8 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
if (!table->prelocking_placeholder &&
(old_lex->sql_command == SQLCOM_SELECT && old_lex->describe))
{
- if (check_table_access(thd, SELECT_ACL, view_tables, 1) &&
- check_table_access(thd, SHOW_VIEW_ACL, table, 1))
+ if (check_table_access(thd, SELECT_ACL, view_tables, UINT_MAX, TRUE) &&
+ check_table_access(thd, SHOW_VIEW_ACL, table, UINT_MAX, TRUE))
{
my_message(ER_VIEW_NO_EXPLAIN, ER(ER_VIEW_NO_EXPLAIN), MYF(0));
goto err;
@@ -1134,7 +1134,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
(old_lex->sql_command == SQLCOM_SHOW_CREATE) &&
!table->belong_to_view)
{
- if (check_table_access(thd, SHOW_VIEW_ACL, table, 0))
+ if (check_table_access(thd, SHOW_VIEW_ACL, table, UINT_MAX, FALSE))
goto err;
}
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index b1267e20774..3d718dfd9d2 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -17,11 +17,16 @@
#include "stacktrace.h"
#include <signal.h>
#include <my_pthread.h>
+#include <m_string.h>
#ifdef HAVE_STACKTRACE
#include <unistd.h>
#include <strings.h>
+#if HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
char *heap_start;
@@ -93,9 +98,68 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
}
#endif /* defined(__alpha__) && defined(__GNUC__) */
+#if BACKTRACE_DEMANGLE
+static void my_demangle_symbols(char **addrs, int n)
+{
+ int status, i;
+ char *begin, *end, *demangled;
+
+ for (i= 0; i < n; i++)
+ {
+ demangled= NULL;
+ begin= strchr(addrs[i], '(');
+ end= begin ? strchr(begin, '+') : NULL;
+
+ if (begin && end)
+ {
+ *begin++= *end++= '\0';
+ demangled= my_demangle(begin, &status);
+ if (!demangled || status)
+ {
+ demangled= NULL;
+ begin[-1]= '(';
+ end[-1]= '+';
+ }
+ }
+
+ if (demangled)
+ fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end);
+ else
+ fprintf(stderr, "%s\n", addrs[i]);
+ }
+}
+#endif
+
+
+#if HAVE_BACKTRACE
+static void backtrace_current_thread(void)
+{
+ void *addrs[128];
+ char **strings= NULL;
+ int n = backtrace(addrs, array_elements(addrs));
+#if BACKTRACE_DEMANGLE
+ if ((strings= backtrace_symbols(addrs, n)))
+ {
+ my_demangle_symbols(strings, n);
+ free(strings);
+ }
+#endif
+#if HAVE_BACKTRACE_SYMBOLS_FD
+ if (!strings)
+ {
+ backtrace_symbols_fd(addrs, n, fileno(stderr));
+ }
+#endif
+}
+#endif
+
void print_stacktrace(uchar* stack_bottom, ulong thread_stack)
{
+#if HAVE_BACKTRACE
+ backtrace_current_thread();
+ return;
+#endif
uchar** fp;
uint frame_count = 0, sigreturn_frame_count;
#if defined(__alpha__) && defined(__GNUC__)
diff --git a/sql/stacktrace.h b/sql/stacktrace.h
index 1a0b80c88d3..96c09a21ad6 100644
--- a/sql/stacktrace.h
+++ b/sql/stacktrace.h
@@ -17,6 +17,14 @@
extern "C" {
#endif
+#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE
+#define BACKTRACE_DEMANGLE 1
+#endif
+
+#if BACKTRACE_DEMANGLE
+char *my_demangle(const char *mangled_name, int *status);
+#endif
+
#ifdef TARGET_OS_LINUX
#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
#undef HAVE_STACKTRACE