summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2019-03-17 13:06:41 +0100
committerSergei Golubchik <serg@mariadb.org>2019-03-17 13:06:41 +0100
commitb64fde8f38515dc39e019de26db7624cc0ea7046 (patch)
tree0478ea4c3ddeee290f6d381a47efa4f9aded9c0b /sql
parenta89ee3cd154a67df2231f034fd8339f9225dbe64 (diff)
parent1f020299f816263e347c852eb2a494b5ef1cbf0d (diff)
downloadmariadb-git-b64fde8f38515dc39e019de26db7624cc0ea7046.tar.gz
Merge branch '10.2' into 10.3
Diffstat (limited to 'sql')
-rw-r--r--sql/debug_sync.cc6
-rw-r--r--sql/encryption.cc15
-rw-r--r--sql/handler.h4
-rw-r--r--sql/item.cc1
-rw-r--r--sql/item_jsonfunc.cc4
-rw-r--r--sql/item_timefunc.cc18
-rw-r--r--sql/log_slow.h1
-rw-r--r--sql/mdl.h10
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/opt_range.cc17
-rw-r--r--sql/partition_info.cc9
-rw-r--r--sql/protocol.h67
-rw-r--r--sql/sql_acl.cc120
-rw-r--r--sql/sql_acl.h2
-rw-r--r--sql/sql_admin.cc2
-rw-r--r--sql/sql_admin.h8
-rw-r--r--sql/sql_alter.cc11
-rw-r--r--sql/sql_alter.h2
-rw-r--r--sql/sql_analyse.cc5
-rw-r--r--sql/sql_analyse.h5
-rw-r--r--sql/sql_class.cc19
-rw-r--r--sql/sql_class.h34
-rw-r--r--sql/sql_cmd.h14
-rw-r--r--sql/sql_connect.cc1
-rw-r--r--sql/sql_cte.cc1
-rw-r--r--sql/sql_handler.cc7
-rw-r--r--sql/sql_insert.cc6
-rw-r--r--sql/sql_lex.cc14
-rw-r--r--sql/sql_parse.cc166
-rw-r--r--sql/sql_partition_admin.cc1
-rw-r--r--sql/sql_plugin_services.ic3
-rw-r--r--sql/sql_prepare.cc31
-rw-r--r--sql/sql_priv.h6
-rw-r--r--sql/sql_select.cc12
-rw-r--r--sql/sql_select.h5
-rw-r--r--sql/sql_show.cc55
-rw-r--r--sql/sql_string.h20
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_trigger.cc4
-rw-r--r--sql/sql_union.cc27
-rw-r--r--sql/sql_view.cc25
-rw-r--r--sql/sql_yacc.yy5
-rw-r--r--sql/sql_yacc_ora.yy4
-rw-r--r--sql/table.h16
-rw-r--r--sql/tztime.cc8
-rw-r--r--sql/wsrep_dummy.cc3
-rw-r--r--sql/wsrep_thd.cc10
47 files changed, 371 insertions, 437 deletions
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index d25c1a75e96..357d8f4ce60 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -584,7 +584,7 @@ static void debug_sync_remove_action(st_debug_sync_control *ds_control,
memmove(save_action, action, sizeof(st_debug_sync_action));
/* Move actions down. */
- memmove(ds_control->ds_action + dsp_idx,
+ memmove((void*)(ds_control->ds_action + dsp_idx),
ds_control->ds_action + dsp_idx + 1,
(ds_control->ds_active - dsp_idx) *
sizeof(st_debug_sync_action));
@@ -595,8 +595,8 @@ static void debug_sync_remove_action(st_debug_sync_control *ds_control,
produced by the shift. Again do not use an assignment operator to
avoid string allocation/copy.
*/
- memmove(ds_control->ds_action + ds_control->ds_active, save_action,
- sizeof(st_debug_sync_action));
+ memmove((void*)(ds_control->ds_action + ds_control->ds_active),
+ save_action, sizeof(st_debug_sync_action));
}
DBUG_VOID_RETURN;
diff --git a/sql/encryption.cc b/sql/encryption.cc
index 3174968f9b3..0d75fdacd8f 100644
--- a/sql/encryption.cc
+++ b/sql/encryption.cc
@@ -25,6 +25,10 @@ struct encryption_service_st encryption_handler;
extern "C" {
+uint no_get_key(uint, uint, uchar*, uint*)
+{
+ return ENCRYPTION_KEY_VERSION_INVALID;
+}
uint no_key(uint)
{
return ENCRYPTION_KEY_VERSION_INVALID;
@@ -47,6 +51,11 @@ static unsigned int get_length(unsigned int slen, unsigned int key_id,
return my_aes_get_size(MY_AES_CBC, slen);
}
+uint ctx_size(unsigned int, unsigned int)
+{
+ return MY_AES_CTX_SIZE;
+}
+
} /* extern "C" */
int initialize_encryption_plugin(st_plugin_int *plugin)
@@ -72,8 +81,7 @@ int initialize_encryption_plugin(st_plugin_int *plugin)
if (handle->crypt_ctx_size)
encryption_handler.encryption_ctx_size_func= handle->crypt_ctx_size;
else
- encryption_handler.encryption_ctx_size_func=
- (uint (*)(unsigned int, unsigned int))my_aes_ctx_size;
+ encryption_handler.encryption_ctx_size_func= ctx_size;
encryption_handler.encryption_ctx_init_func=
handle->crypt_ctx_init ? handle->crypt_ctx_init : ctx_init;
@@ -102,8 +110,7 @@ int finalize_encryption_plugin(st_plugin_int *plugin)
if (used)
{
- encryption_handler.encryption_key_get_func=
- (uint (*)(uint, uint, uchar*, uint*))no_key;
+ encryption_handler.encryption_key_get_func= no_get_key;
encryption_handler.encryption_key_get_latest_version_func= no_key;
encryption_handler.encryption_ctx_size_func= zero_size;
}
diff --git a/sql/handler.h b/sql/handler.h
index 84231d77c63..8aaedcc69b9 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -2072,6 +2072,7 @@ struct Table_scope_and_contents_source_pod_st // For trivial members
/* The following is used to remember the old state for CREATE OR REPLACE */
TABLE *table;
TABLE_LIST *pos_in_locked_tables;
+ TABLE_LIST *merge_list;
MDL_ticket *mdl_ticket;
bool table_was_deleted;
sequence_definition *seq_create_info;
@@ -2099,14 +2100,11 @@ struct Table_scope_and_contents_source_pod_st // For trivial members
struct Table_scope_and_contents_source_st:
public Table_scope_and_contents_source_pod_st
{
- SQL_I_List<TABLE_LIST> merge_list;
-
Vers_parse_info vers_info;
void init()
{
Table_scope_and_contents_source_pod_st::init();
- merge_list.empty();
vers_info.init();
}
diff --git a/sql/item.cc b/sql/item.cc
index ada79fcb9df..7f4e69a3523 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2401,7 +2401,6 @@ void Item::split_sum_func2(THD *thd, Ref_ptr_array ref_pointer_array,
}
if (unlikely((!(used_tables() & ~PARAM_TABLE_BIT) ||
- type() == SUBSELECT_ITEM ||
(type() == REF_ITEM &&
((Item_ref*)this)->ref_type() != Item_ref::VIEW_REF))))
return;
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index fe8784a7073..960a6e9ccc8 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -680,11 +680,11 @@ static int alloc_tmp_paths(THD *thd, uint n_paths,
*paths= (json_path_with_flags *) alloc_root(root,
sizeof(json_path_with_flags) * n_paths);
- *tmp_paths= (String *) alloc_root(root, sizeof(String) * n_paths);
+
+ *tmp_paths= new (root) String[n_paths];
if (*paths == 0 || *tmp_paths == 0)
return 1;
- bzero(*tmp_paths, sizeof(String) * n_paths);
for (uint c_path=0; c_path < n_paths; c_path++)
(*tmp_paths)[c_path].set_charset(&my_charset_utf8_general_ci);
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 25fecd0a134..2339c6afbdc 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -456,7 +456,7 @@ err:
Create a formated date/time value in a string.
*/
-static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
+static bool make_date_time(const LEX_CSTRING &format, MYSQL_TIME *l_time,
timestamp_type type, const MY_LOCALE *locale,
String *str)
{
@@ -471,7 +471,7 @@ static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
if (l_time->neg)
str->append('-');
- end= (ptr= format->format.str) + format->format.length;
+ end= (ptr= format.str) + format.length;
for (; ptr != end ; ptr++)
{
if (*ptr != '%' || ptr+1 == end)
@@ -591,7 +591,7 @@ static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
str->append_with_prefill(intbuff, length, 2, '0');
break;
case 'j':
- if (type == MYSQL_TIMESTAMP_TIME)
+ if (type == MYSQL_TIMESTAMP_TIME || !l_time->month || !l_time->year)
return 1;
length= (uint) (int10_to_str(calc_daynr(l_time->year,l_time->month,
l_time->day) -
@@ -1992,6 +1992,7 @@ uint Item_func_date_format::format_length(const String *format)
String *Item_func_date_format::val_str(String *str)
{
+ StringBuffer<64> format_buffer;
String *format;
MYSQL_TIME l_time;
uint size;
@@ -2001,7 +2002,7 @@ String *Item_func_date_format::val_str(String *str)
if ((null_value= args[0]->get_date(&l_time, is_time_format ? TIME_TIME_ONLY : 0)))
return 0;
- if (!(format = args[1]->val_str(str)) || !format->length())
+ if (!(format= args[1]->val_str(&format_buffer)) || !format->length())
goto null_date;
if (!is_time_format && !(lc= locale) && !(lc= args[2]->locale_from_val_str()))
@@ -2015,18 +2016,13 @@ String *Item_func_date_format::val_str(String *str)
if (size < MAX_DATE_STRING_REP_LENGTH)
size= MAX_DATE_STRING_REP_LENGTH;
- if (format == str)
- str= &value; // Save result here
+ DBUG_ASSERT(format != str);
if (str->alloc(size))
goto null_date;
- DATE_TIME_FORMAT date_time_format;
- date_time_format.format.str= (char*) format->ptr();
- date_time_format.format.length= format->length();
-
/* Create the result string */
str->set_charset(collation.collation);
- if (!make_date_time(&date_time_format, &l_time,
+ if (!make_date_time(format->lex_cstring(), &l_time,
is_time_format ? MYSQL_TIMESTAMP_TIME :
MYSQL_TIMESTAMP_DATE,
lc, str))
diff --git a/sql/log_slow.h b/sql/log_slow.h
index 069c35173b9..8322f94ee3c 100644
--- a/sql/log_slow.h
+++ b/sql/log_slow.h
@@ -38,6 +38,7 @@
#define QPLAN_TMP_DISK (1U << 10)
/* ... */
+#define QPLAN_STATUS (1UL << 31) /* not in the slow_log_filter */
#define QPLAN_MAX (1UL << 31) /* reserved as placeholder */
/* Bits for log_slow_disabled_statements */
diff --git a/sql/mdl.h b/sql/mdl.h
index 952d97d301c..848b2497f43 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -470,6 +470,16 @@ public:
DBUG_ASSERT(ticket == NULL);
type= type_arg;
}
+ void move_from(MDL_request &from)
+ {
+ type= from.type;
+ duration= from.duration;
+ ticket= from.ticket;
+ next_in_list= from.next_in_list;
+ prev_in_list= from.prev_in_list;
+ key.mdl_key_init(&from.key);
+ from.ticket= NULL; // that's what "move" means
+ }
/**
Is this a request for a lock which allow data to be updated?
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index e0905a6f3ac..7a6a87a1412 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -9769,7 +9769,7 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
global_system_variables.binlog_format= BINLOG_FORMAT_ROW;
}
- if (!opt_bootstrap && WSREP_PROVIDER_EXISTS &&
+ if (!opt_bootstrap && WSREP_PROVIDER_EXISTS && WSREP_ON &&
global_system_variables.binlog_format != BINLOG_FORMAT_ROW)
{
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 2ea632675a3..b19504cff22 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1344,14 +1344,12 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
- Use rowids from unique to run a disk-ordered sweep
*/
-QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT(THD *thd_param,
- TABLE *table)
+QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT(THD *thd_param, TABLE *table)
:unique(NULL), pk_quick_select(NULL), thd(thd_param)
{
DBUG_ENTER("QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT");
index= MAX_KEY;
head= table;
- bzero(&read_record, sizeof(read_record));
init_sql_alloc(&alloc, "QUICK_INDEX_SORT_SELECT",
thd->variables.range_alloc_block_size, 0,
MYF(MY_THREAD_SPECIFIC));
@@ -5109,6 +5107,16 @@ typedef struct st_partial_index_intersect_info
key_map filtered_scans; /* scans to be filtered by cpk conditions */
MY_BITMAP *intersect_fields; /* bitmap of fields used in intersection */
+
+ void init()
+ {
+ common_info= NULL;
+ intersect_fields= NULL;
+ records_sent_to_unique= records= length= in_memory= use_cpk_filter= 0;
+ cost= index_read_cost= in_memory_cost= 0.0;
+ filtered_scans.init();
+ filtered_scans.clear_all();
+ }
} PARTIAL_INDEX_INTERSECT_INFO;
@@ -5245,8 +5253,7 @@ bool prepare_search_best_index_intersect(PARAM *param,
if (!n_index_scans)
return 1;
- bzero(init, sizeof(*init));
- init->filtered_scans.init();
+ init->init();
init->common_info= common;
init->cost= cutoff_cost;
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 2f021d6118c..34ccdbc1686 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -64,7 +64,7 @@ partition_info *partition_info::get_clone(THD *thd)
if (!part_clone)
DBUG_RETURN(NULL);
- memcpy(part_clone, part, sizeof(partition_element));
+ *part_clone= *part;
part_clone->subpartitions.empty();
while ((subpart= (subpart_it++)))
{
@@ -72,7 +72,7 @@ partition_info *partition_info::get_clone(THD *thd)
if (!subpart_clone)
DBUG_RETURN(NULL);
- memcpy(subpart_clone, subpart, sizeof(partition_element));
+ *subpart_clone= *subpart;
part_clone->subpartitions.push_back(subpart_clone, mem_root);
}
clone->partitions.push_back(part_clone, mem_root);
@@ -1432,12 +1432,11 @@ void partition_info::print_no_partition_found(TABLE *table_arg, myf errflag)
TABLE_LIST table_list;
THD *thd= current_thd;
- bzero(&table_list, sizeof(table_list));
+ table_list.reset();
table_list.db= table_arg->s->db;
table_list.table_name= table_arg->s->table_name;
- if (check_single_table_access(thd,
- SELECT_ACL, &table_list, TRUE))
+ if (check_single_table_access(thd, SELECT_ACL, &table_list, TRUE))
{
my_message(ER_NO_PARTITION_FOR_GIVEN_VALUE,
ER_THD(thd, ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT), errflag);
diff --git a/sql/protocol.h b/sql/protocol.h
index 6397e3dd5e6..1a6cb3bdc3c 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -230,60 +230,29 @@ class Protocol_discard : public Protocol_text
{
public:
Protocol_discard(THD *thd_arg) : Protocol_text(thd_arg) {}
- /* The real writing is done only in write() */
- virtual bool write() { return 0; }
- virtual bool send_result_set_metadata(List<Item> *list, uint flags)
- {
- // Don't pas Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF flags
- return Protocol_text::send_result_set_metadata(list, 0);
- }
-
- // send_error is intentionally not overloaded.
- virtual bool send_eof(uint server_status, uint statement_warn_count)
- {
- return 0;
- }
-
- void prepare_for_resend()
- {
-#ifndef DBUG_OFF
- field_pos= 0;
-#endif
- }
+ bool write() { return 0; }
+ bool send_result_set_metadata(List<Item> *, uint) { return 0; }
+ bool send_eof(uint, uint) { return 0; }
+ void prepare_for_resend() { IF_DBUG(field_pos= 0,); }
/*
Provide dummy overrides for any storage methods so that we
avoid allocating and copying of data
*/
- virtual bool store_null()
- { return false; }
- virtual bool store_tiny(longlong from)
- { return false; }
- virtual bool store_short(longlong from)
- { return false; }
- virtual bool store_long(longlong from)
- { return false; }
- virtual bool store_longlong(longlong from, bool unsigned_flag)
- { return false; }
- virtual bool store_decimal(const my_decimal *)
- { return false; }
- virtual bool store(const char *from, size_t length, CHARSET_INFO *cs)
- { return false; }
- virtual bool store(const char *from, size_t length,
- CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
- { return false; }
- virtual bool store(MYSQL_TIME *time, int decimals)
- { return false; }
- virtual bool store_date(MYSQL_TIME *time)
- { return false; }
- virtual bool store_time(MYSQL_TIME *time, int decimals)
- { return false; }
- virtual bool store(float nr, uint32 decimals, String *buffer)
- { return false; }
- virtual bool store(double from, uint32 decimals, String *buffer)
- { return false; }
- virtual bool store(Field *field)
- { return false; }
+ bool store_null() { return false; }
+ bool store_tiny(longlong) { return false; }
+ bool store_short(longlong) { return false; }
+ bool store_long(longlong) { return false; }
+ bool store_longlong(longlong, bool) { return false; }
+ bool store_decimal(const my_decimal *) { return false; }
+ bool store(const char *, size_t, CHARSET_INFO *) { return false; }
+ bool store(const char *, size_t, CHARSET_INFO *, CHARSET_INFO *) { return false; }
+ bool store(MYSQL_TIME *, int) { return false; }
+ bool store_date(MYSQL_TIME *) { return false; }
+ bool store_time(MYSQL_TIME *, int) { return false; }
+ bool store(float, uint32, String *) { return false; }
+ bool store(double, uint32, String *) { return false; }
+ bool store(Field *) { return false; }
};
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 16c70b3ed92..0b1749fd10d 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -681,7 +681,7 @@ enum enum_acl_tables
ROLES_MAPPING_TABLE,
TABLES_MAX // <== always the last
};
-// bits for open_grant_tables
+
static const int Table_user= 1 << USER_TABLE;
static const int Table_db= 1 << DB_TABLE;
static const int Table_tables_priv= 1 << TABLES_PRIV_TABLE;
@@ -762,7 +762,7 @@ class Grant_table_base
Grant_table_base() : start_privilege_column(0), num_privilege_cols(0)
{
- bzero(&tl, sizeof(tl));
+ tl.reset();
};
/* Initialization sequence common for all grant tables. This should be called
@@ -8483,60 +8483,6 @@ static bool print_grants_for_role(THD *thd, ACL_ROLE * role)
}
-/** checks privileges for SHOW GRANTS and SHOW CREATE USER
-
- @note that in case of SHOW CREATE USER the parser guarantees
- that a role can never happen here, so *rolename will never
- be assigned to
-*/
-static bool check_show_access(THD *thd, LEX_USER *lex_user,
- const char **username,
- const char **hostname, const char **rolename)
-{
- DBUG_ENTER("check_show_access");
-
- if (lex_user->user.str == current_user.str)
- {
- *username= thd->security_ctx->priv_user;
- *hostname= thd->security_ctx->priv_host;
- }
- else if (lex_user->user.str == current_role.str)
- {
- *rolename= thd->security_ctx->priv_role;
- }
- else if (lex_user->user.str == current_user_and_current_role.str)
- {
- *username= thd->security_ctx->priv_user;
- *hostname= thd->security_ctx->priv_host;
- *rolename= thd->security_ctx->priv_role;
- }
- else
- {
- Security_context *sctx= thd->security_ctx;
- bool do_check_access;
-
- lex_user= get_current_user(thd, lex_user);
- if (!lex_user)
- DBUG_RETURN(TRUE);
-
- if (lex_user->is_role())
- {
- *rolename= lex_user->user.str;
- do_check_access= strcmp(*rolename, sctx->priv_role);
- }
- else
- {
- *username= lex_user->user.str;
- *hostname= lex_user->host.str;
- do_check_access= strcmp(*username, sctx->priv_user) ||
- strcmp(*hostname, sctx->priv_host);
- }
-
- if (do_check_access && check_access(thd, SELECT_ACL, "mysql", 0, 0, 1, 0))
- DBUG_RETURN(TRUE);
- }
- DBUG_RETURN(FALSE);
-}
bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
{
@@ -8548,7 +8494,7 @@ bool mysql_show_create_user(THD *thd, LEX_USER *lex_user)
uint head_length;
DBUG_ENTER("mysql_show_create_user");
- if (check_show_access(thd, lex_user, &username, &hostname, NULL))
+ if (get_show_user(thd, lex_user, &username, &hostname, NULL))
DBUG_RETURN(TRUE);
List<Item> field_list;
@@ -8624,6 +8570,57 @@ void mysql_show_grants_get_fields(THD *thd, List<Item> *fields,
fields->push_back(field, thd->mem_root);
}
+/** checks privileges for SHOW GRANTS and SHOW CREATE USER
+
+ @note that in case of SHOW CREATE USER the parser guarantees
+ that a role can never happen here, so *rolename will never
+ be assigned to
+*/
+bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username,
+ const char **hostname, const char **rolename)
+{
+ if (lex_user->user.str == current_user.str)
+ {
+ *username= thd->security_ctx->priv_user;
+ *hostname= thd->security_ctx->priv_host;
+ return 0;
+ }
+ if (lex_user->user.str == current_role.str)
+ {
+ *rolename= thd->security_ctx->priv_role;
+ return 0;
+ }
+ if (lex_user->user.str == current_user_and_current_role.str)
+ {
+ *username= thd->security_ctx->priv_user;
+ *hostname= thd->security_ctx->priv_host;
+ *rolename= thd->security_ctx->priv_role;
+ return 0;
+ }
+
+ Security_context *sctx= thd->security_ctx;
+ bool do_check_access;
+
+ if (!(lex_user= get_current_user(thd, lex_user)))
+ return 1;
+
+ if (lex_user->is_role())
+ {
+ *rolename= lex_user->user.str;
+ do_check_access= strcmp(*rolename, sctx->priv_role);
+ }
+ else
+ {
+ *username= lex_user->user.str;
+ *hostname= lex_user->host.str;
+ do_check_access= strcmp(*username, sctx->priv_user) ||
+ strcmp(*hostname, sctx->priv_host);
+ }
+
+ if (do_check_access && check_access(thd, SELECT_ACL, "mysql", 0, 0, 1, 0))
+ return 1;
+ return 0;
+}
/*
SHOW GRANTS; Send grants for a user to the client
@@ -8648,15 +8645,16 @@ bool mysql_show_grants(THD *thd, LEX_USER *lex_user)
DBUG_RETURN(TRUE);
}
- if (check_show_access(thd, lex_user, &username, &hostname, &rolename))
+ if (get_show_user(thd, lex_user, &username, &hostname, &rolename))
DBUG_RETURN(TRUE);
+
DBUG_ASSERT(rolename || username);
List<Item> field_list;
- if (!username)
- end= strxmov(buff,"Grants for ",rolename, NullS);
- else
+ if (username)
end= strxmov(buff,"Grants for ",username,"@",hostname, NullS);
+ else
+ end= strxmov(buff,"Grants for ",rolename, NullS);
mysql_show_grants_get_fields(thd, &field_list, buff, (uint) (end-buff));
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index 6da7d4d5db4..cb49172a90c 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -254,6 +254,8 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table);
ulong get_column_grant(THD *thd, GRANT_INFO *grant,
const char *db_name, const char *table_name,
const char *field_name);
+bool get_show_user(THD *thd, LEX_USER *lex_user, const char **username,
+ const char **hostname, const char **rolename);
void mysql_show_grants_get_fields(THD *thd, List<Item> *fields,
const char *name, size_t length);
bool mysql_show_grants(THD *thd, LEX_USER *user);
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 914cd4d826b..4afe34ba18d 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -452,8 +452,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_ENTER("mysql_admin_table");
DBUG_PRINT("enter", ("extra_open_options: %u", extra_open_options));
- thd->prepare_logs_for_admin_command();
-
field_list.push_back(item= new (thd->mem_root)
Item_empty_string(thd, "Table",
NAME_CHAR_LEN * 2), thd->mem_root);
diff --git a/sql/sql_admin.h b/sql/sql_admin.h
index dea835c2de9..e7f4086540a 100644
--- a/sql/sql_admin.h
+++ b/sql/sql_admin.h
@@ -28,7 +28,7 @@ int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
/**
Sql_cmd_analyze_table represents the ANALYZE TABLE statement.
*/
-class Sql_cmd_analyze_table : public Sql_cmd_admin
+class Sql_cmd_analyze_table : public Sql_cmd
{
public:
/**
@@ -53,7 +53,7 @@ public:
/**
Sql_cmd_check_table represents the CHECK TABLE statement.
*/
-class Sql_cmd_check_table : public Sql_cmd_admin
+class Sql_cmd_check_table : public Sql_cmd
{
public:
/**
@@ -77,7 +77,7 @@ public:
/**
Sql_cmd_optimize_table represents the OPTIMIZE TABLE statement.
*/
-class Sql_cmd_optimize_table : public Sql_cmd_admin
+class Sql_cmd_optimize_table : public Sql_cmd
{
public:
/**
@@ -102,7 +102,7 @@ public:
/**
Sql_cmd_repair_table represents the REPAIR TABLE statement.
*/
-class Sql_cmd_repair_table : public Sql_cmd_admin
+class Sql_cmd_repair_table : public Sql_cmd
{
public:
/**
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc
index 5fc9ff8209c..0408808d800 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -402,7 +402,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
DBUG_RETURN(TRUE); /* purecov: inspected */
/* If it is a merge table, check privileges for merge children. */
- if (create_info.merge_list.first)
+ if (create_info.merge_list)
{
/*
The user must have (SELECT_ACL | UPDATE_ACL | DELETE_ACL) on the
@@ -440,7 +440,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
*/
if (check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
- create_info.merge_list.first, FALSE, UINT_MAX, FALSE))
+ create_info.merge_list, FALSE, UINT_MAX, FALSE))
DBUG_RETURN(TRUE);
}
@@ -451,9 +451,7 @@ bool Sql_cmd_alter_table::execute(THD *thd)
{
// Rename of table
TABLE_LIST tmp_table;
- memset(&tmp_table, 0, sizeof(tmp_table));
- tmp_table.table_name= lex->name;
- tmp_table.db= select_lex->db;
+ tmp_table.init_one_table(&select_lex->db, &lex->name, 0, TL_IGNORE);
tmp_table.grant.privilege= priv;
if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, FALSE,
UINT_MAX, FALSE))
@@ -471,7 +469,6 @@ bool Sql_cmd_alter_table::execute(THD *thd)
"INDEX DIRECTORY");
create_info.data_file_name= create_info.index_file_name= NULL;
- thd->prepare_logs_for_admin_command();
#ifdef WITH_PARTITION_STORAGE_ENGINE
thd->work_part_info= 0;
#endif
@@ -519,8 +516,6 @@ bool Sql_cmd_discard_import_tablespace::execute(THD *thd)
if (check_grant(thd, ALTER_ACL, table_list, false, UINT_MAX, false))
return true;
- thd->prepare_logs_for_admin_command();
-
/*
Check if we attempt to alter mysql.slow_log or
mysql.general_log table and return an error if
diff --git a/sql/sql_alter.h b/sql/sql_alter.h
index e2e7abe2a1c..14242015bd2 100644
--- a/sql/sql_alter.h
+++ b/sql/sql_alter.h
@@ -333,7 +333,7 @@ private:
statements.
@todo move Alter_info and other ALTER generic structures from Lex here.
*/
-class Sql_cmd_common_alter_table : public Sql_cmd_admin
+class Sql_cmd_common_alter_table : public Sql_cmd
{
protected:
/**
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 6626a054052..48e61177774 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -298,9 +298,9 @@ bool get_ev_num_info(EV_NUM_INFO *ev_info, NUM_INFO *info, const char *num)
} // get_ev_num_info
-int free_string(String *s)
+int free_string(void* str, TREE_FREE, void*)
{
- s->free();
+ ((String*)str)->free();
return 0;
}
@@ -1242,4 +1242,3 @@ uint check_ulonglong(const char *str, uint length)
while (*cmp && *cmp++ == *str++) ;
return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
} /* check_ulonlong */
-
diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h
index 6704de4ed6d..a76e1409659 100644
--- a/sql/sql_analyse.h
+++ b/sql/sql_analyse.h
@@ -68,7 +68,7 @@ int compare_ulonglong2(void* cmp_arg __attribute__((unused)),
int compare_decimal2(int* len, const char *s, const char *t);
Procedure *proc_analyse_init(THD *thd, ORDER *param, select_result *result,
List<Item> &field_list);
-int free_string(String*);
+int free_string(void* str, TREE_FREE, void*);
class analyse;
class field_info :public Sql_alloc
@@ -121,8 +121,7 @@ public:
must_be_blob(0), was_zero_fill(0),
was_maybe_zerofill(0), can_be_still_num(1)
{ init_tree(&tree, 0, 0, sizeof(String), (qsort_cmp2) sortcmp2,
- (tree_element_free) free_string, NULL,
- MYF(MY_THREAD_SPECIFIC)); };
+ free_string, NULL, MYF(MY_THREAD_SPECIFIC)); };
void add();
void get_opt_type(String*, ha_rows);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 9c9fa228e2a..4ff57856cd9 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2586,17 +2586,15 @@ CHANGED_TABLE_LIST* THD::changed_table_dup(const char *key, size_t key_length)
}
-void THD::prepare_explain_fields(select_result *result,
- List<Item> *field_list,
- uint8 explain_flags,
- bool is_analyze)
+int THD::prepare_explain_fields(select_result *result, List<Item> *field_list,
+ uint8 explain_flags, bool is_analyze)
{
if (lex->explain_json)
make_explain_json_field_list(*field_list, is_analyze);
else
make_explain_field_list(*field_list, explain_flags, is_analyze);
- result->prepare(*field_list, NULL);
+ return result->prepare(*field_list, NULL);
}
@@ -2606,11 +2604,10 @@ int THD::send_explain_fields(select_result *result,
{
List<Item> field_list;
int rc;
- prepare_explain_fields(result, &field_list, explain_flags, is_analyze);
- rc= result->send_result_set_metadata(field_list,
- Protocol::SEND_NUM_ROWS |
- Protocol::SEND_EOF);
- return(rc);
+ rc= prepare_explain_fields(result, &field_list, explain_flags, is_analyze) ||
+ result->send_result_set_metadata(field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF);
+ return rc;
}
@@ -2685,7 +2682,7 @@ void THD::make_explain_field_list(List<Item> &field_list, uint8 explain_flags,
if (is_analyze)
{
field_list.push_back(item= new (mem_root)
- Item_float(this, "r_rows", 0.1234, 10, 4),
+ Item_float(this, "r_rows", 0.1234, 2, 4),
mem_root);
item->maybe_null=1;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 69e6f58f854..e8083c5981b 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3801,8 +3801,8 @@ public:
void add_changed_table(TABLE *table);
void add_changed_table(const char *key, size_t key_length);
CHANGED_TABLE_LIST * changed_table_dup(const char *key, size_t key_length);
- void prepare_explain_fields(select_result *result, List<Item> *field_list,
- uint8 explain_flags, bool is_analyze);
+ int prepare_explain_fields(select_result *result, List<Item> *field_list,
+ uint8 explain_flags, bool is_analyze);
int send_explain_fields(select_result *result, uint8 explain_flags,
bool is_analyze);
void make_explain_field_list(List<Item> &field_list, uint8 explain_flags,
@@ -4836,11 +4836,6 @@ public:
Item *sp_fix_func_item(Item **it_addr);
Item *sp_prepare_func_item(Item **it_addr, uint cols= 1);
bool sp_eval_expr(Field *result_field, Item **expr_item_ptr);
-
- inline void prepare_logs_for_admin_command()
- {
- query_plan_flags|= QPLAN_ADMIN;
- }
};
inline void add_to_active_threads(THD *thd)
@@ -4945,6 +4940,7 @@ public:
void reset(THD *thd_arg) { thd= thd_arg; }
};
+class select_result_interceptor;
/*
Interface for sending tabular data, together with some other stuff:
@@ -5043,11 +5039,10 @@ public:
/*
This returns
- - FALSE if the class sends output row to the client
- - TRUE if the output is set elsewhere (a file, @variable, or table).
- Currently all intercepting classes derive from select_result_interceptor.
+ - NULL if the class sends output row to the client
+ - this if the output is set elsewhere (a file, @variable, or table).
*/
- virtual bool is_result_interceptor()=0;
+ virtual select_result_interceptor *result_interceptor()=0;
/*
This method is used to distinguish an normal SELECT from the cursor
@@ -5123,7 +5118,7 @@ public:
} /* Remove gcc warning */
uint field_count(List<Item> &fields) const { return 0; }
bool send_result_set_metadata(List<Item> &fields, uint flag) { return FALSE; }
- bool is_result_interceptor() { return true; }
+ select_result_interceptor *result_interceptor() { return this; }
/*
Instruct the object to not call my_ok(). Client output will be handled
@@ -5257,7 +5252,7 @@ public:
virtual bool check_simple_select() const { return FALSE; }
void abort_result_set();
virtual void cleanup();
- bool is_result_interceptor() { return false; }
+ select_result_interceptor *result_interceptor() { return NULL; }
};
@@ -6297,21 +6292,26 @@ public:
#define CF_UPDATES_DATA (1U << 18)
/**
+ Not logged into slow log as "admin commands"
+*/
+#define CF_ADMIN_COMMAND (1U << 19)
+
+/**
SP Bulk execution safe
*/
-#define CF_SP_BULK_SAFE (1U << 19)
+#define CF_SP_BULK_SAFE (1U << 20)
/**
SP Bulk execution optimized
*/
-#define CF_SP_BULK_OPTIMIZED (1U << 20)
+#define CF_SP_BULK_OPTIMIZED (1U << 21)
/**
If command creates or drops a table
*/
-#define CF_SCHEMA_CHANGE (1U << 21)
+#define CF_SCHEMA_CHANGE (1U << 22)
/**
If command creates or drops a database
*/
-#define CF_DB_CHANGE (1U << 22)
+#define CF_DB_CHANGE (1U << 23)
/* Bits in server_command_flags */
diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h
index 83dd1b1da4f..017dbca3e5e 100644
--- a/sql/sql_cmd.h
+++ b/sql/sql_cmd.h
@@ -160,8 +160,6 @@ public:
*/
virtual bool execute(THD *thd) = 0;
- virtual bool log_slow_enabled_statement(const THD *thd) const;
-
protected:
Sql_cmd()
{}
@@ -179,17 +177,6 @@ protected:
};
-class Sql_cmd_admin: public Sql_cmd
-{
-public:
- Sql_cmd_admin()
- {}
- ~Sql_cmd_admin()
- {}
- bool log_slow_enabled_statement(const THD *thd) const;
-};
-
-
/**
Sql_cmd_call represents the CALL statement.
*/
@@ -219,5 +206,4 @@ public:
}
};
-
#endif // SQL_CMD_INCLUDED
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 6881ca5956e..21cd164e2a8 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1189,7 +1189,6 @@ void end_connection(THD *thd)
}
thd->wsrep_client_thread= 0;
#endif
- plugin_thdvar_cleanup(thd);
if (thd->user_connect)
{
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index 24fd2c60503..01caeda1325 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -706,6 +706,7 @@ void With_element::move_anchors_ahead()
}
}
first_recursive= new_pos;
+ spec->first_select()->linkage= DERIVED_TABLE_TYPE;
}
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 817447fe917..f0a395d63d5 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -417,8 +417,6 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
sql_handler->reset();
}
sql_handler->table= table;
- memcpy(&sql_handler->mdl_request, &tables->mdl_request,
- sizeof(tables->mdl_request));
if (!(sql_handler->lock= get_lock_data(thd, &sql_handler->table, 1,
GET_LOCK_STORE_LOCKS)))
@@ -431,6 +429,8 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
if (unlikely(error))
goto err;
+ sql_handler->mdl_request.move_from(tables->mdl_request);
+
/* Always read all columns */
table->read_set= &table->s->all_set;
if (table->vcol_set)
@@ -470,9 +470,6 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen)
table_list->table->open_by_handler= 1;
}
- /* Safety, cleanup the pointer to satisfy MDL assertions. */
- tables->mdl_request.ticket= NULL;
-
if (! reopen)
my_ok(thd);
DBUG_PRINT("exit",("OK"));
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index c6c14bd6ffb..abe4254db3e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -4490,14 +4490,12 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
DBUG_ASSERT(thd->is_current_stmt_binlog_format_row());
DBUG_ASSERT(tables && *tables && count > 0);
- char buf[2048];
- String query(buf, sizeof(buf), system_charset_info);
+ StringBuffer<2048> query(system_charset_info);
int result;
TABLE_LIST tmp_table_list;
- memset(&tmp_table_list, 0, sizeof(tmp_table_list));
+ tmp_table_list.reset();
tmp_table_list.table = *tables;
- query.length(0); // Have to zero it since constructor doesn't
result= show_create_table(thd, &tmp_table_list, &query,
create_info, WITH_DB_NAME);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index d6cc62c9dbf..e75433eb417 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -5104,20 +5104,6 @@ bool LEX::is_partition_management() const
}
-bool Sql_cmd::log_slow_enabled_statement(const THD *thd) const
-{
- return global_system_variables.sql_log_slow && thd->variables.sql_log_slow;
-}
-
-
-bool Sql_cmd_admin::log_slow_enabled_statement(const THD *thd) const
-{
- return !MY_TEST(thd->variables.log_slow_disabled_statements &
- LOG_SLOW_DISABLE_ADMIN) &&
- Sql_cmd::log_slow_enabled_statement(thd);
-}
-
-
/**
Exclude last added SELECT_LEX (current) in the UNIT and return pointer in it
(previous become currect)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8eeb0fa3415..b8ed887b52d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -545,12 +545,14 @@ void init_update_queries(void)
CF_REEXECUTION_FRAGILE |
CF_AUTO_COMMIT_TRANS |
CF_SCHEMA_CHANGE);
- sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS |
+ CF_ADMIN_COMMAND | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS |
- CF_INSERTS_DATA;
+ CF_INSERTS_DATA | CF_ADMIN_COMMAND;
sql_command_flags[SQLCOM_ALTER_SEQUENCE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
- CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE;
+ CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE |
+ CF_ADMIN_COMMAND;
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE;
@@ -566,8 +568,9 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_DROP_PACKAGE_BODY]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_DB_CHANGE;
- sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
- sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_ADMIN_COMMAND;
+ sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS |
+ CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
@@ -747,10 +750,14 @@ void init_update_queries(void)
The following admin table operations are allowed
on log tables.
*/
- sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS;
- sql_command_flags[SQLCOM_OPTIMIZE]|= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS;
- sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS;
- sql_command_flags[SQLCOM_CHECK]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS |
+ CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
+ sql_command_flags[SQLCOM_OPTIMIZE]|= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS |
+ CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
+ sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS |
+ CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
+ sql_command_flags[SQLCOM_CHECK]= CF_WRITE_LOGS_COMMAND | CF_AUTO_COMMIT_TRANS |
+ CF_REPORT_PROGRESS | CF_ADMIN_COMMAND;
sql_command_flags[SQLCOM_CHECKSUM]= CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_CREATE_USER]|= CF_AUTO_COMMIT_TRANS;
@@ -1638,10 +1645,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->reset_for_next_command();
thd->set_command(command);
- /*
- thd->variables.log_slow_disabled_statements defines which statements
- are logged to slow log
- */
thd->enable_slow_log= true;
thd->query_plan_flags= QPLAN_INIT;
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
@@ -2086,7 +2089,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
status_var_increment(thd->status_var.com_other);
- thd->prepare_logs_for_admin_command();
+ thd->query_plan_flags|= QPLAN_ADMIN;
if (check_global_access(thd, REPL_SLAVE_ACL))
break;
@@ -2470,33 +2473,11 @@ com_multi_end:
DBUG_RETURN(error);
}
-
-static bool log_slow_enabled_statement(const THD *thd)
+static bool slow_filter_masked(THD *thd, ulonglong mask)
{
- /*
- TODO-10.4: Add classes Sql_cmd_create_index and Sql_cmd_drop_index
- for symmetry with other admin commands, so these statements can be
- handled by this command:
- */
- if (thd->lex->m_sql_cmd)
- return thd->lex->m_sql_cmd->log_slow_enabled_statement(thd);
-
- /*
- Currently CREATE INDEX or DROP INDEX cause a full table rebuild
- and thus classify as slow administrative statements just like
- ALTER TABLE.
- */
- if ((thd->lex->sql_command == SQLCOM_CREATE_INDEX ||
- thd->lex->sql_command == SQLCOM_DROP_INDEX) &&
- MY_TEST(thd->variables.log_slow_disabled_statements &
- LOG_SLOW_DISABLE_ADMIN))
- return true;
-
- return global_system_variables.sql_log_slow &&
- thd->variables.sql_log_slow;
+ return thd->variables.log_slow_filter && !(thd->variables.log_slow_filter & mask);
}
-
/*
Log query to slow queries, if it passes filtering
@@ -2527,11 +2508,16 @@ void log_slow_statement(THD *thd)
if (!thd->enable_slow_log)
goto end; // E.g. SP statement
+ DBUG_EXECUTE_IF("simulate_slow_query", {
+ if (thd->get_command() == COM_QUERY ||
+ thd->get_command() == COM_STMT_EXECUTE)
+ thd->server_status|= SERVER_QUERY_WAS_SLOW;
+ });
+
if ((thd->server_status &
(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
- !(sql_command_flags[thd->last_sql_command] & CF_STATUS_COMMAND) &&
- (!thd->variables.log_slow_filter ||
- (thd->variables.log_slow_filter & QPLAN_NOT_USING_INDEX)))
+ !(thd->query_plan_flags & QPLAN_STATUS) &&
+ !slow_filter_masked(thd, QPLAN_NOT_USING_INDEX))
{
thd->query_plan_flags|= QPLAN_NOT_USING_INDEX;
/* We are always logging no index queries if enabled in filter */
@@ -2543,7 +2529,15 @@ void log_slow_statement(THD *thd)
{
thd->status_var.long_query_count++;
- if (!log_slow_enabled_statement(thd))
+ /*
+ until log_slow_disabled_statements=admin is removed, it
+ duplicates slow_log_filter=admin
+ */
+ if ((thd->query_plan_flags & QPLAN_ADMIN) &&
+ (thd->variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_ADMIN))
+ goto end;
+
+ if (!global_system_variables.sql_log_slow || !thd->variables.sql_log_slow)
goto end;
/*
@@ -2558,8 +2552,7 @@ void log_slow_statement(THD *thd)
Follow the slow log filter configuration:
skip logging if the current statement matches the filter.
*/
- if (thd->variables.log_slow_filter &&
- !(thd->variables.log_slow_filter & thd->query_plan_flags))
+ if (slow_filter_masked(thd, thd->query_plan_flags))
goto end;
THD_STAGE_INFO(thd, stage_logging_slow_query);
@@ -3729,6 +3722,11 @@ mysql_execute_command(THD *thd)
goto error;
}
+ if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
+ thd->query_plan_flags|= QPLAN_STATUS;
+ if (sql_command_flags[lex->sql_command] & CF_ADMIN_COMMAND)
+ thd->query_plan_flags|= QPLAN_ADMIN;
+
/* Start timeouts */
thd->set_query_timer();
@@ -3792,12 +3790,14 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_PROFILE:
case SQLCOM_SELECT:
{
-#ifdef WITH_WSREP
if (lex->sql_command == SQLCOM_SELECT)
- WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ)
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_READ);
else
- WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW)
-#endif /* WITH_WSREP */
+ {
+ WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
+ if (lex->sql_command == SQLCOM_SHOW_PROFILE)
+ thd->profiling.discard_current_query();
+ }
thd->status_var.last_query_cost= 0.0;
@@ -4370,12 +4370,6 @@ end_with_restore_list:
if (check_one_table_access(thd, INDEX_ACL, all_tables))
goto error; /* purecov: inspected */
WSREP_TO_ISOLATION_BEGIN(first_table->db.str, first_table->table_name.str, NULL);
- /*
- Currently CREATE INDEX or DROP INDEX cause a full table rebuild
- and thus classify as slow administrative statements just like
- ALTER TABLE.
- */
- thd->prepare_logs_for_admin_command();
bzero((char*) &create_info, sizeof(create_info));
create_info.db_type= 0;
@@ -4538,48 +4532,6 @@ end_with_restore_list:
DBUG_PRINT("debug", ("lex->only_view: %d, table: %s.%s",
lex->table_type == TABLE_TYPE_VIEW,
first_table->db.str, first_table->table_name.str));
- if (lex->table_type == TABLE_TYPE_VIEW)
- {
- if (check_table_access(thd, SELECT_ACL, first_table, FALSE, 1, FALSE))
- {
- DBUG_PRINT("debug", ("check_table_access failed"));
- my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
- "SHOW", thd->security_ctx->priv_user,
- thd->security_ctx->host_or_ip, first_table->alias.str);
- goto error;
- }
- DBUG_PRINT("debug", ("check_table_access succeeded"));
-
- /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
- first_table->open_type= OT_BASE_ONLY;
- }
- else
- {
- /*
- Temporary tables should be opened for SHOW CREATE TABLE, but not
- for SHOW CREATE VIEW.
- */
- if (thd->open_temporary_tables(all_tables))
- goto error;
-
- /*
- The fact that check_some_access() returned FALSE does not mean that
- access is granted. We need to check if first_table->grant.privilege
- contains any table-specific privilege.
- */
- DBUG_PRINT("debug", ("first_table->grant.privilege: %lx",
- first_table->grant.privilege));
- if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, first_table) ||
- (first_table->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0)
- {
- my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
- "SHOW", thd->security_ctx->priv_user,
- thd->security_ctx->host_or_ip, first_table->alias.str);
- goto error;
- }
- }
-
- /* Access is granted. Execute the command. */
res= mysqld_show_create(thd, first_table);
break;
#endif
@@ -4932,7 +4884,7 @@ end_with_restore_list:
case SQLCOM_DELETE:
{
WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE);
- select_result *sel_result=lex->result;
+ select_result *sel_result= NULL;
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (WSREP_CLIENT(thd) &&
wsrep_sync_wait(thd, WSREP_SYNC_WAIT_BEFORE_UPDATE_DELETE))
@@ -4963,16 +4915,15 @@ end_with_restore_list:
}
else
{
- if (!(sel_result= lex->result) &&
- !(sel_result= new (thd->mem_root) select_send(thd)))
- return 1;
+ if (!lex->result && !(sel_result= new (thd->mem_root) select_send(thd)))
+ goto error;
}
}
res = mysql_delete(thd, all_tables,
select_lex->where, &select_lex->order_list,
unit->select_limit_cnt, select_lex->options,
- sel_result);
+ lex->result ? lex->result : sel_result);
if (replaced_protocol)
{
@@ -6325,8 +6276,6 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
/* fall through */
case SQLCOM_ALTER_SEQUENCE:
- thd->query_plan_flags|= QPLAN_ADMIN;
- /* fall through */
case SQLCOM_SIGNAL:
case SQLCOM_RESIGNAL:
case SQLCOM_GET_DIAGNOSTICS:
@@ -6579,8 +6528,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
Protocol *save_protocol= NULL;
if (lex->analyze_stmt)
{
- if (result && result->is_result_interceptor())
- ((select_result_interceptor*)result)->disable_my_ok_calls();
+ if (result && result->result_interceptor())
+ result->result_interceptor()->disable_my_ok_calls();
else
{
DBUG_ASSERT(thd->protocol);
@@ -7137,7 +7086,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
Check_grant will grant access if there is any column privileges on
all of the tables thanks to the fourth parameter (bool show_table).
*/
- if (check_grant(thd, SELECT_ACL, dst_table, TRUE, UINT_MAX, FALSE))
+ if (check_grant(thd, SELECT_ACL, dst_table, TRUE, 1, FALSE))
return TRUE; /* Access denied */
close_thread_tables(thd);
@@ -9664,7 +9613,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
goto err;
/* If it is a merge table, check privileges for merge children. */
- if (lex->create_info.merge_list.first)
+ if (lex->create_info.merge_list)
{
/*
The user must have (SELECT_ACL | UPDATE_ACL | DELETE_ACL) on the
@@ -9702,8 +9651,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
*/
if (check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
- lex->create_info.merge_list.first,
- FALSE, UINT_MAX, FALSE))
+ lex->create_info.merge_list, FALSE, UINT_MAX, FALSE))
goto err;
}
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index 2d3c640b758..cba4949ccd3 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -96,7 +96,6 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd)
DBUG_ASSERT(!create_info.data_file_name && !create_info.index_file_name);
WSREP_TO_ISOLATION_BEGIN_WRTCHK(NULL, NULL, first_table);
- thd->prepare_logs_for_admin_command();
DBUG_RETURN(exchange_partition(thd, first_table, &alter_info));
#ifdef WITH_WSREP
wsrep_error_label:
diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.ic
index f0ec917d411..db73dbb6913 100644
--- a/sql/sql_plugin_services.ic
+++ b/sql/sql_plugin_services.ic
@@ -183,7 +183,8 @@ static struct wsrep_service_st wsrep_handler = {
wsrep_trx_is_aborting,
wsrep_trx_order_before,
wsrep_unlock_rollback,
- wsrep_set_data_home_dir
+ wsrep_set_data_home_dir,
+ wsrep_thd_is_applier
};
static struct thd_specifics_service_st thd_specifics_handler=
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index d83e88a8d13..63fbc9e29f6 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1901,8 +1901,20 @@ static int mysql_test_show_grants(Prepared_statement *stmt)
DBUG_ENTER("mysql_test_show_grants");
THD *thd= stmt->thd;
List<Item> fields;
+ char buff[1024];
+ const char *username= NULL, *hostname= NULL, *rolename= NULL, *end;
- mysql_show_grants_get_fields(thd, &fields, STRING_WITH_LEN("Grants for"));
+ if (get_show_user(thd, thd->lex->grant_user, &username, &hostname, &rolename))
+ DBUG_RETURN(1);
+
+ if (username)
+ end= strxmov(buff,"Grants for ",username,"@",hostname, NullS);
+ else if (rolename)
+ end= strxmov(buff,"Grants for ",rolename, NullS);
+ else
+ DBUG_RETURN(1);
+
+ mysql_show_grants_get_fields(thd, &fields, buff, (uint)(end - buff));
DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
}
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
@@ -1926,7 +1938,7 @@ static int mysql_test_show_slave_status(Prepared_statement *stmt)
THD *thd= stmt->thd;
List<Item> fields;
- show_master_info_get_fields(thd, &fields, 0, 0);
+ show_master_info_get_fields(thd, &fields, thd->lex->verbose, 0);
DBUG_RETURN(send_stmt_metadata(thd, stmt, &fields));
}
@@ -2464,6 +2476,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
case SQLCOM_CREATE_INDEX:
case SQLCOM_DROP_INDEX:
case SQLCOM_ROLLBACK:
+ case SQLCOM_ROLLBACK_TO_SAVEPOINT:
case SQLCOM_TRUNCATE:
case SQLCOM_DROP_VIEW:
case SQLCOM_REPAIR:
@@ -2483,6 +2496,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
case SQLCOM_ALTER_DB_UPGRADE:
case SQLCOM_CHECKSUM:
case SQLCOM_CREATE_USER:
+ case SQLCOM_ALTER_USER:
case SQLCOM_RENAME_USER:
case SQLCOM_DROP_USER:
case SQLCOM_CREATE_ROLE:
@@ -2492,6 +2506,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
case SQLCOM_GRANT:
case SQLCOM_GRANT_ROLE:
case SQLCOM_REVOKE:
+ case SQLCOM_REVOKE_ALL:
case SQLCOM_REVOKE_ROLE:
case SQLCOM_KILL:
case SQLCOM_COMPOUND:
@@ -2520,14 +2535,12 @@ static bool check_prepared_statement(Prepared_statement *stmt)
{
if (lex->describe || lex->analyze_stmt)
{
- if (!lex->result &&
- !(lex->result= new (stmt->mem_root) select_send(thd)))
- DBUG_RETURN(TRUE);
+ select_send result(thd);
List<Item> field_list;
- thd->prepare_explain_fields(lex->result, &field_list,
- lex->describe, lex->analyze_stmt);
- res= send_prep_stmt(stmt, lex->result->field_count(field_list)) ||
- lex->result->send_result_set_metadata(field_list,
+ res= thd->prepare_explain_fields(&result, &field_list,
+ lex->describe, lex->analyze_stmt) ||
+ send_prep_stmt(stmt, result.field_count(field_list)) ||
+ result.send_result_set_metadata(field_list,
Protocol::SEND_EOF);
}
else
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index b179ae6ae40..ae6c691ae56 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -175,12 +175,6 @@
*/
#define OPTION_MASTER_SQL_ERROR (1ULL << 35)
-/*
- Dont report errors for individual rows,
- But just report error on commit (or read ofcourse)
- Note! Reserved for use in MySQL Cluster
-*/
-#define OPTION_ALLOW_BATCH (1ULL << 36) // THD, intern (slave)
#define OPTION_SKIP_REPLICATION (1ULL << 37) // THD, user
#define OPTION_RPL_SKIP_PARALLEL (1ULL << 38)
#define OPTION_FOUND_COMMENT (1ULL << 39) // SELECT, intern, parser
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 831bd66166c..7ce4ea49c73 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2833,7 +2833,7 @@ bool JOIN::make_aggr_tables_info()
aggr_tables++;
curr_tab= join_tab + exec_join_tab_cnt();
- bzero(curr_tab, sizeof(JOIN_TAB));
+ bzero((void*)curr_tab, sizeof(JOIN_TAB));
curr_tab->ref.key= -1;
curr_tab->join= this;
@@ -2923,7 +2923,7 @@ bool JOIN::make_aggr_tables_info()
{
aggr_tables++;
curr_tab= join_tab + exec_join_tab_cnt();
- bzero(curr_tab, sizeof(JOIN_TAB));
+ bzero((void*)curr_tab, sizeof(JOIN_TAB));
curr_tab->ref.key= -1;
if (only_const_tables())
first_select= sub_select_postjoin_aggr;
@@ -3051,7 +3051,7 @@ bool JOIN::make_aggr_tables_info()
curr_tab++;
aggr_tables++;
- bzero(curr_tab, sizeof(JOIN_TAB));
+ bzero((void*)curr_tab, sizeof(JOIN_TAB));
curr_tab->ref.key= -1;
/* group data to new table */
@@ -4431,7 +4431,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
DBUG_RETURN(1);
/* The following should be optimized to only clear critical things */
- bzero(stat, sizeof(JOIN_TAB)* table_count);
+ bzero((void*)stat, sizeof(JOIN_TAB)* table_count);
/* Initialize POSITION objects */
for (i=0 ; i <= table_count ; i++)
(void) new ((char*) (join->positions + i)) POSITION;
@@ -9585,7 +9585,7 @@ bool JOIN::get_best_combination()
1. Put into main join order a JOIN_TAB that represents a lookup or scan
in the temptable.
*/
- bzero(j, sizeof(JOIN_TAB));
+ bzero((void*)j, sizeof(JOIN_TAB));
j->join= this;
j->table= NULL; //temporary way to tell SJM tables from others.
j->ref.key = -1;
@@ -18003,7 +18003,7 @@ bool Virtual_tmp_table::init(uint field_count)
&bitmaps, bitmap_buffer_size(field_count) * 6,
NullS))
DBUG_RETURN(true);
- bzero(s, sizeof(*s));
+ s->reset();
s->blob_field= blob_field;
setup_tmp_table_column_bitmaps(this, bitmaps, field_count);
m_alloced_field_count= field_count;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 57d8dab8258..88959f84fdb 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -241,7 +241,6 @@ struct SplM_plan_info;
class SplM_opt_info;
typedef struct st_join_table {
- st_join_table() {}
TABLE *table;
TABLE_LIST *tab_list;
KEYUSE *keyuse; /**< pointer to first used key */
@@ -2134,9 +2133,9 @@ public:
static void operator delete(void *ptr, size_t size) { TRASH_FREE(ptr, size); }
static void operator delete(void *, THD *) throw(){}
- Virtual_tmp_table(THD *thd)
+ Virtual_tmp_table(THD *thd) : m_alloced_field_count(0)
{
- bzero(this, sizeof(*this));
+ reset();
temp_pool_slot= MY_BIT_NONE;
in_use= thd;
copy_blobs= true;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 426f40d1729..0003d546ed3 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1238,13 +1238,56 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
List<Item> *field_list, String *buffer)
{
bool error= TRUE;
+ LEX *lex= thd->lex;
MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_show_create_get_fields");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db.str,
table_list->table_name.str));
+ if (lex->table_type == TABLE_TYPE_VIEW)
+ {
+ if (check_table_access(thd, SELECT_ACL, table_list, FALSE, 1, FALSE))
+ {
+ DBUG_PRINT("debug", ("check_table_access failed"));
+ my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
+ "SHOW", thd->security_ctx->priv_user,
+ thd->security_ctx->host_or_ip, table_list->alias.str);
+ goto exit;
+ }
+ DBUG_PRINT("debug", ("check_table_access succeeded"));
+
+ /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
+ table_list->open_type= OT_BASE_ONLY;
+ }
+ else
+ {
+ /*
+ Temporary tables should be opened for SHOW CREATE TABLE, but not
+ for SHOW CREATE VIEW.
+ */
+ if (thd->open_temporary_tables(table_list))
+ goto exit;
+
+ /*
+ The fact that check_some_access() returned FALSE does not mean that
+ access is granted. We need to check if table_list->grant.privilege
+ contains any table-specific privilege.
+ */
+ DBUG_PRINT("debug", ("table_list->grant.privilege: %lx",
+ table_list->grant.privilege));
+ if (check_some_access(thd, SHOW_CREATE_TABLE_ACLS, table_list) ||
+ (table_list->grant.privilege & SHOW_CREATE_TABLE_ACLS) == 0)
+ {
+ my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0),
+ "SHOW", thd->security_ctx->priv_user,
+ thd->security_ctx->host_or_ip, table_list->alias.str);
+ goto exit;
+ }
+ }
+ /* Access is granted. Execute the command. */
+
/* We want to preserve the tree for views. */
- thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
{
/*
@@ -1259,20 +1302,20 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
bool open_error=
open_tables(thd, &table_list, &counter,
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL) ||
- mysql_handle_derived(thd->lex, DT_INIT | DT_PREPARE);
+ mysql_handle_derived(lex, DT_INIT | DT_PREPARE);
thd->pop_internal_handler();
if (unlikely(open_error && (thd->killed || thd->is_error())))
goto exit;
}
/* TODO: add environment variables show when it become possible */
- if (thd->lex->table_type == TABLE_TYPE_VIEW && !table_list->view)
+ if (lex->table_type == TABLE_TYPE_VIEW && !table_list->view)
{
my_error(ER_WRONG_OBJECT, MYF(0),
table_list->db.str, table_list->table_name.str, "VIEW");
goto exit;
}
- else if (thd->lex->table_type == TABLE_TYPE_SEQUENCE &&
+ else if (lex->table_type == TABLE_TYPE_SEQUENCE &&
table_list->table->s->table_type != TABLE_TYPE_SEQUENCE)
{
my_error(ER_NOT_SEQUENCE, MYF(0),
@@ -1287,7 +1330,7 @@ mysqld_show_create_get_fields(THD *thd, TABLE_LIST *table_list,
if ((table_list->view ?
show_create_view(thd, table_list, buffer) :
- thd->lex->table_type == TABLE_TYPE_SEQUENCE ?
+ lex->table_type == TABLE_TYPE_SEQUENCE ?
show_create_sequence(thd, table_list, buffer) :
show_create_table(thd, table_list, buffer, NULL, WITHOUT_DB_NAME)))
goto exit;
@@ -6655,7 +6698,7 @@ static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
{
TABLE_LIST table_list;
uint view_access;
- memset(&table_list, 0, sizeof(table_list));
+ table_list.reset();
table_list.db= tables->db;
table_list.table_name= tables->table_name;
table_list.grant.privilege= thd->col_access;
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 23783405b19..7c920cafc4f 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -27,6 +27,7 @@
#include "m_ctype.h" /* my_charset_bin */
#include <my_sys.h> /* alloc_root, my_free, my_realloc */
#include "m_string.h" /* TRASH */
+#include "sql_list.h"
class String;
typedef struct st_io_cache IO_CACHE;
@@ -126,7 +127,7 @@ uint convert_to_printable(char *to, size_t to_len,
const char *from, size_t from_len,
CHARSET_INFO *from_cs, size_t nbytes= 0);
-class String
+class String : public Sql_alloc
{
char *Ptr;
uint32 str_length,Alloced_length, extra_alloc;
@@ -176,23 +177,6 @@ public:
alloced= thread_specific= 0;
str_charset=str.str_charset;
}
- static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
- { return (void*) alloc_root(mem_root, size); }
- static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
- { return alloc_root(mem_root, size); }
- static void operator delete(void *ptr_arg, size_t size)
- {
- (void) ptr_arg;
- (void) size;
- TRASH_FREE(ptr_arg, size);
- }
- static void operator delete(void *, MEM_ROOT *)
- { /* never called */ }
- static void operator delete[](void *ptr, size_t size)
- { TRASH_FREE(ptr, size); }
- static void operator delete[](void *, MEM_ROOT *)
- { /* never called */ }
-
~String() { free(); }
/* Mark variable thread specific it it's not allocated already */
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 36357ce765d..b2d9ea3bdaf 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -10627,8 +10627,6 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool table_copy)
if (table_copy)
alter_info.requested_algorithm= Alter_info::ALTER_TABLE_ALGORITHM_COPY;
- thd->prepare_logs_for_admin_command();
-
bool res= mysql_alter_table(thd, &null_clex_str, &null_clex_str, &create_info,
table_list, &alter_info, 0,
(ORDER *) 0, 0);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index d03807c63d5..632822a8e87 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1806,7 +1806,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db,
bool result= 0;
DBUG_ENTER("Triggers::drop_all_triggers");
- bzero(&table, sizeof(table));
+ table.reset();
init_sql_alloc(&table.mem_root, "Triggers::drop_all_triggers", 8192, 0,
MYF(0));
@@ -2058,7 +2058,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const LEX_CSTRING *db,
Trigger *err_trigger;
DBUG_ENTER("Triggers::change_table_name");
- bzero(&table, sizeof(table));
+ table.reset();
init_sql_alloc(&table.mem_root, "Triggers::change_table_name", 8192, 0,
MYF(0));
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 7b0e79620ff..87fbbebe4ba 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1240,15 +1240,6 @@ cont:
allocation in setup_ref_array().
*/
fake_select_lex->n_child_sum_items+= global_parameters()->n_sum_items;
-
- saved_error= fake_select_lex->join->
- prepare(fake_select_lex->table_list.first,
- 0, 0,
- global_parameters()->order_list.elements, // og_num
- global_parameters()->order_list.first, // order
- false, NULL, NULL, NULL,
- fake_select_lex, this);
- fake_select_lex->table_list.empty();
}
}
else
@@ -1259,6 +1250,24 @@ cont:
*/
table->reset_item_list(&item_list, intersect_mark ? 1 : 0);
}
+ if (fake_select_lex != NULL &&
+ (thd->stmt_arena->is_stmt_prepare() ||
+ (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)))
+ {
+ if (!fake_select_lex->join &&
+ !(fake_select_lex->join=
+ new JOIN(thd, item_list, thd->variables.option_bits, result)))
+ {
+ fake_select_lex->table_list.empty();
+ DBUG_RETURN(TRUE);
+ }
+ saved_error= fake_select_lex->join->
+ prepare(fake_select_lex->table_list.first, 0, 0,
+ global_parameters()->order_list.elements, // og_num
+ global_parameters()->order_list.first, // order
+ false, NULL, NULL, NULL, fake_select_lex, this);
+ fake_select_lex->table_list.empty();
+ }
}
thd->lex->current_select= lex_select_save;
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 07230b2205b..c2cb5902371 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -215,7 +215,8 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
LEX *lex= thd->lex;
TABLE_LIST decoy;
- memcpy (&decoy, view, sizeof (TABLE_LIST));
+ decoy= *view;
+ decoy.mdl_request.key.mdl_key_init(&view->mdl_request.key);
if (tdc_open_view(thd, &decoy, OPEN_VIEW_NO_PARSE))
return TRUE;
@@ -330,12 +331,11 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view,
{
if (!tbl->table_in_first_from_clause)
{
- if (check_access(thd, SELECT_ACL, tbl->db.str,
- &tbl->grant.privilege,
- &tbl->grant.m_internal,
- 0, 0) ||
- check_grant(thd, SELECT_ACL, tbl, FALSE, 1, FALSE))
+ if (check_single_table_access(thd, SELECT_ACL, tbl, FALSE))
+ {
+ tbl->hide_view_error(thd);
goto err;
+ }
}
}
}
@@ -911,15 +911,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
View definition query is stored in the client character set.
*/
- char view_query_buff[4096];
- String view_query(view_query_buff,
- sizeof (view_query_buff),
- thd->charset());
-
- char is_query_buff[4096];
- String is_query(is_query_buff,
- sizeof (is_query_buff),
- system_charset_info);
+ StringBuffer<4096> view_query(thd->charset());
+ StringBuffer<4096> is_query(system_charset_info);
char md5[MD5_BUFF_LENGTH];
bool can_be_merged;
@@ -2180,7 +2173,7 @@ mysql_rename_view(THD *thd,
view definition parsing or use temporary 'view_def'
object for it.
*/
- bzero(&view_def, sizeof(view_def));
+ view_def.reset();
view_def.timestamp.str= view_def.timestamp_buffer;
view_def.view_suid= TRUE;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 98ead67011c..b9f6a64b378 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -6383,7 +6383,7 @@ create_table_option:
from the global list.
*/
LEX *lex=Lex;
- lex->create_info.merge_list= lex->select_lex.table_list;
+ lex->create_info.merge_list= lex->select_lex.table_list.first;
lex->select_lex.table_list= lex->save_list;
/*
When excluding union list from the global list we assume that
@@ -6392,7 +6392,7 @@ create_table_option:
*/
TABLE_LIST *last_non_sel_table= lex->create_last_non_select_table;
DBUG_ASSERT(last_non_sel_table->next_global ==
- lex->create_info.merge_list.first);
+ lex->create_info.merge_list);
last_non_sel_table->next_global= 0;
Lex->query_tables_last= &last_non_sel_table->next_global;
@@ -14769,6 +14769,7 @@ load:
LOAD data_or_xml
{
LEX *lex= thd->lex;
+ mysql_init_select(lex);
if (unlikely(lex->sphead))
{
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index f7aa1c937c6..61f2426427e 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -6229,7 +6229,7 @@ create_table_option:
from the global list.
*/
LEX *lex=Lex;
- lex->create_info.merge_list= lex->select_lex.table_list;
+ lex->create_info.merge_list= lex->select_lex.table_list.first;
lex->select_lex.table_list= lex->save_list;
/*
When excluding union list from the global list we assume that
@@ -6238,7 +6238,7 @@ create_table_option:
*/
TABLE_LIST *last_non_sel_table= lex->create_last_non_select_table;
DBUG_ASSERT(last_non_sel_table->next_global ==
- lex->create_info.merge_list.first);
+ lex->create_info.merge_list);
last_non_sel_table->next_global= 0;
Lex->query_tables_last= &last_non_sel_table->next_global;
diff --git a/sql/table.h b/sql/table.h
index 9156390a0eb..72f516aebdb 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -793,6 +793,8 @@ struct TABLE_SHARE
/** Instrumentation for this table share. */
PSI_table_share *m_psi;
+ inline void reset() { bzero((void*)this, sizeof(*this)); }
+
/*
Set share's table cache key and update its db and table name appropriately.
@@ -1351,6 +1353,8 @@ public:
SplM_opt_info *spl_opt_info;
key_map keys_usable_for_splitting;
+
+ inline void reset() { bzero((void*)this, sizeof(*this)); }
void init(THD *thd, TABLE_LIST *tl);
bool fill_item_list(List<Item> *item_list) const;
void reset_item_list(List<Item> *item_list, uint skip) const;
@@ -1932,6 +1936,7 @@ struct TABLE_LIST
Prepare TABLE_LIST that consists of one table instance to use in
open_and_lock_tables
*/
+ inline void reset() { bzero((void*)this, sizeof(*this)); }
inline void init_one_table(const LEX_CSTRING *db_arg,
const LEX_CSTRING *table_name_arg,
const LEX_CSTRING *alias_arg,
@@ -1945,7 +1950,7 @@ struct TABLE_LIST
else
mdl_type= MDL_SHARED_READ;
- bzero((char*) this, sizeof(*this));
+ reset();
DBUG_ASSERT(!db_arg->str || strlen(db_arg->str) == db_arg->length);
DBUG_ASSERT(!table_name_arg->str || strlen(table_name_arg->str) == table_name_arg->length);
DBUG_ASSERT(!alias_arg || strlen(alias_arg->str) == alias_arg->length);
@@ -2461,8 +2466,7 @@ struct TABLE_LIST
@sa check_and_update_table_version()
*/
- inline
- bool is_table_ref_id_equal(TABLE_SHARE *s) const
+ inline bool is_table_ref_id_equal(TABLE_SHARE *s) const
{
return (m_table_ref_type == s->get_table_ref_type() &&
m_table_ref_version == s->get_table_ref_version());
@@ -2474,12 +2478,10 @@ struct TABLE_LIST
@sa check_and_update_table_version()
*/
- inline
- void set_table_ref_id(TABLE_SHARE *s)
+ inline void set_table_ref_id(TABLE_SHARE *s)
{ set_table_ref_id(s->get_table_ref_type(), s->get_table_ref_version()); }
- inline
- void set_table_ref_id(enum_table_ref_type table_ref_type_arg,
+ inline void set_table_ref_id(enum_table_ref_type table_ref_type_arg,
ulong table_ref_version_arg)
{
m_table_ref_type= table_ref_type_arg;
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 177521e5a55..fb158480b21 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1531,14 +1531,10 @@ my_offset_tzs_get_key(Time_zone_offset *entry,
static void
tz_init_table_list(TABLE_LIST *tz_tabs)
{
- bzero(tz_tabs, sizeof(TABLE_LIST) * MY_TZ_TABLES_COUNT);
-
for (int i= 0; i < MY_TZ_TABLES_COUNT; i++)
{
- tz_tabs[i].alias= tz_tabs[i].table_name= tz_tables_names[i];
- tz_tabs[i].db= MYSQL_SCHEMA_NAME;
- tz_tabs[i].lock_type= TL_READ;
-
+ tz_tabs[i].init_one_table(&MYSQL_SCHEMA_NAME, tz_tables_names + i,
+ NULL, TL_READ);
if (i != MY_TZ_TABLES_COUNT - 1)
tz_tabs[i].next_global= tz_tabs[i].next_local= &tz_tabs[i+1];
if (i != 0)
diff --git a/sql/wsrep_dummy.cc b/sql/wsrep_dummy.cc
index 4438ede9c1c..9afdb36a643 100644
--- a/sql/wsrep_dummy.cc
+++ b/sql/wsrep_dummy.cc
@@ -150,3 +150,6 @@ void wsrep_unlock_rollback()
void wsrep_set_data_home_dir(const char *)
{ }
+
+my_bool wsrep_thd_is_applier(MYSQL_THD thd)
+{ return false; }
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index 6d4e4f6bc5f..f28063849ea 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -697,3 +697,13 @@ void wsrep_thd_auto_increment_variables(THD* thd,
*increment= thd->variables.auto_increment_increment;
}
}
+
+my_bool wsrep_thd_is_applier(MYSQL_THD thd)
+{
+ my_bool is_applier= false;
+
+ if (thd && thd->wsrep_applier)
+ is_applier= true;
+
+ return (is_applier);
+}