diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-13 19:01:28 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-06-13 19:01:28 +0300 |
commit | 805340936aa47493886bafd119863d83c475f45c (patch) | |
tree | 46e5a4bd2e8311ef2880caa0526ce705a40c925e /sql | |
parent | f9e53a659c87f1147d4f6d004702077d4d0ce5d7 (diff) | |
parent | d83a4432503d199f6aed8e378563b08471d090dc (diff) | |
download | mariadb-git-805340936aa47493886bafd119863d83c475f45c.tar.gz |
Merge 10.3 into 10.4
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 7 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/item_sum.cc | 40 | ||||
-rw-r--r-- | sql/item_sum.h | 3 | ||||
-rw-r--r-- | sql/log.cc | 4 | ||||
-rw-r--r-- | sql/sql_acl.cc | 48 | ||||
-rw-r--r-- | sql/sql_cache.cc | 16 | ||||
-rw-r--r-- | sql/sql_type.cc | 12 | ||||
-rw-r--r-- | sql/uniques.cc | 10 | ||||
-rw-r--r-- | sql/uniques.h | 3 |
10 files changed, 101 insertions, 46 deletions
diff --git a/sql/item.h b/sql/item.h index 1fa80066f9d..d779e2d6f16 100644 --- a/sql/item.h +++ b/sql/item.h @@ -6818,6 +6818,13 @@ public: bool cache_value(); bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate); int save_in_field(Field *field, bool no_conversions); + bool setup(THD *thd, Item *item) + { + if (Item_cache_int::setup(thd, item)) + return true; + set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); + return false; + } void store_packed(longlong val_arg, Item *example); /* Having a clone_item method tells optimizer that this object diff --git a/sql/item_func.h b/sql/item_func.h index 996a445617b..a8727272adc 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -970,11 +970,11 @@ class Item_num_op :public Item_func_numhybrid decimals= 0; set_handler(type_handler_long_or_longlong()); } - void fix_length_and_dec_temporal() + void fix_length_and_dec_temporal(bool downcast_decimal_to_int) { set_handler(&type_handler_newdecimal); fix_length_and_dec_decimal(); - if (decimals == 0) + if (decimals == 0 && downcast_decimal_to_int) set_handler(type_handler_long_or_longlong()); } bool need_parentheses_in_default() { return true; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 3c468c72fa9..88110367b38 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3628,23 +3628,25 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), ulonglong *offset_limit= &item->copy_offset_limit; ulonglong *row_limit = &item->copy_row_limit; if (item->limit_clause && !(*row_limit)) + { + item->result_finalized= true; return 1; - - if (item->no_appended) - item->no_appended= FALSE; - else - result->append(*item->separator); + } tmp.length(0); if (item->limit_clause && (*offset_limit)) { item->row_count++; - item->no_appended= TRUE; (*offset_limit)--; return 0; } + if (!item->result_finalized) + item->result_finalized= true; + else + result->append(*item->separator); + for (; arg < arg_end; arg++) { String *res; @@ -3899,7 +3901,7 @@ void Item_func_group_concat::clear() result.copy(); null_value= TRUE; warning_for_row= FALSE; - no_appended= TRUE; + result_finalized= FALSE; if (offset_limit) copy_offset_limit= offset_limit->val_int(); if (row_limit) @@ -4032,13 +4034,12 @@ bool Item_func_group_concat::add() return 1; tree_len+= row_str_len; } + /* - If the row is not a duplicate (el->count == 1) - we can dump the row here in case of GROUP_CONCAT(DISTINCT...) - instead of doing tree traverse later. + In case of GROUP_CONCAT with DISTINCT or ORDER BY (or both) don't dump the + row to the output buffer here. That will be done in val_str. */ - if (row_eligible && !warning_for_row && - (!tree || (el->count == 1 && distinct && !arg_count_order))) + if (row_eligible && !warning_for_row && (!tree && !distinct)) dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this); return 0; @@ -4274,9 +4275,18 @@ String* Item_func_group_concat::val_str(String* str) DBUG_ASSERT(fixed == 1); if (null_value) return 0; - if (no_appended && tree) - /* Tree is used for sorting as in ORDER BY */ - tree_walk(tree, &dump_leaf_key, this, left_root_right); + + if (!result_finalized) // Result yet to be written. + { + if (tree != NULL) // order by + tree_walk(tree, &dump_leaf_key, this, left_root_right); + else if (distinct) // distinct (and no order by). + unique_filter->walk(table, &dump_leaf_key, this); + else if (row_limit && copy_row_limit == (ulonglong)row_limit->val_int()) + return &result; + else + DBUG_ASSERT(false); // Can't happen + } if (table && table->blob_storage && table->blob_storage->is_truncated_value()) diff --git a/sql/item_sum.h b/sql/item_sum.h index 7bf8a41f405..7a6fda708a4 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1871,7 +1871,8 @@ class Item_func_group_concat : public Item_sum bool warning_for_row; bool always_null; bool force_copy_fields; - bool no_appended; + /** True if entire result of GROUP_CONCAT has been written to output buffer. */ + bool result_finalized; /** Limits the rows in the result */ Item *row_limit; /** Skips a particular number of rows in from the result*/ diff --git a/sql/log.cc b/sql/log.cc index b5b5abdfc9e..f6dcbea1210 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2494,7 +2494,7 @@ static int find_uniq_filename(char *name, ulong min_log_number_to_use, char buff[FN_REFLEN], ext_buf[FN_REFLEN]; struct st_my_dir *dir_info; struct fileinfo *file_info; - ulong max_found, next, UNINIT_VAR(number); + ulong max_found= 0, next= 0, number= 0; size_t buf_length, length; char *start, *end; int error= 0; @@ -2530,7 +2530,7 @@ static int find_uniq_filename(char *name, ulong min_log_number_to_use, if (strncmp(file_info->name, start, length) == 0 && test_if_number(file_info->name+length, &number,0)) { - set_if_bigger(max_found,(ulong) number); + set_if_bigger(max_found, number); } } my_dirend(dir_info); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 12977248429..9ea69e5628b 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -11852,7 +11852,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) #ifndef NO_EMBEDDED_ACCESS_CHECKS -static bool update_schema_privilege(THD *thd, TABLE *table, char *buff, +static bool update_schema_privilege(THD *thd, TABLE *table, const char *buff, const char* db, const char* t_name, const char* column, uint col_length, const char *priv, uint priv_length, @@ -11876,6 +11876,21 @@ static bool update_schema_privilege(THD *thd, TABLE *table, char *buff, #endif +#ifndef NO_EMBEDDED_ACCESS_CHECKS +class Grantee_str +{ + char m_buff[USER_HOST_BUFF_SIZE + 6 /* 4 quotes, @, '\0' */]; +public: + Grantee_str(const char *user, const char *host) + { + DBUG_ASSERT(strlen(user) + strlen(host) + 6 < sizeof(m_buff)); + strxmov(m_buff, "'", user, "'@'", host, "'", NullS); + } + operator const char *() const { return m_buff; } +}; +#endif + + int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) { #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -11883,7 +11898,6 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) uint counter; ACL_USER *acl_user; ulong want_access; - char buff[100]; TABLE *table= tables->table; bool no_global_access= check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1); @@ -11908,10 +11922,10 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) if (!(want_access & GRANT_ACL)) is_grantable= "NO"; - strxmov(buff,"'",user,"'@'",host,"'",NullS); + Grantee_str grantee(user, host); if (!(want_access & ~GRANT_ACL)) { - if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0, + if (update_schema_privilege(thd, table, grantee, 0, 0, 0, 0, STRING_WITH_LEN("USAGE"), is_grantable)) { error= 1; @@ -11926,7 +11940,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) { if (test_access & j) { - if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0, + if (update_schema_privilege(thd, table, grantee, 0, 0, 0, 0, command_array[priv_id], command_lengths[priv_id], is_grantable)) { @@ -11954,7 +11968,6 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) uint counter; ACL_DB *acl_db; ulong want_access; - char buff[100]; TABLE *table= tables->table; bool no_global_access= check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1); @@ -11983,10 +11996,10 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) { is_grantable= "NO"; } - strxmov(buff,"'",user,"'@'",host,"'",NullS); + Grantee_str grantee(user, host); if (!(want_access & ~GRANT_ACL)) { - if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, + if (update_schema_privilege(thd, table, grantee, acl_db->db, 0, 0, 0, STRING_WITH_LEN("USAGE"), is_grantable)) { error= 1; @@ -12000,7 +12013,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1) if (test_access & j) { - if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, 0, + if (update_schema_privilege(thd, table, + grantee, acl_db->db, 0, 0, 0, command_array[cnt], command_lengths[cnt], is_grantable)) { @@ -12026,7 +12040,6 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) #ifndef NO_EMBEDDED_ACCESS_CHECKS int error= 0; uint index; - char buff[100]; TABLE *table= tables->table; bool no_global_access= check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1); @@ -12059,10 +12072,11 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) if (!(table_access & GRANT_ACL)) is_grantable= "NO"; - strxmov(buff, "'", user, "'@'", host, "'", NullS); + Grantee_str grantee(user, host); if (!test_access) { - if (update_schema_privilege(thd, table, buff, grant_table->db, + if (update_schema_privilege(thd, table, + grantee, grant_table->db, grant_table->tname, 0, 0, STRING_WITH_LEN("USAGE"), is_grantable)) { @@ -12078,7 +12092,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) { if (test_access & j) { - if (update_schema_privilege(thd, table, buff, grant_table->db, + if (update_schema_privilege(thd, table, + grantee, grant_table->db, grant_table->tname, 0, 0, command_array[cnt], command_lengths[cnt], is_grantable)) @@ -12106,7 +12121,6 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) #ifndef NO_EMBEDDED_ACCESS_CHECKS int error= 0; uint index; - char buff[100]; TABLE *table= tables->table; bool no_global_access= check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1); @@ -12133,7 +12147,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) is_grantable= "NO"; ulong test_access= table_access & ~GRANT_ACL; - strxmov(buff, "'", user, "'@'", host, "'", NullS); + Grantee_str grantee(user, host); if (!test_access) continue; else @@ -12152,7 +12166,9 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) my_hash_element(&grant_table->hash_columns,col_index); if ((grant_column->rights & j) && (table_access & j)) { - if (update_schema_privilege(thd, table, buff, grant_table->db, + if (update_schema_privilege(thd, table, + grantee, + grant_table->db, grant_table->tname, grant_column->column, grant_column->key_length, diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 5b649b739c6..0ba4732b6cd 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -3412,7 +3412,7 @@ Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used, if (!insert_table(thd, key_length, key, (*block_table), tables_used->view_db.length, 0, HA_CACHE_TBL_NONTRANSACT, 0, 0, TRUE)) - DBUG_RETURN(0); + goto err_cleanup; /* We do not need to register view tables here because they are already present in the global list. @@ -3436,7 +3436,7 @@ Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used, tables_used->callback_func, tables_used->engine_data, TRUE)) - DBUG_RETURN(0); + goto err_cleanup; if (tables_used->table->file-> register_query_cache_dependant_tables(thd, this, block_table, &n)) @@ -3444,6 +3444,11 @@ Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used, } } DBUG_RETURN(n - counter); +err_cleanup: + // Mark failed + (*block_table)->next= (*block_table)->prev= NULL; + (*block_table)->parent= NULL; + DBUG_RETURN(0); } /* @@ -3477,7 +3482,12 @@ my_bool Query_cache::register_all_tables(THD *thd, for (Query_cache_block_table *tmp = block->table(0) ; tmp != block_table; tmp++) - unlink_table(tmp); + { + if (tmp->prev) // not marked as failed and unuseable + unlink_table(tmp); + else + break; + } if (block_table->parent) unlink_table(block_table); } diff --git a/sql/sql_type.cc b/sql/sql_type.cc index f1f6ecfb046..b5711f6b41c 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2015,2019 MariaDB + Copyright (c) 2015, 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 @@ -6147,7 +6147,7 @@ bool Type_handler_decimal_result:: bool Type_handler_temporal_result:: Item_func_plus_fix_length_and_dec(Item_func_plus *item) const { - item->fix_length_and_dec_temporal(); + item->fix_length_and_dec_temporal(true); return false; } @@ -6196,7 +6196,7 @@ bool Type_handler_decimal_result:: bool Type_handler_temporal_result:: Item_func_minus_fix_length_and_dec(Item_func_minus *item) const { - item->fix_length_and_dec_temporal(); + item->fix_length_and_dec_temporal(true); return false; } @@ -6245,7 +6245,7 @@ bool Type_handler_decimal_result:: bool Type_handler_temporal_result:: Item_func_mul_fix_length_and_dec(Item_func_mul *item) const { - item->fix_length_and_dec_temporal(); + item->fix_length_and_dec_temporal(true); return false; } @@ -6294,7 +6294,7 @@ bool Type_handler_decimal_result:: bool Type_handler_temporal_result:: Item_func_div_fix_length_and_dec(Item_func_div *item) const { - item->fix_length_and_dec_temporal(); + item->fix_length_and_dec_temporal(false); return false; } @@ -6343,7 +6343,7 @@ bool Type_handler_decimal_result:: bool Type_handler_temporal_result:: Item_func_mod_fix_length_and_dec(Item_func_mod *item) const { - item->fix_length_and_dec_temporal(); + item->fix_length_and_dec_temporal(true); return false; } diff --git a/sql/uniques.cc b/sql/uniques.cc index fafb44b56a0..1b8e91f2566 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -318,6 +318,9 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size, max_elements_in_tree= ((size_t) max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size)); + if (max_elements_in_tree == 0) + max_elements_in_tree= 1; + n_full_trees= nkeys / max_elements_in_tree; last_tree_elems= nkeys % max_elements_in_tree; @@ -786,7 +789,12 @@ bool Unique::get(TABLE *table) /* Not enough memory; Save the result to file && free memory used by tree */ if (flush()) DBUG_RETURN(1); - size_t buff_sz= (max_in_memory_size / full_size + 1) * full_size; + /* + merge_buffer must fit at least MERGEBUFF2 + 1 keys, because + merge_index() can merge that many BUFFPEKs at once. The extra space for + one key for Sort_param::unique_buff + */ + size_t buff_sz= MY_MAX(MERGEBUFF2+1, max_in_memory_size/full_size+1) * full_size; if (!(sort_buffer= (uchar*) my_malloc(buff_sz, MYF(MY_THREAD_SPECIFIC|MY_WME)))) DBUG_RETURN(1); diff --git a/sql/uniques.h b/sql/uniques.h index 7cdf6607dd0..a4f5b378fb0 100644 --- a/sql/uniques.h +++ b/sql/uniques.h @@ -85,6 +85,9 @@ public: { size_t max_elems_in_tree= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size); + + if (max_elems_in_tree == 0) + max_elems_in_tree= 1; return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree)); } |