summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item.h7
-rw-r--r--sql/item_func.h4
-rw-r--r--sql/item_sum.cc40
-rw-r--r--sql/item_sum.h3
-rw-r--r--sql/log.cc4
-rw-r--r--sql/sql_acl.cc48
-rw-r--r--sql/sql_cache.cc16
-rw-r--r--sql/sql_type.cc12
-rw-r--r--sql/uniques.cc10
-rw-r--r--sql/uniques.h3
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));
}