From d89bb8867459c058997f0e315cef76d95b56fb2b Mon Sep 17 00:00:00 2001 From: Sujatha Date: Thu, 23 Jan 2020 16:17:55 +0530 Subject: =?UTF-8?q?MDEV-20923:UBSAN:=20member=20access=20within=20address?= =?UTF-8?q?=20=E2=80=A6=20which=20does=20not=20point=20to=20an=20object=20?= =?UTF-8?q?of=20type=20'xid=5Fcount=5Fper=5Fbinlog'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: ------- Accessing a member within 'xid_count_per_binlog' structure results in following error when 'UBSAN' is enabled. member access within address 0xXXX which does not point to an object of type 'xid_count_per_binlog' Analysis: --------- The problem appears to be that no constructor for 'xid_count_per_binlog' is being called, and thus the vtable will not be initialized. Fix: --- Defined a parameterized constructor for 'xid_count_per_binlog' class. --- sql/log.cc | 27 +++++++++++---------------- sql/log.h | 13 ++++++++++++- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index acf1f8f8a9c..0efef6d1e29 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3216,7 +3216,7 @@ void MYSQL_BIN_LOG::cleanup() DBUG_ASSERT(!binlog_xid_count_list.head()); WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::cleanup(): Removing xid_list_entry " "for %s (%lu)", b); - my_free(b); + delete b; } mysql_mutex_destroy(&LOCK_log); @@ -3580,17 +3580,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name, */ uint off= dirname_length(log_file_name); uint len= strlen(log_file_name) - off; - char *entry_mem, *name_mem; - if (!(new_xid_list_entry = (xid_count_per_binlog *) - my_multi_malloc(MYF(MY_WME), - &entry_mem, sizeof(xid_count_per_binlog), - &name_mem, len, - NULL))) + new_xid_list_entry= new xid_count_per_binlog(log_file_name+off, (int)len); + if (!new_xid_list_entry) goto err; - memcpy(name_mem, log_file_name+off, len); - new_xid_list_entry->binlog_name= name_mem; - new_xid_list_entry->binlog_name_len= len; - new_xid_list_entry->xid_count= 0; /* Find the name for the Initial binlog checkpoint. @@ -3607,7 +3599,10 @@ bool MYSQL_BIN_LOG::open(const char *log_name, mysql_mutex_unlock(&LOCK_xid_list); if (!b) b= new_xid_list_entry; - strmake(buf, b->binlog_name, b->binlog_name_len); + if (b->binlog_name) + strmake(buf, b->binlog_name, b->binlog_name_len); + else + goto err; Binlog_checkpoint_log_event ev(buf, len); DBUG_EXECUTE_IF("crash_before_write_checkpoint_event", flush_io_cache(&log_file); @@ -3711,7 +3706,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name, { WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::open(): Removing xid_list_entry for " "%s (%lu)", b); - my_free(binlog_xid_count_list.get()); + delete binlog_xid_count_list.get(); } mysql_cond_broadcast(&COND_xid_list); WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::open(): Adding new xid_list_entry for " @@ -3758,7 +3753,7 @@ Turning logging off for the whole duration of the MySQL server process. \ To turn it on again: fix the cause, \ shutdown the MySQL server and restart it.", name, errno); if (new_xid_list_entry) - my_free(new_xid_list_entry); + delete new_xid_list_entry; if (file >= 0) mysql_file_close(file, MYF(0)); close(LOG_CLOSE_INDEX); @@ -4252,7 +4247,7 @@ err: DBUG_ASSERT(b->xid_count == 0); WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::reset_logs(): Removing " "xid_list_entry for %s (%lu)", b); - my_free(binlog_xid_count_list.get()); + delete binlog_xid_count_list.get(); } mysql_cond_broadcast(&COND_xid_list); reset_master_pending--; @@ -9736,7 +9731,7 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint) break; WSREP_XID_LIST_ENTRY("TC_LOG_BINLOG::mark_xid_done(): Removing " "xid_list_entry for %s (%lu)", b); - my_free(binlog_xid_count_list.get()); + delete binlog_xid_count_list.get(); } mysql_mutex_unlock(&LOCK_xid_list); diff --git a/sql/log.h b/sql/log.h index b4c9b24a3a9..277e5c6f69c 100644 --- a/sql/log.h +++ b/sql/log.h @@ -587,7 +587,18 @@ public: long xid_count; /* For linking in requests to the binlog background thread. */ xid_count_per_binlog *next_in_queue; - xid_count_per_binlog(); /* Give link error if constructor used. */ + xid_count_per_binlog(char *log_file_name, uint log_file_name_len) + :binlog_id(0), xid_count(0) + { + binlog_name_len= log_file_name_len; + binlog_name= (char *) my_malloc(binlog_name_len, MYF(MY_ZEROFILL)); + if (binlog_name) + memcpy(binlog_name, log_file_name, binlog_name_len); + } + ~xid_count_per_binlog() + { + my_free(binlog_name); + } }; I_List binlog_xid_count_list; mysql_mutex_t LOCK_binlog_background_thread; -- cgit v1.2.1 From 4932ec871f6e8270fdbe50ef33631a4106edd198 Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Wed, 29 Jan 2020 12:49:06 +0100 Subject: Clean the comment for `table_f_c unt` parameter Deleted with commit: c70a9fa1e3c4 --- sql/table.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql') diff --git a/sql/table.cc b/sql/table.cc index c50476cce84..94b006f1cd6 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3610,7 +3610,6 @@ bool check_column_name(const char *name) been opened. @param[in] table The table to check - @param[in] table_f_count Expected number of columns in the table @param[in] table_def Expected structure of the table (column name and type) -- cgit v1.2.1 From f37a56de3cb795883f5a799f6de9fc475d5feaae Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 30 Jan 2020 18:42:51 +0100 Subject: MDEV-21586 Server does not start if lc_messages setting was not english. Fixed a bug introduced in MDEV-11345, server did not start if non-english error messages were set in startup parameters. Added lc_messages=de_DE option into an existing test case. --- sql/derror.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/derror.cc b/sql/derror.cc index 318800ea262..31634383d1c 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -84,8 +84,9 @@ bool init_errmessage(void) if (!use_english) { /* Read messages from file. */ - use_english= !read_texts(ERRMSG_FILE,lang, &original_error_messages); - error= TRUE; + error= use_english= read_texts(ERRMSG_FILE,lang, &original_error_messages); + if(error) + sql_print_error("Could not load error messages for %s",lang); } if (use_english) -- cgit v1.2.1 From 256994ef7469fc4c62d5b271a6557ad729380f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 31 Jan 2020 11:33:07 +0200 Subject: MDEV-21586: Fix a warning for converting my_bool to bool --- sql/derror.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/derror.cc b/sql/derror.cc index 31634383d1c..d6ca47e9054 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (C) 2011 Monty Program Ab + Copyright (C) 2011, 2020, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -84,8 +84,9 @@ bool init_errmessage(void) if (!use_english) { /* Read messages from file. */ - error= use_english= read_texts(ERRMSG_FILE,lang, &original_error_messages); - if(error) + use_english= read_texts(ERRMSG_FILE,lang, &original_error_messages); + error= use_english != FALSE; + if (error) sql_print_error("Could not load error messages for %s",lang); } -- cgit v1.2.1 From 006f6f97b10703426c497827c370f84db72c31ef Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sun, 2 Feb 2020 15:13:29 +0300 Subject: MDEV-17798 System variable system_versioning_asof accepts wrong values --- sql/sys_vars.ic | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic index c6d7b0593d0..ec8d9ef201a 100644 --- a/sql/sys_vars.ic +++ b/sql/sys_vars.ic @@ -2634,7 +2634,7 @@ public: if (!Sys_var_enum::do_check(thd, var)) return false; MYSQL_TIME ltime; - bool res= var->value->get_date(<ime, 0); + bool res= var->value->get_date(<ime, TIME_NO_ZERO_IN_DATE|TIME_NO_ZERO_DATE); if (!res) { var->save_result.ulonglong_value= SYSTEM_TIME_AS_OF; @@ -2651,7 +2651,7 @@ private: { if (var->value) { - res= var->value->get_date(&out.ltime, 0); + res= var->value->get_date(&out.ltime, TIME_NO_ZERO_IN_DATE|TIME_NO_ZERO_DATE); } else // set DEFAULT from global var { -- cgit v1.2.1 From b0fa30808622fe12d474a70af1838906e60b9897 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sun, 2 Feb 2020 15:13:29 +0300 Subject: MDEV-21195 INSERT chooses wrong partition for RANGE partitioning by DECIMAL column Use FLOOR rounding for DECIMAL_RESULT item_expr in partition function. --- sql/my_decimal.cc | 4 ++-- sql/my_decimal.h | 2 +- sql/sql_partition.cc | 26 +++++++++++++++++++++++--- 3 files changed, 26 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 01fad3dde37..8acb46b9ef2 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -345,12 +345,12 @@ void my_decimal_trim(ulonglong *precision, uint *scale) */ int my_decimal2int(uint mask, const decimal_t *d, bool unsigned_flag, - longlong *l) + longlong *l, decimal_round_mode round_type) { int res; my_decimal rounded; /* decimal_round can return only E_DEC_TRUNCATED */ - decimal_round(d, &rounded, 0, HALF_UP); + decimal_round(d, &rounded, 0, round_type); res= (unsigned_flag ? decimal2ulonglong(&rounded, (ulonglong *) l) : decimal2longlong(&rounded, l)); diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 6d6bb258293..b409a87bdd4 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -348,7 +348,7 @@ my_decimal *seconds2my_decimal(bool sign, ulonglong sec, ulong microsec, (TIME)->second_part, (DECIMAL)) int my_decimal2int(uint mask, const decimal_t *d, bool unsigned_flag, - longlong *l); + longlong *l, decimal_round_mode round_type= HALF_UP); inline int my_decimal2double(uint, const decimal_t *d, double *result) diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 00a78ce3199..febd88c4b9b 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2840,14 +2840,34 @@ bool partition_key_modified(TABLE *table, const MY_BITMAP *fields) static inline int part_val_int(Item *item_expr, longlong *result) { - *result= item_expr->val_int(); + switch (item_expr->cmp_type()) + { + case DECIMAL_RESULT: + { + my_decimal buf; + my_decimal *val= item_expr->val_decimal(&buf); + if (val && my_decimal2int(E_DEC_FATAL_ERROR, val, item_expr->unsigned_flag, + result, FLOOR) != E_DEC_OK) + return true; + break; + } + case INT_RESULT: + *result= item_expr->val_int(); + break; + case STRING_RESULT: + case REAL_RESULT: + case ROW_RESULT: + case TIME_RESULT: + DBUG_ASSERT(0); + break; + } if (item_expr->null_value) { if (unlikely(current_thd->is_error())) - return TRUE; + return true; *result= LONGLONG_MIN; } - return FALSE; + return false; } -- cgit v1.2.1 From b3ded21922fc684c3c1aeb4ad57161bc2fec5859 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Wed, 5 Feb 2020 00:54:16 +0300 Subject: ha_partition: add comments, comment out unused member variables --- sql/ha_partition.cc | 2 +- sql/ha_partition.h | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index a7942f493d7..130c7f7e4d5 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -6235,7 +6235,7 @@ static range_seq_t partition_multi_range_key_init(void *init_params, ha_partition *partition= hld->partition; uint i= hld->part_id; DBUG_ENTER("partition_multi_range_key_init"); - partition->m_mrr_range_init_flags= flags; + // not used: partition->m_mrr_range_init_flags= flags; hld->partition_part_key_multi_range= partition->m_part_mrr_range_first[i]; DBUG_RETURN(init_params); } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 1085eca72cc..fc6c8c4d570 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -184,17 +184,61 @@ private: bool is_subpart); }; + +/* + List of ranges to be scanned by ha_partition's MRR implementation + + This object is + - A KEY_MULTI_RANGE structure (the MRR range) + - Storage for the range endpoints that the KEY_MULTI_RANGE has pointers to + - list of such ranges (connected through the "next" pointer). +*/ + typedef struct st_partition_key_multi_range { + /* + Number of the range. The ranges are numbered in the order RANGE_SEQ_IF has + emitted them, starting from 1. The numbering in used by ordered MRR scans. + */ uint id; uchar *key[2]; + /* + Sizes of allocated memory in key[]. These may be larger then the actual + values as this structure is reused across MRR scans + */ uint length[2]; + + /* + The range. + key_multi_range.ptr is a pointer to the this PARTITION_KEY_MULTI_RANGE + object + */ KEY_MULTI_RANGE key_multi_range; + + // Range id from the SQL layer range_id_t ptr; + + // The next element in the list of MRR ranges. st_partition_key_multi_range *next; } PARTITION_KEY_MULTI_RANGE; +/* + List of ranges to be scanned in a certain [sub]partition. + + The idea is that there's a list of ranges to be scanned in the table + (formed by PARTITION_KEY_MULTI_RANGE structures), + and for each [sub]partition, we only need to scan a subset of that list. + + PKMR1 --> PKMR2 --> PKMR3 -->... // list of PARTITION_KEY_MULTI_RANGE + ^ ^ + | | + PPKMR1 ----------> PPKMR2 -->... // list of PARTITION_PART_KEY_MULTI_RANGE + + This way, per-partition lists of PARTITION_PART_KEY_MULTI_RANGE have pointers + to the elements of the global list of PARTITION_KEY_MULTI_RANGE. +*/ + typedef struct st_partition_part_key_multi_range { PARTITION_KEY_MULTI_RANGE *partition_key_multi_range; @@ -203,10 +247,23 @@ typedef struct st_partition_part_key_multi_range class ha_partition; + +/* + The structure holding information about range sequence to be used with one + partition. + (pointer to this is used as seq_init_param for RANGE_SEQ_IF structure when + invoking MRR for an individual partition) +*/ + typedef struct st_partition_part_key_multi_range_hld { + /* Owner object */ ha_partition *partition; + + // id of the the partition this structure is for uint32 part_id; + + // Current range we're iterating through. PARTITION_PART_KEY_MULTI_RANGE *partition_part_key_multi_range; } PARTITION_PART_KEY_MULTI_RANGE_HLD; @@ -810,21 +867,51 @@ public: uint m_mrr_new_full_buffer_size; MY_BITMAP m_mrr_used_partitions; uint *m_stock_range_seq; - uint m_current_range_seq; + // not used: uint m_current_range_seq; + + // Value of mrr_mode passed to ha_partition::multi_range_read_init uint m_mrr_mode; + + // Value of n_ranges passed to ha_partition::multi_range_read_init uint m_mrr_n_ranges; + + /* + Ordered MRR mode: m_range_info[N] has the range_id of the last record that + we've got from partition N. + */ range_id_t *m_range_info; + + // TRUE <=> This ha_partition::multi_range_read_next() call is the first one bool m_multi_range_read_first; - uint m_mrr_range_init_flags; + // not used: uint m_mrr_range_init_flags; + + /* Number of elements in the list pointed by m_mrr_range_first. Not used */ uint m_mrr_range_length; + + // Linked list of ranges to scan PARTITION_KEY_MULTI_RANGE *m_mrr_range_first; PARTITION_KEY_MULTI_RANGE *m_mrr_range_current; + + /* + For each partition: number of ranges MRR scan will scan in the partition + */ uint *m_part_mrr_range_length; + + /* + For each partition: List of ranges to scan in this partition. + */ PARTITION_PART_KEY_MULTI_RANGE **m_part_mrr_range_first; PARTITION_PART_KEY_MULTI_RANGE **m_part_mrr_range_current; PARTITION_PART_KEY_MULTI_RANGE_HLD *m_partition_part_key_multi_range_hld; + + /* + Sequence of ranges to be scanned (TODO: why not stores this in + handler::mrr_{iter,funcs}?) + */ range_seq_t m_seq; RANGE_SEQ_IF *m_seq_if; + + // Range iterator structure to be supplied to partitions RANGE_SEQ_IF m_part_seq_if; virtual int multi_range_key_create_key( -- cgit v1.2.1 From a241d411951f72d6cdbe8fa15a3f4c4adf7b0261 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 10 Jul 2019 13:40:54 +0200 Subject: MDEV-18027: Running out of file descriptors and eventual crash For automatic number of opened files limit take into account number of table instances for table cache --- sql/mysqld.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 58106add403..128dd19cbfc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4432,7 +4432,7 @@ static int init_common_variables() min_connections= 10; /* MyISAM requires two file handles per table. */ wanted_files= (extra_files + max_connections + extra_max_connections + - tc_size * 2); + tc_size * 2 * tc_instances); #if defined(HAVE_POOL_OF_THREADS) && !defined(__WIN__) // add epoll or kevent fd for each threadpool group, in case pool of threads is used wanted_files+= (thread_handling > SCHEDULER_NO_THREADS) ? 0 : threadpool_size; @@ -4461,6 +4461,14 @@ static int init_common_variables() if (files < wanted_files && global_system_variables.log_warnings) sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); + /* If we required too much tc_instances than we reduce */ + SYSVAR_AUTOSIZE_IF_CHANGED(tc_instances, + (uint32) MY_MIN(MY_MAX((files - extra_files - + max_connections)/ + 2/tc_size, + 1), + tc_instances), + uint32); /* If we have requested too much file handles than we bring max_connections in supported bounds. Still leave at least @@ -4468,7 +4476,7 @@ static int init_common_variables() */ SYSVAR_AUTOSIZE_IF_CHANGED(max_connections, (ulong) MY_MAX(MY_MIN(files- extra_files- - min_tc_size*2, + min_tc_size*2*tc_instances, max_connections), min_connections), ulong); @@ -4481,7 +4489,7 @@ static int init_common_variables() */ SYSVAR_AUTOSIZE_IF_CHANGED(tc_size, (ulong) MY_MIN(MY_MAX((files - extra_files - - max_connections) / 2, + max_connections) / 2 / tc_instances, min_tc_size), tc_size), ulong); DBUG_PRINT("warning", -- cgit v1.2.1 From fafb35ee517f309d9e507f6e3908caca5d8cd257 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 6 Nov 2019 12:35:19 +0100 Subject: MDEV-20076: SHOW GRANTS does not quote role names properly Quotes added to output. --- sql/sql_acl.cc | 88 +++++++++++++++++++++++----------------------------------- 1 file changed, 35 insertions(+), 53 deletions(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f25bd57ecd0..e29fd0345da 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8361,13 +8361,12 @@ static void add_user_option(String *grant, double value, const char *name) } } -static void add_user_parameters(String *result, ACL_USER* acl_user, +static void add_user_parameters(THD *thd, String *result, ACL_USER* acl_user, bool with_grant) { - result->append(STRING_WITH_LEN("@'")); - result->append(acl_user->host.hostname, acl_user->hostname_length, - system_charset_info); - result->append('\''); + result->append('@'); + append_identifier(thd, result, acl_user->host.hostname, + acl_user->hostname_length); if (acl_user->plugin.str == native_password_plugin_name.str || acl_user->plugin.str == old_password_plugin_name.str) @@ -8548,11 +8547,9 @@ bool mysql_show_create_user(THD *thd, LEX_USER *lex_user) goto end; } - result.append("CREATE USER '"); - result.append(username); - result.append('\''); - - add_user_parameters(&result, acl_user, false); + result.append("CREATE USER "); + append_identifier(thd, &result, username, strlen(username)); + add_user_parameters(thd, &result, acl_user, false); protocol->prepare_for_resend(); protocol->store(result.ptr(), result.length(), result.charset()); @@ -8797,17 +8794,14 @@ static bool show_role_grants(THD *thd, const char *username, grant.append(STRING_WITH_LEN("GRANT ")); ACL_ROLE *acl_role= *(dynamic_element(&acl_entry->role_grants, counter, ACL_ROLE**)); - grant.append(acl_role->user.str, acl_role->user.length, - system_charset_info); - grant.append(STRING_WITH_LEN(" TO '")); - grant.append(acl_entry->user.str, acl_entry->user.length, - system_charset_info); + append_identifier(thd, &grant, acl_role->user.str, acl_role->user.length); + grant.append(STRING_WITH_LEN(" TO ")); + append_identifier(thd, &grant, acl_entry->user.str, acl_entry->user.length); if (!(acl_entry->flags & IS_ROLE)) { - grant.append(STRING_WITH_LEN("'@'")); - grant.append(&host); + grant.append('@'); + append_identifier(thd, &grant, host.str, host.length); } - grant.append('\''); ROLE_GRANT_PAIR *pair= find_role_grant_pair(&acl_entry->user, &host, &acl_role->user); @@ -8861,13 +8855,12 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry, } } } - global.append (STRING_WITH_LEN(" ON *.* TO '")); - global.append(acl_entry->user.str, acl_entry->user.length, - system_charset_info); - global.append('\''); + global.append (STRING_WITH_LEN(" ON *.* TO ")); + append_identifier(thd, &global, acl_entry->user.str, acl_entry->user.length); if (!handle_as_role) - add_user_parameters(&global, (ACL_USER *)acl_entry, (want_access & GRANT_ACL)); + add_user_parameters(thd, &global, (ACL_USER *)acl_entry, + (want_access & GRANT_ACL)); protocol->prepare_for_resend(); protocol->store(global.ptr(),global.length(),global.charset()); @@ -8878,6 +8871,21 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry, } + +static void add_to_user(THD *thd, String *result, const char *user, + bool is_user, const char *host) +{ + result->append(STRING_WITH_LEN(" TO ")); + append_identifier(thd, result, user, strlen(user)); + if (is_user) + { + result->append('@'); + // host and lex_user->host are equal except for case + append_identifier(thd, result, host, strlen(host)); + } +} + + static bool show_database_privileges(THD *thd, const char *username, const char *hostname, char *buff, size_t buffsize) @@ -8938,16 +8946,8 @@ static bool show_database_privileges(THD *thd, const char *username, } db.append (STRING_WITH_LEN(" ON ")); append_identifier(thd, &db, acl_db->db, strlen(acl_db->db)); - db.append (STRING_WITH_LEN(".* TO '")); - db.append(username, strlen(username), - system_charset_info); - if (*hostname) - { - db.append (STRING_WITH_LEN("'@'")); - // host and lex_user->host are equal except for case - db.append(host, strlen(host), system_charset_info); - } - db.append ('\''); + db.append (STRING_WITH_LEN(".*")); + add_to_user(thd, &db, username, (*hostname), host); if (want_access & GRANT_ACL) db.append(STRING_WITH_LEN(" WITH GRANT OPTION")); protocol->prepare_for_resend(); @@ -9078,16 +9078,7 @@ static bool show_table_and_column_privileges(THD *thd, const char *username, global.append('.'); append_identifier(thd, &global, grant_table->tname, strlen(grant_table->tname)); - global.append(STRING_WITH_LEN(" TO '")); - global.append(username, strlen(username), - system_charset_info); - if (*hostname) - { - global.append(STRING_WITH_LEN("'@'")); - // host and lex_user->host are equal except for case - global.append(host, strlen(host), system_charset_info); - } - global.append('\''); + add_to_user(thd, &global, username, (*hostname), host); if (table_access & GRANT_ACL) global.append(STRING_WITH_LEN(" WITH GRANT OPTION")); protocol->prepare_for_resend(); @@ -9173,16 +9164,7 @@ static int show_routine_grants(THD* thd, global.append('.'); append_identifier(thd, &global, grant_proc->tname, strlen(grant_proc->tname)); - global.append(STRING_WITH_LEN(" TO '")); - global.append(username, strlen(username), - system_charset_info); - if (*hostname) - { - global.append(STRING_WITH_LEN("'@'")); - // host and lex_user->host are equal except for case - global.append(host, strlen(host), system_charset_info); - } - global.append('\''); + add_to_user(thd, &global, username, (*hostname), host); if (proc_access & GRANT_ACL) global.append(STRING_WITH_LEN(" WITH GRANT OPTION")); protocol->prepare_for_resend(); -- cgit v1.2.1 From 8d7462ec499812557d0a0eff2ad1792927cb80ab Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 7 Feb 2020 19:42:11 -0800 Subject: MDEV-21614 Wrong query results with optimizer_switch="split_materialized=on" Do not materialize a semi-join nest if it contains a materialized derived table /view that potentially can be subject to the split optimization. Splitting of materialization of such nest would help, but currently there is no code to support this technique. --- sql/opt_split.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/opt_split.cc b/sql/opt_split.cc index cfac0c93544..6f8248c315c 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -307,7 +307,7 @@ struct SplM_field_ext_info: public SplM_field_info 8. P contains some references on the columns of the joined tables C occurred also in the select list of this join 9. There are defined some keys usable for ref access of fields from C - with available statistics. + with available statistics. @retval true if the answer is positive @@ -477,6 +477,15 @@ bool JOIN::check_for_splittable_materialized() /* Attach this info to the table T */ derived->table->set_spl_opt_info(spl_opt_info); + /* + If this is specification of a materialized derived table T that is + potentially splittable and is used in the from list of the right operand + of an IN predicand transformed to a semi-join then the embedding semi-join + nest is not allowed to be materialized. + */ + if (derived && derived->is_materialized_derived() && + derived->embedding && derived->embedding->sj_subq_pred) + derived->embedding->sj_subq_pred->types_allow_materialization= FALSE; return true; } -- cgit v1.2.1 From b08579aa28d979e9e45239ff507c22a3399c92a7 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 30 Jan 2020 21:11:24 +0100 Subject: MDEV-16308 : protocol messed up sporadically Context involves semicolon batching, and the error starts 10.2 No reproducible examples were made yet, but TCP trace suggests multiple packets that are "squeezed" together (e.g overlong OK packet that has a trailer which is belongs to another packet) Remove thd->get_stmt_da()->set_skip_flush() when processing a batch. skip_flush stems from the COM_MULTI code, which was checked in during 10.2 (and is never used) The fix is confirmed to work, when evaluated by bug reporter (one of them) We never reproduced it locally, with multiple tries thus the root cause analysis is still missing. --- sql/sql_parse.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 45ce82d7fd8..35b6667a25c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1833,7 +1833,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) && ! thd->is_error()) { - thd->get_stmt_da()->set_skip_flush(); /* Multiple queries exist, execute them individually */ -- cgit v1.2.1