summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/gcalc_slicescan.cc2
-rw-r--r--sql/handler.cc1
-rw-r--r--sql/item.h49
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_func.h11
-rw-r--r--sql/sp_head.cc3
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_parse.cc15
-rw-r--r--sql/sql_show.cc5
-rw-r--r--sql/sql_statistics.cc6
-rw-r--r--sql/sql_string.h5
-rw-r--r--sql/sql_update.cc3
12 files changed, 86 insertions, 19 deletions
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc
index 68764205302..ba75a1ed827 100644
--- a/sql/gcalc_slicescan.cc
+++ b/sql/gcalc_slicescan.cc
@@ -993,6 +993,8 @@ void Gcalc_heap::reset()
{
if (m_n_points)
{
+ if (m_hook)
+ *m_hook= NULL;
free_list(m_first);
m_n_points= 0;
}
diff --git a/sql/handler.cc b/sql/handler.cc
index ae63640ae5c..ad1bad59efa 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1996,6 +1996,7 @@ int ha_recover(HASH *commit_list)
for (info.len= MAX_XID_LIST_SIZE ;
info.list==0 && info.len > MIN_XID_LIST_SIZE; info.len/=2)
{
+ DBUG_EXECUTE_IF("min_xa_len", info.len = 16;);
info.list=(XID *)my_malloc(info.len*sizeof(XID), MYF(0));
}
if (!info.list)
diff --git a/sql/item.h b/sql/item.h
index 466f8d15df8..bd72fed5300 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -707,6 +707,45 @@ protected:
bool fixed_length,
bool set_blob_packlength);
Field *create_tmp_field(bool group, TABLE *table, uint convert_int_length);
+ /* Helper methods, to get an Item value from another Item */
+ double val_real_from_item(Item *item)
+ {
+ DBUG_ASSERT(fixed == 1);
+ double value= item->val_real();
+ null_value= item->null_value;
+ return value;
+ }
+ longlong val_int_from_item(Item *item)
+ {
+ DBUG_ASSERT(fixed == 1);
+ longlong value= item->val_int();
+ null_value= item->null_value;
+ return value;
+ }
+ String *val_str_from_item(Item *item, String *str)
+ {
+ DBUG_ASSERT(fixed == 1);
+ String *res= item->val_str(str);
+ if (res)
+ res->set_charset(collation.collation);
+ if ((null_value= item->null_value))
+ res= NULL;
+ return res;
+ }
+ my_decimal *val_decimal_from_item(Item *item, my_decimal *decimal_value)
+ {
+ DBUG_ASSERT(fixed == 1);
+ my_decimal *value= item->val_decimal(decimal_value);
+ if ((null_value= item->null_value))
+ value= NULL;
+ return value;
+ }
+ bool get_date_from_item(Item *item, MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ bool rc= item->get_date(ltime, fuzzydate);
+ null_value= MY_TEST(rc || item->null_value);
+ return rc;
+ }
/*
This method is used if the item was not null but convertion to
TIME/DATE/DATETIME failed. We return a zero date if allowed,
@@ -2862,6 +2901,10 @@ public:
{
return result_field->type();
}
+ CHARSET_INFO *charset_for_protocol(void) const
+ {
+ return collation.collation;
+ }
#else
const Type_handler *type_handler() const
{
@@ -4361,6 +4404,12 @@ public:
void save_org_in_field(Field *field, fast_field_copier optimizer_data);
fast_field_copier setup_fast_field_copier(Field *field)
{ return (*ref)->setup_fast_field_copier(field); }
+#if MARIADB_VERSION_ID < 100300
+ CHARSET_INFO *charset_for_protocol(void) const
+ {
+ return (*ref)->charset_for_protocol();
+ }
+#endif
enum Item_result result_type () const { return (*ref)->result_type(); }
enum_field_types field_type() const { return (*ref)->field_type(); }
Field *get_tmp_table_field()
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 039b4f42f98..33f0b982445 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2766,6 +2766,8 @@ bool Item_func_min_max::fix_length_and_dec()
switch (tmp_cmp_type) {
case TIME_RESULT:
// At least one temporal argument was found.
+ if (temporal_type_count < arg_count)
+ maybe_null= true; // Non-temporal-to-temporal conversion can return NULL
collation.set_numeric();
set_handler_by_field_type(temporal_field_type);
if (is_temporal_type_with_time(temporal_field_type))
diff --git a/sql/item_func.h b/sql/item_func.h
index 41eb019bd6b..cd8e4c08168 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1234,10 +1234,13 @@ public:
name= a->name;
name_length= a->name_length;
}
- double val_real() { return args[0]->val_real(); }
- longlong val_int() { return args[0]->val_int(); }
- String *val_str(String *str) { return args[0]->val_str(str); }
- my_decimal *val_decimal(my_decimal *dec) { return args[0]->val_decimal(dec); }
+ double val_real() { return val_real_from_item(args[0]); }
+ longlong val_int() { return val_int_from_item(args[0]); }
+ String *val_str(String *str) { return val_str_from_item(args[0], str); }
+ my_decimal *val_decimal(my_decimal *dec)
+ { return val_decimal_from_item(args[0], dec); }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ { return get_date_from_item(args[0], ltime, fuzzydate); }
const char *func_name() const { return "rollup_const"; }
bool const_item() const { return 0; }
Item_result result_type() const { return args[0]->result_type(); }
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index bb24c3b91bb..c473aec51a1 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -223,6 +223,7 @@ sp_get_flags_for_command(LEX *lex)
case SQLCOM_SHOW_EXPLAIN:
case SQLCOM_SHOW_FIELDS:
case SQLCOM_SHOW_FUNC_CODE:
+ case SQLCOM_SHOW_GENERIC:
case SQLCOM_SHOW_GRANTS:
case SQLCOM_SHOW_ENGINE_STATUS:
case SQLCOM_SHOW_ENGINE_LOGS:
@@ -2896,7 +2897,7 @@ sp_head::show_routine_code(THD *thd)
const char *format= "Instruction at position %u has m_ip=%u";
char tmp[sizeof(format) + 2*SP_INSTR_UINT_MAXLEN + 1];
- sprintf(tmp, format, ip, i->m_ip);
+ my_snprintf(tmp, sizeof(tmp), format, ip, i->m_ip);
/*
Since this is for debugging purposes only, we don't bother to
introduce a special error code for it.
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 2c5c01161b6..38e55f9c4a9 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2390,6 +2390,9 @@ public:
*/
bool create_tmp_table_for_derived;
+ /* The flag to force reading statistics from EITS tables */
+ bool force_read_stats;
+
bool save_prep_leaf_list;
/* container for handler's private per-connection data */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 28cf549bfa1..146c4d2d02e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2926,15 +2926,14 @@ static bool do_execute_sp(THD *thd, sp_head *sp)
my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
return 1;
}
- /*
- If SERVER_MORE_RESULTS_EXISTS is not set,
- then remember that it should be cleared
- */
- bits_to_be_cleared= (~thd->server_status &
- SERVER_MORE_RESULTS_EXISTS);
- thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
}
-
+ /*
+ If SERVER_MORE_RESULTS_EXISTS is not set,
+ then remember that it should be cleared
+ */
+ bits_to_be_cleared= (~thd->server_status &
+ SERVER_MORE_RESULTS_EXISTS);
+ thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
ha_rows select_limit= thd->variables.select_limit;
thd->variables.select_limit= HA_POS_ERROR;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index ce0e3bc6265..a29a6871b78 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -4396,6 +4396,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
'only_view_structure()'.
*/
lex->sql_command= SQLCOM_SHOW_FIELDS;
+ thd->force_read_stats= get_schema_table_idx(schema_table) == SCH_STATISTICS;
result= (thd->open_temporary_tables(table_list) ||
open_normal_and_derived_tables(thd, table_list,
(MYSQL_OPEN_IGNORE_FLUSH |
@@ -4403,6 +4404,10 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
(can_deadlock ?
MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)),
DT_INIT | DT_PREPARE | DT_CREATE));
+
+ (void) read_statistics_for_tables_if_needed(thd, table_list);
+ thd->force_read_stats= false;
+
/*
Restore old value of sql_command back as it is being looked at in
process_table() function.
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 0a51346adb2..3c26f58073d 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -2187,7 +2187,10 @@ inline bool statistics_for_command_is_needed(THD *thd)
{
if (thd->bootstrap || thd->variables.use_stat_tables == NEVER)
return FALSE;
-
+
+ if (thd->force_read_stats)
+ return TRUE;
+
switch(thd->lex->sql_command) {
case SQLCOM_SELECT:
case SQLCOM_INSERT:
@@ -4088,6 +4091,7 @@ bool is_eits_usable(Field *field)
partition list of a table. We assume the selecticivity for
such columns would be handled during partition pruning.
*/
+ DBUG_ASSERT(field->table->stats_is_read);
Column_statistics* col_stats= field->read_stats;
return col_stats && !col_stats->no_stat_values_provided() && //(1)
field->type() != MYSQL_TYPE_GEOMETRY && //(2)
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 0065b1424ce..7a1701f6ef3 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -705,11 +705,6 @@ public:
{
length(0);
}
- StringBuffer(const char *str, size_t length_arg, CHARSET_INFO *cs)
- : String(buff, buff_sz, cs)
- {
- set(str, length_arg, cs);
- }
};
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 11ffa684216..80ecd820046 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -302,6 +302,8 @@ int mysql_update(THD *thd,
if (lock_tables(thd, table_list, table_count, 0))
DBUG_RETURN(1);
+ (void) read_statistics_for_tables_if_needed(thd, table_list);
+
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
DBUG_RETURN(1);
if (table_list->handle_derived(thd->lex, DT_PREPARE))
@@ -1517,6 +1519,7 @@ int mysql_multi_update_prepare(THD *thd)
{
DBUG_RETURN(TRUE);
}
+ (void) read_statistics_for_tables_if_needed(thd, table_list);
/* @todo: downgrade the metadata locks here. */
/*