summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc38
-rw-r--r--sql/field.h3
-rw-r--r--sql/gen_lex_token.cc6
-rw-r--r--sql/item.cc40
-rw-r--r--sql/item.h7
-rw-r--r--sql/item_func.cc15
-rw-r--r--sql/item_subselect.cc6
-rw-r--r--sql/item_sum.cc14
-rw-r--r--sql/item_sum.h1
-rw-r--r--sql/log.cc58
-rw-r--r--sql/log_event.cc50
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/opt_subselect.cc91
-rw-r--r--sql/opt_subselect.h13
-rw-r--r--sql/rpl_handler.cc54
-rw-r--r--sql/rpl_utility.cc24
-rw-r--r--sql/share/errmsg-utf8.txt3
-rw-r--r--sql/slave.cc12
-rw-r--r--sql/sp.cc22
-rw-r--r--sql/sp.h2
-rw-r--r--sql/sql_base.cc72
-rw-r--r--sql/sql_class.cc4
-rw-r--r--sql/sql_class.h16
-rw-r--r--sql/sql_cursor.cc37
-rw-r--r--sql/sql_digest.cc17
-rw-r--r--sql/sql_lex.cc2
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_load.cc12
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_plugin.cc14
-rw-r--r--sql/sql_repl.cc7
-rw-r--r--sql/sql_select.cc22
-rw-r--r--sql/sql_select.h7
-rw-r--r--sql/sql_show.cc5
-rw-r--r--sql/sql_table.cc4
-rw-r--r--sql/sql_test.cc7
-rw-r--r--sql/sql_union.cc3
-rw-r--r--sql/sql_update.cc21
-rw-r--r--sql/sys_vars.cc10
-rw-r--r--sql/table.cc9
40 files changed, 497 insertions, 239 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 76b917859d1..b5f4020af71 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6643,25 +6643,33 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)),
}
-my_decimal *Field_string::val_decimal(my_decimal *decimal_value)
+my_decimal *Field_longstr::val_decimal_from_str(const char *str,
+ uint length,
+ CHARSET_INFO *cs,
+ my_decimal *decimal_value)
{
- ASSERT_COLUMN_MARKED_FOR_READ;
THD *thd;
- int err= str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr, field_length,
- charset(), decimal_value);
+ int err= str2my_decimal(E_DEC_FATAL_ERROR, str, length, cs, decimal_value);
if (err && !(thd= get_thd())->no_errors)
{
- ErrConvString errmsg((char*) ptr, field_length, charset());
+ ErrConvString errmsg(str, length, cs);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER_THD(thd, ER_TRUNCATED_WRONG_VALUE),
"DECIMAL", errmsg.ptr());
}
-
return decimal_value;
}
+my_decimal *Field_string::val_decimal(my_decimal *decimal_value)
+{
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ return val_decimal_from_str((const char *) ptr, field_length,
+ Field_string::charset(), decimal_value);
+}
+
+
struct Check_field_param {
Field *field;
};
@@ -7078,18 +7086,9 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
{
ASSERT_COLUMN_MARKED_FOR_READ;
- CHARSET_INFO *cs= charset();
uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
- int error= str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length,
- cs, decimal_value);
-
- if (!get_thd()->no_errors && error)
- {
- push_numerical_conversion_warning(get_thd(), (char*)ptr+length_bytes,
- length, cs, "DECIMAL",
- ER_TRUNCATED_WRONG_VALUE);
- }
- return decimal_value;
+ return val_decimal_from_str((const char *) ptr + length_bytes, length,
+ Field_varstring::charset(), decimal_value);
}
@@ -7597,9 +7596,8 @@ my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
else
length= get_length(ptr);
- str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
- decimal_value);
- return decimal_value;
+ return val_decimal_from_str(blob, length,
+ Field_blob::charset(), decimal_value);
}
diff --git a/sql/field.h b/sql/field.h
index 392041dcf67..ba44ee28cc6 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1227,6 +1227,9 @@ protected:
const Item *item) const;
bool cmp_to_string_with_stricter_collation(const Item_bool_func *cond,
const Item *item) const;
+ my_decimal *val_decimal_from_str(const char *str, uint length,
+ CHARSET_INFO *cs,
+ my_decimal *decimal_value);
public:
Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
diff --git a/sql/gen_lex_token.cc b/sql/gen_lex_token.cc
index 01a54b1b086..eefe9163819 100644
--- a/sql/gen_lex_token.cc
+++ b/sql/gen_lex_token.cc
@@ -56,6 +56,7 @@ int tok_row_single_value= 0;
int tok_row_single_value_list= 0;
int tok_row_multiple_value= 0;
int tok_row_multiple_value_list= 0;
+int tok_ident= 0;
int tok_unused= 0;
void set_token(int tok, const char *str)
@@ -213,6 +214,10 @@ void compute_tokens()
set_token(tok_row_multiple_value_list, "(...) /* , ... */");
max_token_seen++;
+ tok_ident= max_token_seen;
+ set_token(tok_ident, "(tok_id)");
+
+ max_token_seen++;
tok_unused= max_token_seen;
set_token(tok_unused, "UNUSED");
@@ -323,6 +328,7 @@ void print_tokens()
printf("#define TOK_ROW_SINGLE_VALUE_LIST %d\n", tok_row_single_value_list);
printf("#define TOK_ROW_MULTIPLE_VALUE %d\n", tok_row_multiple_value);
printf("#define TOK_ROW_MULTIPLE_VALUE_LIST %d\n", tok_row_multiple_value_list);
+ printf("#define TOK_IDENT %d\n", tok_ident);
printf("#define TOK_UNUSED %d\n", tok_unused);
}
diff --git a/sql/item.cc b/sql/item.cc
index 0ec12678dee..823b8470f4a 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4320,18 +4320,23 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
Item_ident *resolved_item,
Item_ident *mark_item)
{
- const char *db_name= (resolved_item->db_name ?
- resolved_item->db_name : "");
- const char *table_name= (resolved_item->table_name ?
- resolved_item->table_name : "");
+ DBUG_ENTER("mark_as_dependent");
+
/* store pointer on SELECT_LEX from which item is dependent */
if (mark_item && mark_item->can_be_depended)
+ {
+ DBUG_PRINT("info", ("mark_item: %p lex: %p", mark_item, last));
mark_item->depended_from= last;
- if (current->mark_as_dependent(thd, last, /** resolved_item psergey-thu
- **/mark_item))
- return TRUE;
+ }
+ if (current->mark_as_dependent(thd, last,
+ /** resolved_item psergey-thu **/ mark_item))
+ DBUG_RETURN(TRUE);
if (thd->lex->describe & DESCRIBE_EXTENDED)
{
+ const char *db_name= (resolved_item->db_name ?
+ resolved_item->db_name : "");
+ const char *table_name= (resolved_item->table_name ?
+ resolved_item->table_name : "");
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_WARN_FIELD_RESOLVED,
ER_THD(thd,ER_WARN_FIELD_RESOLVED),
@@ -4340,7 +4345,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
resolved_item->field_name,
current->select_number, last->select_number);
}
- return FALSE;
+ DBUG_RETURN(FALSE);
}
@@ -4790,7 +4795,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
non aggregated fields of the outer select.
*/
marker= select->cur_pos_in_select_list;
- select->non_agg_fields.push_back(this, thd->mem_root);
+ select->join->non_agg_fields.push_back(this, thd->mem_root);
}
if (*from_field != view_ref_found)
{
@@ -5209,9 +5214,10 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
fixed= 1;
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
!outer_fixed && !thd->lex->in_sum_func &&
- thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS)
+ thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS &&
+ thd->lex->current_select->join)
{
- thd->lex->current_select->non_agg_fields.push_back(this, thd->mem_root);
+ thd->lex->current_select->join->non_agg_fields.push_back(this, thd->mem_root);
marker= thd->lex->current_select->cur_pos_in_select_list;
}
mark_non_agg_field:
@@ -6787,7 +6793,7 @@ Item_ref::Item_ref(THD *thd, Name_resolution_context *context_arg,
/*
This constructor used to create some internals references over fixed items
*/
- if (ref && *ref && (*ref)->fixed)
+ if ((set_properties_only= (ref && *ref && (*ref)->fixed)))
set_properties();
}
@@ -6831,7 +6837,7 @@ Item_ref::Item_ref(THD *thd, TABLE_LIST *view_arg, Item **item,
/*
This constructor is used to create some internal references over fixed items
*/
- if (ref && *ref && (*ref)->fixed)
+ if ((set_properties_only= (ref && *ref && (*ref)->fixed)))
set_properties();
}
@@ -6906,7 +6912,11 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(fixed == 0);
SELECT_LEX *current_sel= thd->lex->current_select;
- if (!ref || ref == not_found_item)
+ if (set_properties_only)
+ {
+ /* do nothing */
+ }
+ else if (!ref || ref == not_found_item)
{
DBUG_ASSERT(reference_trough_name != 0);
if (!(ref= resolve_ref_in_select_and_group(thd, this,
@@ -7055,7 +7065,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
goto error;
thd->change_item_tree(reference, fld);
mark_as_dependent(thd, last_checked_context->select_lex,
- thd->lex->current_select, fld, fld);
+ current_sel, fld, fld);
/*
A reference is resolved to a nest level that's outer or the same as
the nest level of the enclosing set function : adjust the value of
diff --git a/sql/item.h b/sql/item.h
index 8faba4ddcb5..5b96e93dd1f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -677,7 +677,7 @@ public:
calls.
*/
uint name_length; /* Length of name */
- int8 marker;
+ int marker;
bool maybe_null; /* If item may be null */
bool in_rollup; /* If used in GROUP BY list
of a query with ROLLUP */
@@ -3599,6 +3599,7 @@ class Item_ref :public Item_ident
{
protected:
void set_properties();
+ bool set_properties_only; // the item doesn't need full fix_fields
public:
enum Ref_Type { REF, DIRECT_REF, VIEW_REF, OUTER_REF, AGGREGATE_REF };
Item **ref;
@@ -3607,7 +3608,7 @@ public:
const char *db_arg, const char *table_name_arg,
const char *field_name_arg):
Item_ident(thd, context_arg, db_arg, table_name_arg, field_name_arg),
- ref(0), reference_trough_name(1) {}
+ set_properties_only(0), ref(0), reference_trough_name(1) {}
/*
This constructor is used in two scenarios:
A) *item = NULL
@@ -3630,7 +3631,7 @@ public:
/* Constructor need to process subselect with temporary tables (see Item) */
Item_ref(THD *thd, Item_ref *item)
- :Item_ident(thd, item), ref(item->ref) {}
+ :Item_ident(thd, item), set_properties_only(0), ref(item->ref) {}
enum Type type() const { return REF_ITEM; }
enum Type real_type() const { return ref ? (*ref)->type() :
REF_ITEM; }
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 79fed505d2d..5bb5f541694 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4280,6 +4280,21 @@ longlong Item_func_get_lock::val_int()
DBUG_RETURN(1);
}
+ if (args[1]->null_value ||
+ (!args[1]->unsigned_flag && ((longlong) timeout < 0)))
+ {
+ char buf[22];
+ if (args[1]->null_value)
+ strmov(buf, "NULL");
+ else
+ llstr(((longlong) timeout), buf);
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ "timeout", buf, "get_lock");
+ null_value= 1;
+ DBUG_RETURN(0);
+ }
+
if (!ull_name_ok(res))
DBUG_RETURN(0);
DBUG_PRINT("enter", ("lock: %.*s", res->length(), res->ptr()));
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index a2ae5308e29..7d73393fdb2 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -478,6 +478,7 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
{
List_iterator_fast<Ref_to_outside> it(upper_refs);
Ref_to_outside *upper;
+ DBUG_ENTER("recalc_used_tables");
used_tables_cache= 0;
while ((upper= it++))
@@ -537,6 +538,8 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
he has done const table detection, and that will be our chance to update
const_tables_cache.
*/
+ DBUG_PRINT("exit", ("used_tables_cache: %llx", used_tables_cache));
+ DBUG_VOID_RETURN;
}
@@ -2022,7 +2025,7 @@ bool Item_allany_subselect::is_maxmin_applicable(JOIN *join)
*/
bool
-Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
+Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
Item **where_item,
Item **having_item)
{
@@ -2032,7 +2035,6 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
during JOIN::optimize: this->tmp_having= this->having; this->having= 0;
*/
Item* join_having= join->having ? join->having : join->tmp_having;
-
DBUG_ENTER("Item_in_subselect::create_single_in_to_exists_cond");
*where_item= NULL;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index c56c4c217fb..ae21a94fc83 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3536,9 +3536,17 @@ bool Item_func_group_concat::setup(THD *thd)
"all_fields". The resulting field list is used as input to create
tmp table columns.
*/
- if (arg_count_order &&
- setup_order(thd, args, context->table_list, list, all_fields, *order))
- DBUG_RETURN(TRUE);
+ if (arg_count_order)
+ {
+ uint n_elems= arg_count_order + all_fields.elements;
+ ref_pointer_array= static_cast<Item**>(thd->alloc(sizeof(Item*) * n_elems));
+ if (!ref_pointer_array)
+ DBUG_RETURN(TRUE);
+ memcpy(ref_pointer_array, args, arg_count * sizeof(Item*));
+ if (setup_order(thd, ref_pointer_array, context->table_list, list,
+ all_fields, *order))
+ DBUG_RETURN(TRUE);
+ }
count_field_types(select_lex, tmp_table_param, all_fields, 0);
tmp_table_param->force_copy_fields= force_copy_fields;
diff --git a/sql/item_sum.h b/sql/item_sum.h
index b5613161d7c..01a580d03cb 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1400,6 +1400,7 @@ class Item_func_group_concat : public Item_sum
String *separator;
TREE tree_base;
TREE *tree;
+ Item **ref_pointer_array;
/**
If DISTINCT is used with this GROUP_CONCAT, this member is used to filter
diff --git a/sql/log.cc b/sql/log.cc
index f40ed4bcdc8..e3d9c3e98f8 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -4240,6 +4240,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
int error;
char *to_purge_if_included= NULL;
inuse_relaylog *ir;
+ ulonglong log_space_reclaimed= 0;
DBUG_ENTER("purge_first_log");
DBUG_ASSERT(is_open());
@@ -4311,17 +4312,13 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
- mysql_mutex_lock(&rli->log_space_lock);
rli->relay_log.purge_logs(to_purge_if_included, included,
- 0, 0, &rli->log_space_total);
- mysql_mutex_unlock(&rli->log_space_lock);
+ 0, 0, &log_space_reclaimed);
- /*
- Ok to broadcast after the critical region as there is no risk of
- the mutex being destroyed by this thread later - this helps save
- context switches
- */
+ mysql_mutex_lock(&rli->log_space_lock);
+ rli->log_space_total-= log_space_reclaimed;
mysql_cond_broadcast(&rli->log_space_cond);
+ mysql_mutex_unlock(&rli->log_space_lock);
/*
* Need to update the log pos because purge logs has been called
@@ -4370,8 +4367,8 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
@param need_mutex
@param need_update_threads If we want to update the log coordinates of
all threads. False for relay logs, true otherwise.
- @param freed_log_space If not null, decrement this variable of
- the amount of log space freed
+ @param reclaimeed_log_space If not null, increment this variable to
+ the amount of log space freed
@note
If any of the logs before the deleted one is in use,
@@ -4387,10 +4384,10 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
*/
int MYSQL_BIN_LOG::purge_logs(const char *to_log,
- bool included,
- bool need_mutex,
- bool need_update_threads,
- ulonglong *decrease_log_space)
+ bool included,
+ bool need_mutex,
+ bool need_update_threads,
+ ulonglong *reclaimed_space)
{
int error= 0;
bool exit_loop= 0;
@@ -4454,7 +4451,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
err:
/* Read each entry from purge_index_file and delete the file. */
if (is_inited_purge_index_file() &&
- (error= purge_index_entry(thd, decrease_log_space, FALSE)))
+ (error= purge_index_entry(thd, reclaimed_space, FALSE)))
sql_print_error("MSYQL_BIN_LOG::purge_logs failed to process registered files"
" that would be purged.");
close_purge_index_file();
@@ -4559,7 +4556,7 @@ int MYSQL_BIN_LOG::register_create_index_entry(const char *entry)
DBUG_RETURN(register_purge_index_entry(entry));
}
-int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
+int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *reclaimed_space,
bool need_mutex)
{
DBUG_ENTER("MYSQL_BIN_LOG:purge_index_entry");
@@ -4672,8 +4669,8 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,
DBUG_PRINT("info",("purging %s",log_info.log_file_name));
if (!my_delete(log_info.log_file_name, MYF(0)))
{
- if (decrease_log_space)
- *decrease_log_space-= s.st_size;
+ if (reclaimed_space)
+ *reclaimed_space+= s.st_size;
}
else
{
@@ -6588,9 +6585,10 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
long val;
ulong end_log_pos_inc= 0; // each event processed adds BINLOG_CHECKSUM_LEN 2 t
uchar header[LOG_EVENT_HEADER_LEN];
- ha_checksum crc= 0, crc_0= 0; // assignments to keep compiler happy
+ ha_checksum crc= 0, crc_0= 0;
my_bool do_checksum= (binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF);
uchar buf[BINLOG_CHECKSUM_LEN];
+ DBUG_ENTER("MYSQL_BIN_LOG::write_cache");
// while there is just one alg the following must hold:
DBUG_ASSERT(!do_checksum ||
@@ -6612,9 +6610,7 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
group= (uint)my_b_tell(&log_file);
hdr_offs= carry= 0;
- if (do_checksum)
- crc= crc_0= my_checksum(0L, NULL, 0);
-
+
do
{
/*
@@ -6643,7 +6639,7 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
/* write the first half of the split header */
if (my_b_write(&log_file, header, carry))
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
status_var_add(thd->status_var.binlog_bytes_written, carry);
/*
@@ -6687,12 +6683,12 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
crc= my_checksum(crc, cache->read_pos, length);
remains -= length;
if (my_b_write(&log_file, cache->read_pos, length))
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
if (remains == 0)
{
int4store(buf, crc);
if (my_b_write(&log_file, buf, BINLOG_CHECKSUM_LEN))
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
crc= crc_0;
}
}
@@ -6719,7 +6715,7 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
DBUG_ASSERT(remains == 0);
if (my_b_write(&log_file, cache->read_pos, hdr_offs) ||
my_b_write(&log_file, buf, BINLOG_CHECKSUM_LEN))
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
crc= crc_0;
}
}
@@ -6751,12 +6747,12 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
length, &crc);
if (my_b_write(&log_file, ev,
remains == 0 ? event_len : length - hdr_offs))
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
if (remains == 0)
{
int4store(buf, crc);
if (my_b_write(&log_file, buf, BINLOG_CHECKSUM_LEN))
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
crc= crc_0; // crc is complete
}
}
@@ -6781,10 +6777,10 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
/* Write data to the binary log file */
DBUG_EXECUTE_IF("fail_binlog_write_1",
- errno= 28; return ER_ERROR_ON_WRITE;);
+ errno= 28; DBUG_RETURN(ER_ERROR_ON_WRITE););
if (!do_checksum)
if (my_b_write(&log_file, cache->read_pos, length))
- return ER_ERROR_ON_WRITE;
+ DBUG_RETURN(ER_ERROR_ON_WRITE);
status_var_add(thd->status_var.binlog_bytes_written, length);
} while ((length= my_b_fill(cache)));
@@ -6793,7 +6789,7 @@ int MYSQL_BIN_LOG::write_cache(THD *thd, IO_CACHE *cache)
DBUG_ASSERT(!do_checksum || remains == 0);
DBUG_ASSERT(!do_checksum || crc == crc_0);
- return 0; // All OK
+ DBUG_RETURN(0); // All OK
}
/*
diff --git a/sql/log_event.cc b/sql/log_event.cc
index cb5b2c5cbbd..81c0d0c1304 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1089,12 +1089,22 @@ my_bool Log_event::need_checksum()
and Stop event)
provides their checksum alg preference through Log_event::checksum_alg.
*/
- ret= ((checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) ?
- (checksum_alg != BINLOG_CHECKSUM_ALG_OFF) :
- ((binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF) &&
- (cache_type == Log_event::EVENT_NO_CACHE)) ?
- MY_TEST(binlog_checksum_options) : FALSE);
-
+ if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ ret= (checksum_alg != BINLOG_CHECKSUM_ALG_OFF);
+ else
+ {
+ if (binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF &&
+ cache_type == Log_event::EVENT_NO_CACHE)
+ {
+ checksum_alg= binlog_checksum_options;
+ ret= MY_TEST(binlog_checksum_options);
+ }
+ else
+ {
+ ret= FALSE;
+ checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_OFF;
+ }
+ }
/*
FD calls the methods before data_written has been calculated.
The following invariant claims if the current is not the first
@@ -1105,10 +1115,6 @@ my_bool Log_event::need_checksum()
DBUG_ASSERT(get_type_code() != FORMAT_DESCRIPTION_EVENT || ret ||
data_written == 0);
- if (checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
- checksum_alg= ret ? // calculated value stored
- (uint8) binlog_checksum_options : (uint8) BINLOG_CHECKSUM_ALG_OFF;
-
DBUG_ASSERT(!ret ||
((checksum_alg == binlog_checksum_options ||
/*
@@ -1148,17 +1154,19 @@ bool Log_event::wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong
bool Log_event::write_footer(IO_CACHE* file)
{
+ DBUG_ENTER("write_footer");
/*
footer contains the checksum-algorithm descriptor
followed by the checksum value
*/
if (need_checksum())
{
+ DBUG_PRINT("info", ("Writing checksum"));
uchar buf[BINLOG_CHECKSUM_LEN];
int4store(buf, crc);
- return (my_b_safe_write(file, (uchar*) buf, sizeof(buf)));
+ DBUG_RETURN(my_b_safe_write(file, (uchar*) buf, sizeof(buf)));
}
- return 0;
+ DBUG_RETURN(0);
}
/*
@@ -1180,7 +1188,7 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
if (need_checksum())
{
- crc= my_checksum(0L, NULL, 0);
+ crc= 0;
data_written += BINLOG_CHECKSUM_LEN;
}
@@ -3072,6 +3080,7 @@ Query_log_event::Query_log_event()
query_arg - array of char representing the query
query_length - size of the `query_arg' array
using_trans - there is a modified transactional table
+ direct - Don't cache statement
suppress_use - suppress the generation of 'USE' statements
errcode - the error code of the query
@@ -3199,10 +3208,17 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
break;
case SQLCOM_CREATE_TABLE:
+ /*
+ If we are using CREATE ... SELECT or if we are a slave
+ executing BEGIN...COMMIT (generated by CREATE...SELECT) we
+ have to use the transactional cache to ensure we don't
+ calculate any checksum for the CREATE part.
+ */
trx_cache= (lex->select_lex.item_list.elements &&
- thd->is_current_stmt_binlog_format_row());
+ thd->is_current_stmt_binlog_format_row()) ||
+ (thd->variables.option_bits & OPTION_GTID_BEGIN);
use_cache= (lex->tmp_table() &&
- thd->in_multi_stmt_transaction_mode()) || trx_cache;
+ thd->in_multi_stmt_transaction_mode()) || trx_cache;
break;
case SQLCOM_SET_OPTION:
if (lex->autocommit)
@@ -3233,8 +3249,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
else
cache_type= Log_event::EVENT_STMT_CACHE;
DBUG_ASSERT(cache_type != Log_event::EVENT_INVALID_CACHE);
- DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %llu",
- (ulong) flags2, sql_mode));
+ DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %llu cache_tye: %d",
+ (ulong) flags2, sql_mode, cache_type));
}
#endif /* MYSQL_CLIENT */
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index f36d1cee9bc..76d74952e89 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5561,8 +5561,6 @@ int mysqld_main(int argc, char **argv)
pfs_param.m_hints.m_table_open_cache= tc_size;
pfs_param.m_hints.m_max_connections= max_connections;
pfs_param.m_hints.m_open_files_limit= open_files_limit;
- /* the performance schema digest size is the same as the SQL layer */
- pfs_param.m_max_digest_length= max_digest_length;
PSI_hook= initialize_performance_schema(&pfs_param);
if (PSI_hook == NULL)
{
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index dac607195f0..9c6784437a7 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -4371,6 +4371,74 @@ int init_dups_weedout(JOIN *join, uint first_table, int first_fanout_table, uint
/*
+ @brief
+ Set up semi-join Loose Scan strategy for execution
+
+ @detail
+ Other strategies are done in setup_semijoin_dups_elimination(),
+ however, we need to set up Loose Scan earlier, before make_join_select is
+ called. This is to prevent make_join_select() from switching full index
+ scans into quick selects (which will break Loose Scan access).
+
+ @return
+ 0 OK
+ 1 Error
+*/
+
+int setup_semijoin_loosescan(JOIN *join)
+{
+ uint i;
+ DBUG_ENTER("setup_semijoin_loosescan");
+
+ POSITION *pos= join->best_positions + join->const_tables;
+ for (i= join->const_tables ; i < join->top_join_tab_count; )
+ {
+ JOIN_TAB *tab=join->join_tab + i;
+ switch (pos->sj_strategy) {
+ case SJ_OPT_MATERIALIZE:
+ case SJ_OPT_MATERIALIZE_SCAN:
+ i+= 1; /* join tabs are embedded in the nest */
+ pos += pos->n_sj_tables;
+ break;
+ case SJ_OPT_LOOSE_SCAN:
+ {
+ /* We jump from the last table to the first one */
+ tab->loosescan_match_tab= tab + pos->n_sj_tables - 1;
+
+ /* LooseScan requires records to be produced in order */
+ if (tab->select && tab->select->quick)
+ tab->select->quick->need_sorted_output();
+
+ for (uint j= i; j < i + pos->n_sj_tables; j++)
+ join->join_tab[j].inside_loosescan_range= TRUE;
+
+ /* Calculate key length */
+ uint keylen= 0;
+ uint keyno= pos->loosescan_picker.loosescan_key;
+ for (uint kp=0; kp < pos->loosescan_picker.loosescan_parts; kp++)
+ keylen += tab->table->key_info[keyno].key_part[kp].store_length;
+
+ tab->loosescan_key= keyno;
+ tab->loosescan_key_len= keylen;
+ if (pos->n_sj_tables > 1)
+ tab[pos->n_sj_tables - 1].do_firstmatch= tab;
+ i+= pos->n_sj_tables;
+ pos+= pos->n_sj_tables;
+ break;
+ }
+ default:
+ {
+ i++;
+ pos++;
+ break;
+ }
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
Setup the strategies to eliminate semi-join duplicates.
SYNOPSIS
@@ -4478,8 +4546,6 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
for (i= join->const_tables ; i < join->top_join_tab_count; )
{
JOIN_TAB *tab=join->join_tab + i;
- //POSITION *pos= join->best_positions + i;
- uint keylen, keyno;
switch (pos->sj_strategy) {
case SJ_OPT_MATERIALIZE:
case SJ_OPT_MATERIALIZE_SCAN:
@@ -4489,26 +4555,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
break;
case SJ_OPT_LOOSE_SCAN:
{
- /* We jump from the last table to the first one */
- tab->loosescan_match_tab= tab + pos->n_sj_tables - 1;
-
- /* LooseScan requires records to be produced in order */
- if (tab->select && tab->select->quick)
- tab->select->quick->need_sorted_output();
-
- for (uint j= i; j < i + pos->n_sj_tables; j++)
- join->join_tab[j].inside_loosescan_range= TRUE;
-
- /* Calculate key length */
- keylen= 0;
- keyno= pos->loosescan_picker.loosescan_key;
- for (uint kp=0; kp < pos->loosescan_picker.loosescan_parts; kp++)
- keylen += tab->table->key_info[keyno].key_part[kp].store_length;
-
- tab->loosescan_key= keyno;
- tab->loosescan_key_len= keylen;
- if (pos->n_sj_tables > 1)
- tab[pos->n_sj_tables - 1].do_firstmatch= tab;
+ /* Setup already handled by setup_semijoin_loosescan */
i+= pos->n_sj_tables;
pos+= pos->n_sj_tables;
break;
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
index a2f6b644bf2..8daa973f825 100644
--- a/sql/opt_subselect.h
+++ b/sql/opt_subselect.h
@@ -195,8 +195,6 @@ public:
PREV_BITS(key_part_map, max_loose_keypart+1) && // (3)
!key_uses_partial_cols(s->table->s, key))
{
- /* Ok, can use the strategy */
- part1_conds_met= TRUE;
if (s->quick && s->quick->index == key &&
s->quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE)
{
@@ -205,6 +203,12 @@ public:
}
DBUG_PRINT("info", ("Can use LooseScan scan"));
+ if (found_part & 1)
+ {
+ /* Can use LooseScan on ref access if the first key part is bound */
+ part1_conds_met= TRUE;
+ }
+
/*
Check if this is a special case where there are no usable bound
IN-equalities, i.e. we have
@@ -212,11 +216,13 @@ public:
outer_expr IN (SELECT innertbl.key FROM ...)
and outer_expr cannot be evaluated yet, so it's actually full
- index scan and not a ref access
+ index scan and not a ref access.
+ We can do full index scan if it uses index-only.
*/
if (!(found_part & 1 ) && /* no usable ref access for 1st key part */
s->table->covering_keys.is_set(key))
{
+ part1_conds_met= TRUE;
DBUG_PRINT("info", ("Can use full index scan for LooseScan"));
/* Calculate the cost of complete loose index scan. */
@@ -384,6 +390,7 @@ public:
bool create_sj_weedout_tmp_table(THD *thd);
};
+int setup_semijoin_loosescan(JOIN *join);
int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
uint no_jbuf_after);
void destroy_sj_tmp_tables(JOIN *join);
diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc
index 3962600f600..733af6c61c8 100644
--- a/sql/rpl_handler.cc
+++ b/sql/rpl_handler.cc
@@ -39,8 +39,6 @@ typedef struct Trans_binlog_info {
char log_file[FN_REFLEN];
} Trans_binlog_info;
-static pthread_key(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
-
int get_user_var_int(const char *name,
long long int *value, int *null_value)
{
@@ -144,13 +142,6 @@ int delegates_init()
}
#endif
- if (pthread_key_create(&RPL_TRANS_BINLOG_INFO, NULL))
- {
- sql_print_error("Error while creating pthread specific data key for replication. "
- "Please report a bug.");
- return 1;
- }
-
return 0;
}
@@ -196,27 +187,27 @@ void delegates_destroy()
int Trans_delegate::after_commit(THD *thd, bool all)
{
Trans_param param;
+ Trans_binlog_info *log_info;
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
+ int ret= 0;
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
- Trans_binlog_info *log_info=
- my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
+ log_info= thd->semisync_info;
- param.log_file= log_info ? log_info->log_file : 0;
+ param.log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
param.log_pos= log_info ? log_info->log_pos : 0;
- int ret= 0;
FOREACH_OBSERVER(ret, after_commit, false, (&param));
/*
This is the end of a real transaction or autocommit statement, we
- can free the memory allocated for binlog file and position.
+ can mark the memory unused.
*/
if (is_real_trans && log_info)
{
- my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, NULL);
- my_free(log_info);
+ log_info->log_file[0]= 0;
+ log_info->log_pos= 0;
}
return ret;
}
@@ -224,27 +215,27 @@ int Trans_delegate::after_commit(THD *thd, bool all)
int Trans_delegate::after_rollback(THD *thd, bool all)
{
Trans_param param;
+ Trans_binlog_info *log_info;
bool is_real_trans= (all || thd->transaction.all.ha_list == 0);
+ int ret= 0;
param.flags = is_real_trans ? TRANS_IS_REAL_TRANS : 0;
- Trans_binlog_info *log_info=
- my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
-
- param.log_file= log_info ? log_info->log_file : 0;
+ log_info= thd->semisync_info;
+
+ param.log_file= log_info && log_info->log_file[0] ? log_info->log_file : 0;
param.log_pos= log_info ? log_info->log_pos : 0;
- int ret= 0;
FOREACH_OBSERVER(ret, after_rollback, false, (&param));
/*
This is the end of a real transaction or autocommit statement, we
- can free the memory allocated for binlog file and position.
+ can mark the memory unused.
*/
if (is_real_trans && log_info)
{
- my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, NULL);
- my_free(log_info);
+ log_info->log_file[0]= 0;
+ log_info->log_pos= 0;
}
return ret;
}
@@ -257,7 +248,10 @@ int Binlog_storage_delegate::after_flush(THD *thd,
bool last_in_group)
{
Binlog_storage_param param;
+ Trans_binlog_info *log_info;
uint32 flags=0;
+ int ret= 0;
+
if (synced)
flags |= BINLOG_STORAGE_IS_SYNCED;
if (first_in_group)
@@ -265,21 +259,17 @@ int Binlog_storage_delegate::after_flush(THD *thd,
if (last_in_group)
flags|= BINLOG_GROUP_COMMIT_TRAILER;
- Trans_binlog_info *log_info=
- my_pthread_getspecific_ptr(Trans_binlog_info*, RPL_TRANS_BINLOG_INFO);
-
- if (!log_info)
+ if (!(log_info= thd->semisync_info))
{
if(!(log_info=
- (Trans_binlog_info *)my_malloc(sizeof(Trans_binlog_info), MYF(0))))
+ (Trans_binlog_info*) my_malloc(sizeof(Trans_binlog_info), MYF(0))))
return 1;
- my_pthread_setspecific_ptr(RPL_TRANS_BINLOG_INFO, log_info);
+ thd->semisync_info= log_info;
}
-
+
strcpy(log_info->log_file, log_file+dirname_length(log_file));
log_info->log_pos = log_pos;
- int ret= 0;
FOREACH_OBSERVER(ret, after_flush, false,
(&param, log_info->log_file, log_info->log_pos, flags));
return ret;
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index dadd9de748c..5147dc4f0cb 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -950,6 +950,7 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
{
Create_field *field_def=
(Create_field*) alloc_root(thd->mem_root, sizeof(Create_field));
+ bool unsigned_flag= 0;
if (field_list.push_back(field_def, thd->mem_root))
DBUG_RETURN(NULL);
@@ -959,8 +960,7 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
uint32 max_length=
max_display_length_for_field(type(col), field_metadata(col));
- switch(type(col))
- {
+ switch(type(col)) {
int precision;
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
@@ -999,6 +999,18 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
pack_length= field_metadata(col) & 0x00ff;
break;
+ case MYSQL_TYPE_TINY:
+ case MYSQL_TYPE_SHORT:
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_LONGLONG:
+ /*
+ As we don't know if the integer was signed or not on the master,
+ assume we have same sign on master and slave. This is true when not
+ using conversions so it should be true also when using conversions.
+ */
+ unsigned_flag= ((Field_num*) target_table->field[col])->unsigned_flag;
+ break;
default:
break;
}
@@ -1006,12 +1018,13 @@ TABLE *table_def::create_conversion_table(THD *thd, rpl_group_info *rgi,
DBUG_PRINT("debug", ("sql_type: %d, target_field: '%s', max_length: %d, decimals: %d,"
" maybe_null: %d, unsigned_flag: %d, pack_length: %u",
binlog_type(col), target_table->field[col]->field_name,
- max_length, decimals, TRUE, FALSE, pack_length));
+ max_length, decimals, TRUE, unsigned_flag,
+ pack_length));
field_def->init_for_tmp_table(type(col),
max_length,
decimals,
TRUE, // maybe_null
- FALSE, // unsigned_flag
+ unsigned_flag,
pack_length);
field_def->charset= target_table->field[col]->charset();
field_def->interval= interval;
@@ -1179,7 +1192,7 @@ bool event_checksum_test(uchar *event_buf, ulong event_len, uint8 alg)
compile_time_assert(BINLOG_CHECKSUM_ALG_ENUM_END <= 0x80);
}
incoming= uint4korr(event_buf + event_len - BINLOG_CHECKSUM_LEN);
- computed= my_checksum(0L, NULL, 0);
+ computed= 0;
/* checksum the event content but the checksum part itself */
computed= my_checksum(computed, (const uchar*) event_buf,
event_len - BINLOG_CHECKSUM_LEN);
@@ -1257,4 +1270,3 @@ void Deferred_log_events::rewind()
}
#endif
-
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 0f519fdd33b..59908dc51c0 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -7109,6 +7109,9 @@ ER_SLAVE_SKIP_NOT_IN_GTID
eng "When using GTID, @@sql_slave_skip_counter can not be used. Instead, setting @@gtid_slave_pos explicitly can be used to skip to after a given GTID position."
ER_TABLE_DEFINITION_TOO_BIG
eng "The definition for table %`s is too big"
+ER_PLUGIN_INSTALLED
+ eng "Plugin '%-.192s' already installed"
+ rus "Плагин '%-.192s' уже установлен"
ER_STATEMENT_TIMEOUT 70100
eng "Query execution was interrupted (max_statement_time exceeded)"
ER_SUBQUERIES_NOT_SUPPORTED 42000
diff --git a/sql/slave.cc b/sql/slave.cc
index 3bbc7610649..659f3a90574 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4619,9 +4619,7 @@ pthread_handler_t handle_slave_sql(void *arg)
rli->parallel.reset();
//tell the I/O thread to take relay_log_space_limit into account from now on
- mysql_mutex_lock(&rli->log_space_lock);
rli->ignore_log_space_limit= 0;
- mysql_mutex_unlock(&rli->log_space_lock);
serial_rgi->gtid_sub_id= 0;
serial_rgi->gtid_pending= false;
@@ -5594,7 +5592,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
if (uint4korr(&buf[0]) == 0 && checksum_alg == BINLOG_CHECKSUM_ALG_OFF &&
mi->rli.relay_log.relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
{
- ha_checksum rot_crc= my_checksum(0L, NULL, 0);
+ ha_checksum rot_crc= 0;
event_len += BINLOG_CHECKSUM_LEN;
memcpy(rot_buf, buf, event_len - BINLOG_CHECKSUM_LEN);
int4store(&rot_buf[EVENT_LEN_OFFSET],
@@ -6819,14 +6817,8 @@ static Log_event* next_event(rpl_group_info *rgi, ulonglong *event_size)
rli->ignore_log_space_limit= true;
}
- /*
- If the I/O thread is blocked, unblock it. Ok to broadcast
- after unlock, because the mutex is only destroyed in
- ~Relay_log_info(), i.e. when rli is destroyed, and rli will
- not be destroyed before we exit the present function.
- */
- mysql_mutex_unlock(&rli->log_space_lock);
mysql_cond_broadcast(&rli->log_space_cond);
+ mysql_mutex_unlock(&rli->log_space_lock);
// Note that wait_for_update_relay_log unlocks lock_log !
rli->relay_log.wait_for_update_relay_log(rli->sql_driver_thd);
// re-acquire data lock since we released it earlier
diff --git a/sql/sp.cc b/sql/sp.cc
index 46970bafdfc..6ec59143720 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1797,7 +1797,8 @@ sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
@param thd Thread handler
@param routines List of needles in the hay stack
- @param any Any of the needles are good enough
+ @param is_proc Indicates whether routines in the list are procedures
+ or functions.
@return
@retval FALSE Found.
@@ -1805,7 +1806,7 @@ sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
*/
bool
-sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any)
+sp_exist_routines(THD *thd, TABLE_LIST *routines, bool is_proc)
{
TABLE_LIST *routine;
bool sp_object_found;
@@ -1821,17 +1822,14 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any)
lex_name.str= thd->strmake(routine->table_name, lex_name.length);
name= new sp_name(lex_db, lex_name, true);
name->init_qname(thd);
- sp_object_found= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
- &thd->sp_proc_cache, FALSE) != NULL ||
- sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
- &thd->sp_func_cache, FALSE) != NULL;
+ sp_object_found= is_proc ? sp_find_routine(thd, TYPE_ENUM_PROCEDURE,
+ name, &thd->sp_proc_cache,
+ FALSE) != NULL :
+ sp_find_routine(thd, TYPE_ENUM_FUNCTION,
+ name, &thd->sp_func_cache,
+ FALSE) != NULL;
thd->get_stmt_da()->clear_warning_info(thd->query_id);
- if (sp_object_found)
- {
- if (any)
- break;
- }
- else if (!any)
+ if (! sp_object_found)
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION or PROCEDURE",
routine->table_name);
diff --git a/sql/sp.h b/sql/sp.h
index eb3291fb1a9..4bfb0577fcc 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -121,7 +121,7 @@ sp_cache_routine(THD *thd, stored_procedure_type type, sp_name *name,
bool lookup_only, sp_head **sp);
bool
-sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any);
+sp_exist_routines(THD *thd, TABLE_LIST *procs, bool is_proc);
bool
sp_show_create_routine(THD *thd, stored_procedure_type type, sp_name *name);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index a97827bae88..86b37742bea 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3439,10 +3439,11 @@ request_backoff_action(enum_open_table_action action_arg,
* We met a broken table that needs repair, or a table that
is not present on this MySQL server and needs re-discovery.
To perform the action, we need an exclusive metadata lock on
- the table. Acquiring an X lock while holding other shared
- locks is very deadlock-prone. If this is a multi- statement
- transaction that holds metadata locks for completed
- statements, we don't do it, and report an error instead.
+ the table. Acquiring X lock while holding other shared
+ locks can easily lead to deadlocks. We rely on MDL deadlock
+ detector to discover them. If this is a multi-statement
+ transaction that holds metadata locks for completed statements,
+ we should keep these locks after discovery/repair.
The action type in this case is OT_DISCOVER or OT_REPAIR.
* Our attempt to acquire an MDL lock lead to a deadlock,
detected by the MDL deadlock detector. The current
@@ -3483,7 +3484,7 @@ request_backoff_action(enum_open_table_action action_arg,
keep tables open between statements and a livelock
is not possible.
*/
- if (action_arg != OT_REOPEN_TABLES && m_has_locks)
+ if (action_arg == OT_BACKOFF_AND_RETRY && m_has_locks)
{
my_error(ER_LOCK_DEADLOCK, MYF(0));
m_thd->mark_transaction_to_rollback(true);
@@ -3512,6 +3513,32 @@ request_backoff_action(enum_open_table_action action_arg,
/**
+ An error handler to mark transaction to rollback on DEADLOCK error
+ during DISCOVER / REPAIR.
+*/
+class MDL_deadlock_discovery_repair_handler : public Internal_error_handler
+{
+public:
+ virtual bool handle_condition(THD *thd,
+ uint sql_errno,
+ const char* sqlstate,
+ Sql_condition::enum_warning_level level,
+ const char* msg,
+ Sql_condition ** cond_hdl)
+ {
+ if (sql_errno == ER_LOCK_DEADLOCK)
+ {
+ thd->mark_transaction_to_rollback(true);
+ }
+ /*
+ We have marked this transaction to rollback. Return false to allow
+ error to be reported or handled by other handlers.
+ */
+ return false;
+ }
+};
+
+/**
Recover from failed attempt of open table by performing requested action.
@pre This function should be called only with "action" != OT_NO_ACTION
@@ -3525,6 +3552,12 @@ bool
Open_table_context::recover_from_failed_open()
{
bool result= FALSE;
+ MDL_deadlock_discovery_repair_handler handler;
+ /*
+ Install error handler to mark transaction to rollback on DEADLOCK error.
+ */
+ m_thd->push_internal_handler(&handler);
+
/* Execute the action. */
switch (m_action)
{
@@ -3561,7 +3594,12 @@ Open_table_context::recover_from_failed_open()
result= FALSE;
}
- m_thd->mdl_context.release_transactional_locks();
+ /*
+ Rollback to start of the current statement to release exclusive lock
+ on table which was discovered but preserve locks from previous statements
+ in current transaction.
+ */
+ m_thd->mdl_context.rollback_to_savepoint(start_of_statement_svp());
break;
}
case OT_REPAIR:
@@ -3575,12 +3613,18 @@ Open_table_context::recover_from_failed_open()
m_failed_table->table_name, FALSE);
result= auto_repair_table(m_thd, m_failed_table);
- m_thd->mdl_context.release_transactional_locks();
+ /*
+ Rollback to start of the current statement to release exclusive lock
+ on table which was discovered but preserve locks from previous statements
+ in current transaction.
+ */
+ m_thd->mdl_context.rollback_to_savepoint(start_of_statement_svp());
break;
}
default:
DBUG_ASSERT(0);
}
+ m_thd->pop_internal_handler();
/*
Reset the pointers to conflicting MDL request and the
TABLE_LIST element, set when we need auto-discovery or repair,
@@ -6611,6 +6655,7 @@ find_field_in_tables(THD *thd, Item_ident *item,
if (item->cached_table)
{
+ DBUG_PRINT("info", ("using cached table"));
/*
This shortcut is used by prepared statements. We assume that
TABLE_LIST *first_table is not changed during query execution (which
@@ -7363,14 +7408,6 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
*/
result= FALSE;
- /*
- Save the lists made during natural join matching (because
- the matching done only once but we need the list in case
- of prepared statements).
- */
- table_ref_1->persistent_used_items= table_ref_1->used_items;
- table_ref_2->persistent_used_items= table_ref_2->used_items;
-
err:
if (arena)
thd->restore_active_arena(arena, &backup);
@@ -8418,11 +8455,6 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
}
}
#endif
- /*
- field_iterator.create_item() builds used_items which we
- have to save because changes made once and they are persistent
- */
- tables->persistent_used_items= tables->used_items;
if ((field= field_iterator.field()))
{
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index a367e0b44df..9b225de1ab8 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -961,6 +961,7 @@ THD::THD(bool is_wsrep_applier)
file_id = 0;
query_id= 0;
query_name_consts= 0;
+ semisync_info= 0;
db_charset= global_system_variables.collation_database;
bzero(ha_data, sizeof(ha_data));
mysys_var=0;
@@ -1418,6 +1419,7 @@ void THD::init(void)
bzero((char *) &org_status_var, sizeof(org_status_var));
start_bytes_received= 0;
last_commit_gtid.seq_no= 0;
+ status_in_global= 0;
#ifdef WITH_WSREP
wsrep_exec_mode= wsrep_applier ? REPL_RECV : LOCAL_STATE;
wsrep_conflict_state= NO_CONFLICT;
@@ -1540,6 +1542,7 @@ void THD::change_user(void)
cleanup();
reset_killed();
cleanup_done= 0;
+ status_in_global= 0;
init();
stmt_map.reset();
my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
@@ -1676,6 +1679,7 @@ THD::~THD()
mysql_audit_free_thd(this);
if (rgi_slave)
rgi_slave->cleanup_after_session();
+ my_free(semisync_info);
#endif
main_lex.free_set_stmt_mem_root();
free_root(&main_mem_root, MYF(0));
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 645862f8183..d9a0913d972 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -66,7 +66,6 @@ class Reprepare_observer;
class Relay_log_info;
struct rpl_group_info;
class Rpl_filter;
-
class Query_log_event;
class Load_log_event;
class Slave_log_event;
@@ -77,6 +76,7 @@ class Parser_state;
class Rows_log_event;
class Sroutine_hash_entry;
class user_var_entry;
+struct Trans_binlog_info;
class rpl_io_thread_info;
class rpl_sql_thread_info;
@@ -2043,6 +2043,9 @@ public:
*/
const char *where;
+ /* Needed by MariaDB semi sync replication */
+ Trans_binlog_info *semisync_info;
+
ulong client_capabilities; /* What the client supports */
ulong max_client_packet_length;
@@ -2111,11 +2114,11 @@ public:
/* Do not set socket timeouts for wait_timeout (used with threadpool) */
bool skip_wait_timeout;
- /* container for handler's private per-connection data */
- Ha_data ha_data[MAX_HA];
-
bool prepare_derived_at_open;
+ /* Set to 1 if status of this THD is already in global status */
+ bool status_in_global;
+
/*
To signal that the tmp table to be created is created for materialized
derived table or a view.
@@ -2124,6 +2127,9 @@ public:
bool save_prep_leaf_list;
+ /* container for handler's private per-connection data */
+ Ha_data ha_data[MAX_HA];
+
#ifndef MYSQL_CLIENT
binlog_cache_mngr * binlog_setup_trx_data();
@@ -3833,6 +3839,8 @@ public:
{
mysql_mutex_lock(&LOCK_status);
add_to_status(&global_status_var, &status_var);
+ /* Mark that this THD status has already been added in global status */
+ status_in_global= 1;
mysql_mutex_unlock(&LOCK_status);
}
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 27dea480025..a8c5569ba4a 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -54,6 +54,8 @@ public:
virtual void fetch(ulong num_rows);
virtual void close();
virtual ~Materialized_cursor();
+
+ void on_table_fill_finished();
};
@@ -74,6 +76,18 @@ public:
Select_materialize(THD *thd_arg, select_result *result_arg):
select_union(thd_arg), result(result_arg), materialized_cursor(0) {}
virtual bool send_result_set_metadata(List<Item> &list, uint flags);
+ bool send_eof()
+ {
+ if (materialized_cursor)
+ materialized_cursor->on_table_fill_finished();
+ return false;
+ }
+
+ void abort_result_set()
+ {
+ if (materialized_cursor)
+ materialized_cursor->on_table_fill_finished();
+ }
};
@@ -389,6 +403,29 @@ Materialized_cursor::~Materialized_cursor()
}
+/*
+ @brief
+ Perform actions that are to be done when cursor materialization has
+ finished.
+
+ @detail
+ This function is called when "OPEN $cursor" has finished filling the
+ temporary table with rows that the cursor will return.
+
+ Temporary table has table->field->orig_table pointing at the tables
+ that are used in the cursor definition query. Pointers to these tables
+ will not be valid after the query finishes. So, we do what is done for
+ regular tables: have orig_table point at the table that the fields belong
+ to.
+*/
+
+void Materialized_cursor::on_table_fill_finished()
+{
+ uint fields= table->s->fields;
+ for (uint i= 0; i < fields; i++)
+ table->field[i]->orig_table= table->field[i]->table;
+}
+
/***************************************************************************
Select_materialize
****************************************************************************/
diff --git a/sql/sql_digest.cc b/sql/sql_digest.cc
index cdbfcbb2e89..7f6f3bbfe9b 100644
--- a/sql/sql_digest.cc
+++ b/sql/sql_digest.cc
@@ -224,6 +224,7 @@ void compute_digest_text(const sql_digest_storage* digest_storage,
/* All identifiers are printed with their name. */
case IDENT:
case IDENT_QUOTED:
+ case TOK_IDENT:
{
char *id_ptr= NULL;
int id_len= 0;
@@ -259,13 +260,10 @@ void compute_digest_text(const sql_digest_storage* digest_storage,
break;
}
/* Copy the converted identifier into the digest string. */
- if (tok == IDENT_QUOTED)
- digest_output->append("`", 1);
+ digest_output->append("`", 1);
if (id_length > 0)
digest_output->append(id_string, id_length);
- if (tok == IDENT_QUOTED)
- digest_output->append("`", 1);
- digest_output->append(" ", 1);
+ digest_output->append("` ", 2);
}
break;
@@ -575,6 +573,15 @@ sql_digest_state* digest_add_token(sql_digest_state *state,
char *yytext= lex_token->lex_str.str;
size_t yylen= lex_token->lex_str.length;
+ /*
+ REDUCE:
+ TOK_IDENT := IDENT | IDENT_QUOTED
+ The parser gives IDENT or IDENT_TOKEN for the same text,
+ depending on the character set used.
+ We unify both to always print the same digest text,
+ and always have the same digest hash.
+ */
+ token= TOK_IDENT;
/* Add this token and identifier string to digest storage. */
store_token_identifier(digest_storage, token, yylen, yytext);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 0dce2f4c0ae..12f55acf5a0 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1934,7 +1934,6 @@ void st_select_lex::init_select()
with_sum_func= 0;
is_correlated= 0;
cur_pos_in_select_list= UNDEF_POS;
- non_agg_fields.empty();
cond_value= having_value= Item::COND_UNDEF;
inner_refs_list.empty();
insert_tables= 0;
@@ -1942,6 +1941,7 @@ void st_select_lex::init_select()
m_non_agg_field_used= false;
m_agg_func_used= false;
name_visibility_map= 0;
+ join= 0;
}
/*
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index da44cb31523..473fd18a2ee 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -870,8 +870,6 @@ public:
bool no_wrap_view_item;
/* exclude this select from check of unique_table() */
bool exclude_from_table_unique_test;
- /* List of fields that aren't under an aggregate function */
- List<Item_field> non_agg_fields;
/* index in the select list of the expression currently being fixed */
int cur_pos_in_select_list;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 7d64f263a4a..2870e90ef4d 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -299,6 +299,18 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
table->prepare_triggers_for_insert_stmt_or_event();
table->mark_columns_needed_for_insert();
+ if (table->vfield)
+ {
+ for (Field **vfield_ptr= table->vfield; *vfield_ptr; vfield_ptr++)
+ {
+ if ((*vfield_ptr)->stored_in_db)
+ {
+ thd->lex->unit.insert_table_with_stored_vcol= table;
+ break;
+ }
+ }
+ }
+
uint tot_length=0;
bool use_blobs= 0, use_vars= 0;
List_iterator_fast<Item> it(fields_vars);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d3e99e17275..8567587a48a 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -6848,6 +6848,8 @@ void THD::reset_for_next_command()
thd->reset_current_stmt_binlog_format_row();
thd->binlog_unsafe_warning_flags= 0;
+ thd->save_prep_leaf_list= false;
+
DBUG_PRINT("debug",
("is_current_stmt_binlog_format_row(): %d",
thd->is_current_stmt_binlog_format_row()));
@@ -8327,6 +8329,8 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
*/
for (table= tables; table; table= table->next_local)
{
+ if (table->is_jtbm())
+ continue;
if (table->derived)
table->grant.privilege= SELECT_ACL;
else if ((check_access(thd, UPDATE_ACL, table->db,
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index a43b8c7484a..6d8268efe86 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1077,7 +1077,7 @@ static bool plugin_add(MEM_ROOT *tmp_root,
if (name->str && plugin_find_internal(name, MYSQL_ANY_PLUGIN))
{
- report_error(report, ER_UDF_EXISTS, name->str);
+ report_error(report, ER_PLUGIN_INSTALLED, name->str);
DBUG_RETURN(TRUE);
}
/* Clear the whole struct to catch future extensions. */
@@ -1577,6 +1577,9 @@ int plugin_init(int *argc, char **argv, int flags)
/*
First we register builtin plugins
*/
+ if (global_system_variables.log_warnings >= 9)
+ sql_print_information("Initializing built-in plugins");
+
for (builtins= mysql_mandatory_plugins; *builtins || mandatory; builtins++)
{
if (!*builtins)
@@ -1640,6 +1643,8 @@ int plugin_init(int *argc, char **argv, int flags)
{
I_List_iterator<i_string> iter(opt_plugin_load_list);
i_string *item;
+ if (global_system_variables.log_warnings >= 9)
+ sql_print_information("Initializing plugins specified on the command line");
while (NULL != (item= iter++))
plugin_load_list(&tmp_root, item->ptr);
@@ -1763,6 +1768,9 @@ static void plugin_load(MEM_ROOT *tmp_root)
bool result;
DBUG_ENTER("plugin_load");
+ if (global_system_variables.log_warnings >= 9)
+ sql_print_information("Initializing installed plugins");
+
new_thd->thread_stack= (char*) &tables;
new_thd->store_globals();
new_thd->db= my_strdup("mysql", MYF(0));
@@ -1811,9 +1819,7 @@ static void plugin_load(MEM_ROOT *tmp_root)
the mutex here to satisfy the assert
*/
mysql_mutex_lock(&LOCK_plugin);
- if (plugin_add(tmp_root, &name, &dl, REPORT_TO_LOG))
- sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.",
- str_name.c_ptr(), str_dl.c_ptr());
+ plugin_add(tmp_root, &name, &dl, REPORT_TO_LOG);
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
mysql_mutex_unlock(&LOCK_plugin);
}
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 6d03d23f800..71e53dd86a2 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -79,8 +79,7 @@ fake_event_header(String* packet, Log_event_type event_type, ulong extra_len,
}
if (*do_checksum)
{
- *crc= my_checksum(0L, NULL, 0);
- *crc= my_checksum(*crc, (uchar*)header, sizeof(header));
+ *crc= my_checksum(0, (uchar*)header, sizeof(header));
}
return 0;
}
@@ -811,8 +810,8 @@ static int send_heartbeat_event(binlog_send_info *info,
if (do_checksum)
{
char b[BINLOG_CHECKSUM_LEN];
- ha_checksum crc= my_checksum(0L, NULL, 0);
- crc= my_checksum(crc, (uchar*) header, sizeof(header));
+ ha_checksum crc;
+ crc= my_checksum(0, (uchar*) header, sizeof(header));
crc= my_checksum(crc, (uchar*) p, ident_len);
int4store(b, crc);
packet->append(b, sizeof(b));
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index a15dd56fa75..b489756c784 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1550,6 +1550,9 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S
/* Cache constant expressions in WHERE, HAVING, ON clauses. */
cache_const_exprs();
+ if (setup_semijoin_loosescan(this))
+ DBUG_RETURN(1);
+
if (make_join_select(this, select, conds))
{
zero_result_cause=
@@ -5243,6 +5246,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
KEY_FIELD *key_fields, *end, *field;
uint sz;
uint m= MY_MAX(select_lex->max_equal_elems,1);
+ DBUG_ENTER("update_ref_and_keys");
+ DBUG_PRINT("enter", ("normal_tables: %llx", normal_tables));
SELECT_LEX *sel=thd->lex->current_select;
sel->cond_count= 0;
@@ -5289,7 +5294,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
sz= MY_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
((sel->cond_count*2 + sel->between_count)*m+1);
if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
- return TRUE; /* purecov: inspected */
+ DBUG_RETURN(TRUE); /* purecov: inspected */
and_level= 0;
field= end= key_fields;
*sargables= (SARGABLE_PARAM *) key_fields +
@@ -5300,7 +5305,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
if (my_init_dynamic_array2(keyuse, sizeof(KEYUSE),
thd->alloc(sizeof(KEYUSE) * 20), 20, 64,
MYF(MY_THREAD_SPECIFIC)))
- return TRUE;
+ DBUG_RETURN(TRUE);
if (cond)
{
@@ -5351,16 +5356,16 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
for ( ; field != end ; field++)
{
if (add_key_part(keyuse,field))
- return TRUE;
+ DBUG_RETURN(TRUE);
}
if (select_lex->ftfunc_list->elements)
{
if (add_ft_keys(keyuse,join_tab,cond,normal_tables))
- return TRUE;
+ DBUG_RETURN(TRUE);
}
- return FALSE;
+ DBUG_RETURN(FALSE);
}
@@ -9778,9 +9783,14 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
Check again if we should use an index.
We could have used an column from a previous table in
the index if we are using limit and this is the first table
+
+ (1) - Don't switch the used index if we are using semi-join
+ LooseScan on this table. Using different index will not
+ produce the desired ordering and de-duplication.
*/
if (!tab->table->is_filled_at_execution() &&
+ !tab->loosescan_match_tab && // (1)
((cond && (!tab->keys.is_subset(tab->const_keys) && i > 0)) ||
(!tab->const_keys.is_clear_all() && i == join->const_tables &&
join->unit->select_limit_cnt <
@@ -21906,7 +21916,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
Item_field *field;
int cur_pos_in_select_list= 0;
List_iterator<Item> li(fields);
- List_iterator<Item_field> naf_it(thd->lex->current_select->non_agg_fields);
+ List_iterator<Item_field> naf_it(thd->lex->current_select->join->non_agg_fields);
field= naf_it++;
while (field && (item=li++))
diff --git a/sql/sql_select.h b/sql/sql_select.h
index ca69c0c23eb..57c66bae8e2 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -745,8 +745,7 @@ public:
struct st_position *pos,
struct st_position *loose_scan_pos);
friend bool get_best_combination(JOIN *join);
- friend int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
- uint no_jbuf_after);
+ friend int setup_semijoin_loosescan(JOIN *join);
friend void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
};
@@ -963,6 +962,9 @@ public:
Item *pre_sort_idx_pushed_cond;
void clean_pre_sort_join_tab();
+ /* List of fields that aren't under an aggregate function */
+ List<Item_field> non_agg_fields;
+
/*
For "Using temporary+Using filesort" queries, JOIN::join_tab can point to
either:
@@ -1382,6 +1384,7 @@ public:
all_fields= fields_arg;
if (&fields_list != &fields_arg) /* Avoid valgrind-warning */
fields_list= fields_arg;
+ non_agg_fields.empty();
bzero((char*) &keyuse,sizeof(keyuse));
tmp_table_param.init();
tmp_table_param.end_write_records= HA_POS_ERROR;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index ddad6096bd8..28e623f3af1 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3363,7 +3363,10 @@ void calc_sum_of_all_status(STATUS_VAR *to)
/* Add to this status from existing threads */
while ((tmp= it++))
- add_to_status(to, &tmp->status_var);
+ {
+ if (!tmp->status_in_global)
+ add_to_status(to, &tmp->status_var);
+ }
mysql_mutex_unlock(&LOCK_thread_count);
DBUG_VOID_RETURN;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2ce4a08410d..da7d144f3d8 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4680,12 +4680,12 @@ int create_table_impl(THD *thd,
bool table_creation_was_logged= tmp_table->s->table_creation_was_logged;
if (options.or_replace())
{
- bool is_trans;
+ bool tmp;
/*
We are using CREATE OR REPLACE on an existing temporary table
Remove the old table so that we can re-create it.
*/
- if (drop_temporary_table(thd, tmp_table, &is_trans))
+ if (drop_temporary_table(thd, tmp_table, &tmp))
goto err;
}
else if (options.if_not_exists())
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index ec65bd037b9..8e7525893eb 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -224,7 +224,7 @@ TEST_join(JOIN *join)
#define FT_KEYPART (MAX_FIELDS+10)
-void print_keyuse(KEYUSE *keyuse)
+static void print_keyuse(KEYUSE *keyuse)
{
char buff[256];
char buf2[64];
@@ -242,14 +242,11 @@ void print_keyuse(KEYUSE *keyuse)
else
fieldname= key_info->key_part[keyuse->keypart].field->field_name;
ll2str(keyuse->used_tables, buf2, 16, 0);
- DBUG_LOCK_FILE;
fprintf(DBUG_FILE, "KEYUSE: %s.%s=%s optimize: %u used_tables: %s "
"ref_table_rows: %lu keypart_map: %0lx\n",
keyuse->table->alias.c_ptr(), fieldname, str.ptr(),
(uint) keyuse->optimize, buf2, (ulong) keyuse->ref_table_rows,
(ulong) keyuse->keypart_map);
- DBUG_UNLOCK_FILE;
- //key_part_map keypart_map; --?? there can be several?
}
@@ -258,9 +255,9 @@ void print_keyuse_array(DYNAMIC_ARRAY *keyuse_array)
{
DBUG_LOCK_FILE;
fprintf(DBUG_FILE, "KEYUSE array (%d elements)\n", keyuse_array->elements);
- DBUG_UNLOCK_FILE;
for(uint i=0; i < keyuse_array->elements; i++)
print_keyuse((KEYUSE*)dynamic_array_ptr(keyuse_array, i));
+ DBUG_UNLOCK_FILE;
}
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 356f68693bd..c8350838ee8 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1178,7 +1178,6 @@ bool st_select_lex::cleanup()
{
error= (bool) ((uint) error | (uint) lex_unit->cleanup());
}
- non_agg_fields.empty();
inner_refs_list.empty();
exclude_from_table_unique_test= FALSE;
DBUG_RETURN(error);
@@ -1189,6 +1188,7 @@ void st_select_lex::cleanup_all_joins(bool full)
{
SELECT_LEX_UNIT *unit;
SELECT_LEX *sl;
+ DBUG_ENTER("st_select_lex::cleanup_all_joins");
if (join)
join->cleanup(full);
@@ -1196,6 +1196,7 @@ void st_select_lex::cleanup_all_joins(bool full)
for (unit= first_inner_unit(); unit; unit= unit->next_unit())
for (sl= unit->first_select(); sl; sl= sl->next_select())
sl->cleanup_all_joins(full);
+ DBUG_VOID_RETURN;
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 0f17716974c..7a66cc3734c 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1186,7 +1186,7 @@ bool unsafe_key_update(List<TABLE_LIST> leaves, table_map tables_for_update)
while ((tl= it++))
{
- if (tl->table->map & tables_for_update)
+ if (!tl->is_jtbm() && (tl->table->map & tables_for_update))
{
TABLE *table1= tl->table;
bool primkey_clustered= (table1->file->primary_key_is_clustered() &&
@@ -1203,6 +1203,8 @@ bool unsafe_key_update(List<TABLE_LIST> leaves, table_map tables_for_update)
it2.rewind();
while ((tl2= it2++))
{
+ if (tl2->is_jtbm())
+ continue;
/*
Look at "next" tables only since all previous tables have
already been checked
@@ -1434,6 +1436,9 @@ int mysql_multi_update_prepare(THD *thd)
{
TABLE *table= tl->table;
+ if (tl->is_jtbm())
+ continue;
+
/* if table will be updated then check that it is unique */
if (table->map & tables_for_update)
{
@@ -1482,6 +1487,8 @@ int mysql_multi_update_prepare(THD *thd)
for (tl= table_list; tl; tl= tl->next_local)
{
bool not_used= false;
+ if (tl->is_jtbm())
+ continue;
if (multi_update_check_table_access(thd, tl, tables_for_update, &not_used))
DBUG_RETURN(TRUE);
}
@@ -1489,6 +1496,8 @@ int mysql_multi_update_prepare(THD *thd)
/* check single table update for view compound from several tables */
for (tl= table_list; tl; tl= tl->next_local)
{
+ if (tl->is_jtbm())
+ continue;
if (tl->is_merged_derived())
{
TABLE_LIST *for_update= 0;
@@ -1518,6 +1527,8 @@ int mysql_multi_update_prepare(THD *thd)
ti.rewind();
while ((tl= ti++))
{
+ if (tl->is_jtbm())
+ continue;
TABLE *table= tl->table;
TABLE_LIST *tlist;
if (!(tlist= tl->top_table())->derived)
@@ -1661,6 +1672,9 @@ int multi_update::prepare(List<Item> &not_used_values,
*/
while ((table_ref= ti++))
{
+ if (table_ref->is_jtbm())
+ continue;
+
TABLE *table= table_ref->table;
if (tables_to_update & table->map)
{
@@ -1680,6 +1694,9 @@ int multi_update::prepare(List<Item> &not_used_values,
ti.rewind();
while ((table_ref= ti++))
{
+ if (table_ref->is_jtbm())
+ continue;
+
TABLE *table= table_ref->table;
if (tables_to_update & table->map)
{
@@ -1710,6 +1727,8 @@ int multi_update::prepare(List<Item> &not_used_values,
while ((table_ref= ti++))
{
/* TODO: add support of view of join support */
+ if (table_ref->is_jtbm())
+ continue;
TABLE *table=table_ref->table;
leaf_table_count++;
if (tables_to_update & table->map)
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 0a04d20ae4b..396b4c0ae83 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -325,6 +325,14 @@ static Sys_var_long Sys_pfs_digest_size(
DEFAULT(-1),
BLOCK_SIZE(1));
+static Sys_var_long Sys_pfs_max_digest_length(
+ "performance_schema_max_digest_length",
+ "Maximum length considered for digest text, when stored in performance_schema tables.",
+ PARSED_EARLY READ_ONLY GLOBAL_VAR(pfs_param.m_max_digest_length),
+ CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024 * 1024),
+ DEFAULT(1024),
+ BLOCK_SIZE(1));
+
static Sys_var_long Sys_pfs_connect_attrs_size(
"performance_schema_session_connect_attrs_size",
"Size of session attribute string buffer per thread."
@@ -1349,7 +1357,7 @@ static Sys_var_ulong Sys_max_connect_errors(
static Sys_var_uint Sys_max_digest_length(
"max_digest_length", "Maximum length considered for digest text.",
- PARSED_EARLY READ_ONLY GLOBAL_VAR(max_digest_length),
+ READ_ONLY GLOBAL_VAR(max_digest_length),
CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, 1024 * 1024), DEFAULT(1024), BLOCK_SIZE(1));
diff --git a/sql/table.cc b/sql/table.cc
index f233fd19860..76cb4b86a81 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -5301,7 +5301,7 @@ Item *Field_iterator_table::create_item(THD *thd)
if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
!thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
{
- select->non_agg_fields.push_back(item);
+ select->join->non_agg_fields.push_back(item);
item->marker= select->cur_pos_in_select_list;
select->set_non_agg_field_used(true);
}
@@ -5366,6 +5366,12 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
item->maybe_null= TRUE;
/* Save item in case we will need to fall back to materialization. */
view->used_items.push_front(item, thd->mem_root);
+ /*
+ If we create this reference on persistent memory then it should be
+ present in persistent list
+ */
+ if (thd->mem_root == thd->stmt_arena->mem_root)
+ view->persistent_used_items.push_front(item, thd->mem_root);
DBUG_RETURN(item);
}
@@ -7086,6 +7092,7 @@ bool TABLE_LIST::handle_derived(LEX *lex, uint phases)
{
SELECT_LEX_UNIT *unit;
DBUG_ENTER("handle_derived");
+ DBUG_PRINT("enter", ("phases: 0x%x", phases));
if ((unit= get_unit()))
{
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())