summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc12
-rw-r--r--sql/field.h12
-rw-r--r--sql/ha_partition.cc9
-rw-r--r--sql/handler.cc10
-rw-r--r--sql/item.cc111
-rw-r--r--sql/item.h2
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/item_strfunc.h2
-rw-r--r--sql/item_subselect.cc3
-rw-r--r--sql/item_sum.cc8
-rw-r--r--sql/log.cc3
-rw-r--r--sql/log_event.cc4
-rw-r--r--sql/opt_range.cc19
-rw-r--r--sql/opt_split.cc71
-rw-r--r--sql/opt_subselect.cc43
-rw-r--r--sql/partition_info.cc33
-rw-r--r--sql/partition_info.h4
-rw-r--r--sql/protocol.cc8
-rw-r--r--sql/share/errmsg-utf8.txt4
-rw-r--r--sql/slave.cc9
-rw-r--r--sql/sql_base.cc7
-rw-r--r--sql/sql_lex.cc7
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_locale.cc74
-rw-r--r--sql/sql_plugin.cc2
-rw-r--r--sql/sql_plugin_services.inl (renamed from sql/sql_plugin_services.ic)0
-rw-r--r--sql/sql_prepare.cc4
-rw-r--r--sql/sql_select.cc69
-rw-r--r--sql/sql_select.h1
-rw-r--r--sql/sql_sequence.cc11
-rw-r--r--sql/sql_show.cc2
-rw-r--r--sql/sql_table.cc54
-rw-r--r--sql/sql_view.cc14
-rw-r--r--sql/sys_vars.cc2
-rw-r--r--sql/sys_vars.inl (renamed from sql/sys_vars.ic)0
-rw-r--r--sql/table.cc37
-rw-r--r--sql/table.h2
-rw-r--r--sql/tztime.cc36
-rw-r--r--sql/wsrep_mysqld.cc23
39 files changed, 441 insertions, 275 deletions
diff --git a/sql/field.cc b/sql/field.cc
index e3aa7d149a0..fb331f2f185 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -9822,16 +9822,8 @@ bool Field_num::is_equal(const Column_definition &new_field) const
}
-bool Field_enum::can_optimize_range(const Item_bool_func *cond,
- const Item *item,
- bool is_eq_func) const
-{
- return item->cmp_type() != TIME_RESULT;
-}
-
-
-bool Field_enum::can_optimize_keypart_ref(const Item_bool_func *cond,
- const Item *item) const
+bool Field_enum::can_optimize_range_or_keypart_ref(const Item_bool_func *cond,
+ const Item *item) const
{
switch (item->cmp_type())
{
diff --git a/sql/field.h b/sql/field.h
index c19a501f1f9..c17d698a856 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -4284,6 +4284,8 @@ uint gis_field_options_read(const uchar *buf, size_t buf_len,
class Field_enum :public Field_str {
static void do_field_enum(Copy_field *copy_field);
+ bool can_optimize_range_or_keypart_ref(const Item_bool_func *cond,
+ const Item *item) const;
protected:
uint packlength;
public:
@@ -4370,7 +4372,10 @@ public:
const uchar *from_end, uint param_data);
bool can_optimize_keypart_ref(const Item_bool_func *cond,
- const Item *item) const;
+ const Item *item) const
+ {
+ return can_optimize_range_or_keypart_ref(cond, item);
+ }
bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const
{
@@ -4385,7 +4390,10 @@ public:
}
bool can_optimize_range(const Item_bool_func *cond,
const Item *item,
- bool is_eq_func) const;
+ bool is_eq_func) const
+ {
+ return can_optimize_range_or_keypart_ref(cond, item);
+ }
private:
int save_field_metadata(uchar *first_byte);
bool is_equal(const Column_definition &new_field) const;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 7f53eeb565c..7666563891d 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -3947,8 +3947,9 @@ int ha_partition::external_lock(THD *thd, int lock_type)
These commands may be excluded because working history partition is needed
only for versioned DML. */
thd->lex->sql_command != SQLCOM_SELECT &&
- thd->lex->sql_command != SQLCOM_INSERT_SELECT)
- m_part_info->vers_set_hist_part(thd);
+ thd->lex->sql_command != SQLCOM_INSERT_SELECT &&
+ (error= m_part_info->vers_set_hist_part(thd)))
+ goto err_handler;
}
DBUG_RETURN(0);
@@ -4085,7 +4086,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
i= bitmap_get_next_set(&m_part_info->lock_partitions, i))
{
if (unlikely((error= m_file[i]->start_stmt(thd, lock_type))))
- break;
+ DBUG_RETURN(error);
/* Add partition to be called in reset(). */
bitmap_set_bit(&m_partitions_to_reset, i);
}
@@ -4104,7 +4105,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
// TODO: MDEV-20345 (see above)
thd->lex->sql_command != SQLCOM_SELECT &&
thd->lex->sql_command != SQLCOM_INSERT_SELECT)
- m_part_info->vers_set_hist_part(thd);
+ error= m_part_info->vers_set_hist_part(thd);
default:;
}
DBUG_RETURN(error);
diff --git a/sql/handler.cc b/sql/handler.cc
index 49849f46908..4aff21851a6 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4013,6 +4013,9 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_TABLE_IN_FK_CHECK:
textno= ER_TABLE_IN_FK_CHECK;
break;
+ case HA_ERR_PARTITION_LIST:
+ my_error(ER_VERS_NOT_ALLOWED, errflag, table->s->db.str, table->s->table_name.str);
+ DBUG_VOID_RETURN;
default:
{
/* The error was "unknown" to this function.
@@ -7545,6 +7548,8 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields(
List_iterator<Create_field> it(alter_info->create_list);
while (Create_field *f= it++)
{
+ if (f->vers_sys_field())
+ continue;
if ((f->versioning == Column_definition::VERSIONING_NOT_SET && !add_versioning) ||
f->versioning == Column_definition::WITHOUT_VERSIONING)
{
@@ -7566,9 +7571,10 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields(
if (!(options & HA_VERSIONED_TABLE))
return false;
+ uint versioned_fields= 0;
+
if (!(alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING))
{
- uint versioned_fields= 0;
uint fieldnr= 0;
List_iterator<Create_field> field_it(alter_info->create_list);
while (Create_field *f= field_it++)
@@ -7599,7 +7605,7 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields(
}
}
- if (!(alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING))
+ if (!(alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING) && !versioned_fields)
return false;
bool can_native= ha_check_storage_engine_flag(db_type,
diff --git a/sql/item.cc b/sql/item.cc
index c45212af617..534f614b173 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -70,12 +70,11 @@ bool cmp_items(Item *a, Item *b)
/**
Set max_sum_func_level if it is needed
*/
-inline void set_max_sum_func_level(SELECT_LEX *select)
+inline void set_max_sum_func_level(THD *thd, SELECT_LEX *select)
{
- LEX *lex_s= select->parent_lex;
- if (lex_s->in_sum_func &&
- lex_s->in_sum_func->nest_level >= select->nest_level)
- set_if_bigger(lex_s->in_sum_func->max_sum_func_level,
+ if (thd->lex->in_sum_func &&
+ thd->lex->in_sum_func->nest_level >= select->nest_level)
+ set_if_bigger(thd->lex->in_sum_func->max_sum_func_level,
select->nest_level - 1);
}
@@ -644,7 +643,6 @@ Item_ident::Item_ident(THD *thd, Name_resolution_context *context_arg,
cached_table(0), depended_from(0), can_be_depended(TRUE)
{
name= *field_name_arg;
- DBUG_ASSERT(!context || context->select_lex);
}
@@ -661,7 +659,6 @@ Item_ident::Item_ident(THD *thd, TABLE_LIST *view_arg,
cached_table(NULL), depended_from(NULL), can_be_depended(TRUE)
{
name= *field_name_arg;
- DBUG_ASSERT(!context || context->select_lex);
}
@@ -683,9 +680,7 @@ Item_ident::Item_ident(THD *thd, Item_ident *item)
cached_table(item->cached_table),
depended_from(item->depended_from),
can_be_depended(item->can_be_depended)
-{
- DBUG_ASSERT(!context || context->select_lex);
-}
+{}
void Item_ident::cleanup()
{
@@ -5528,14 +5523,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
*/
Name_resolution_context *last_checked_context= context;
Item **ref= (Item **) not_found_item;
- /*
- There are cases when name resolution context is absent (when we are not
- doing name resolution), but here the name resolution context should
- be present because we are doing name resolution
- */
- DBUG_ASSERT(context);
- SELECT_LEX *current_sel= context->select_lex;
- LEX *lex_s= context->select_lex->parent_lex;
+ SELECT_LEX *current_sel= thd->lex->current_select;
Name_resolution_context *outer_context= 0;
SELECT_LEX *select= 0;
/* Currently derived tables cannot be correlated */
@@ -5637,18 +5625,19 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
return -1;
thd->change_item_tree(reference, rf);
select->inner_refs_list.push_back(rf, thd->mem_root);
- rf->in_sum_func= lex_s->in_sum_func;
+ rf->in_sum_func= thd->lex->in_sum_func;
}
/*
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
max_arg_level for the function if it's needed.
*/
- if (lex_s->in_sum_func &&
- lex_s->in_sum_func->nest_level >= select->nest_level)
+ if (thd->lex->in_sum_func &&
+ thd->lex == context->select_lex->parent_lex &&
+ thd->lex->in_sum_func->nest_level >= select->nest_level)
{
Item::Type ref_type= (*reference)->type();
- set_if_bigger(lex_s->in_sum_func->max_arg_level,
+ set_if_bigger(thd->lex->in_sum_func->max_arg_level,
select->nest_level);
set_field(*from_field);
fixed= 1;
@@ -5669,10 +5658,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0), false);
- if (lex_s->in_sum_func &&
- lex_s->in_sum_func->nest_level >= select->nest_level)
+ if (thd->lex->in_sum_func &&
+ thd->lex == context->select_lex->parent_lex &&
+ thd->lex->in_sum_func->nest_level >= select->nest_level)
{
- set_if_bigger(lex_s->in_sum_func->max_arg_level,
+ set_if_bigger(thd->lex->in_sum_func->max_arg_level,
select->nest_level);
}
/*
@@ -5764,7 +5754,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
{
outer_context->select_lex->inner_refs_list.push_back((Item_outer_ref*)rf,
thd->mem_root);
- ((Item_outer_ref*)rf)->in_sum_func= lex_s->in_sum_func;
+ ((Item_outer_ref*)rf)->in_sum_func= thd->lex->in_sum_func;
}
thd->change_item_tree(reference, rf);
/*
@@ -5779,7 +5769,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
- set_max_sum_func_level(select);
+ set_max_sum_func_level(thd, select);
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex, rf,
rf, false);
@@ -5792,7 +5782,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
- set_max_sum_func_level(select);
+ set_max_sum_func_level(thd, select);
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex,
this, (Item_ident*)*reference, false);
@@ -5870,20 +5860,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(fixed == 0);
Field *from_field= (Field *)not_found_field;
bool outer_fixed= false;
- SELECT_LEX *select;
- LEX *lex_s;
- if (context)
- {
- select= context->select_lex;
- lex_s= context->select_lex->parent_lex;
- }
- else
- {
- // No real name resolution, used somewhere in SP
- DBUG_ASSERT(field);
- select= NULL;
- lex_s= NULL;
- }
+ SELECT_LEX *select= thd->lex->current_select;
if (select && select->in_tvc)
{
@@ -5951,7 +5928,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
- set_max_sum_func_level(select);
+ set_max_sum_func_level(thd, select);
set_field(new_field);
depended_from= (*((Item_field**)res))->depended_from;
return 0;
@@ -5979,7 +5956,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
- set_max_sum_func_level(select);
+ set_max_sum_func_level(thd, select);
return FALSE;
}
}
@@ -6016,11 +5993,12 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
goto mark_non_agg_field;
}
- if (lex_s &&
- lex_s->in_sum_func &&
- lex_s->in_sum_func->nest_level ==
+ if (!thd->lex->current_select->no_wrap_view_item &&
+ thd->lex->in_sum_func &&
+ thd->lex == select->parent_lex &&
+ thd->lex->in_sum_func->nest_level ==
select->nest_level)
- set_if_bigger(lex_s->in_sum_func->max_arg_level,
+ set_if_bigger(thd->lex->in_sum_func->max_arg_level,
select->nest_level);
/*
if it is not expression from merged VIEW we will set this field.
@@ -6086,9 +6064,8 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (field->vcol_info)
fix_session_vcol_expr_for_read(thd, field, field->vcol_info);
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
- !outer_fixed &&
+ !outer_fixed && !thd->lex->in_sum_func &&
select &&
- !lex_s->in_sum_func &&
select->cur_pos_in_select_list != UNDEF_POS &&
select->join)
{
@@ -6123,13 +6100,13 @@ mark_non_agg_field:
*/
select_lex= context->select_lex;
}
- if (!lex_s || !lex_s->in_sum_func)
+ if (!thd->lex->in_sum_func)
select_lex->set_non_agg_field_used(true);
else
{
if (outer_fixed)
- lex_s->in_sum_func->outer_fields.push_back(this, thd->mem_root);
- else if (lex_s->in_sum_func->nest_level !=
+ thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root);
+ else if (thd->lex->in_sum_func->nest_level !=
select->nest_level)
select_lex->set_non_agg_field_used(true);
}
@@ -7588,12 +7565,6 @@ Item *get_field_item_for_having(THD *thd, Item *item, st_select_lex *sel)
return NULL;
}
-Item *Item_ident::derived_field_transformer_for_having(THD *thd, uchar *arg)
-{
- st_select_lex *sel= (st_select_lex *)arg;
- context= &sel->context;
- return this;
-}
Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
{
@@ -7613,13 +7584,12 @@ Item *Item_field::derived_field_transformer_for_having(THD *thd, uchar *arg)
Item *Item_direct_view_ref::derived_field_transformer_for_having(THD *thd,
uchar *arg)
{
- st_select_lex *sel= (st_select_lex *)arg;
- context= &sel->context;
if ((*ref)->marker & SUBSTITUTION_FL)
{
this->marker|= SUBSTITUTION_FL;
return this;
}
+ st_select_lex *sel= (st_select_lex *)arg;
table_map tab_map= sel->master_unit()->derived->table->map;
if ((item_equal && !(item_equal->used_tables() & tab_map)) ||
!item_equal)
@@ -7882,9 +7852,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
{
enum_parsing_place place= NO_MATTER;
DBUG_ASSERT(fixed == 0);
-
- SELECT_LEX *current_sel= context->select_lex;
- LEX *lex_s= context->select_lex->parent_lex;
+ SELECT_LEX *current_sel= thd->lex->current_select;
if (set_properties_only)
{
@@ -8045,10 +8013,11 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
the nest level of the enclosing set function : adjust the value of
max_arg_level for the function if it's needed.
*/
- if (lex_s->in_sum_func &&
- lex_s->in_sum_func->nest_level >=
+ if (thd->lex->in_sum_func &&
+ thd->lex == context->select_lex->parent_lex &&
+ thd->lex->in_sum_func->nest_level >=
last_checked_context->select_lex->nest_level)
- set_if_bigger(lex_s->in_sum_func->max_arg_level,
+ set_if_bigger(thd->lex->in_sum_func->max_arg_level,
last_checked_context->select_lex->nest_level);
return FALSE;
}
@@ -8068,10 +8037,11 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
the nest level of the enclosing set function : adjust the value of
max_arg_level for the function if it's needed.
*/
- if (lex_s->in_sum_func &&
- lex_s->in_sum_func->nest_level >=
+ if (thd->lex->in_sum_func &&
+ thd->lex == context->select_lex->parent_lex &&
+ thd->lex->in_sum_func->nest_level >=
last_checked_context->select_lex->nest_level)
- set_if_bigger(lex_s->in_sum_func->max_arg_level,
+ set_if_bigger(thd->lex->in_sum_func->max_arg_level,
last_checked_context->select_lex->nest_level);
}
}
@@ -9595,6 +9565,7 @@ bool Item_default_value::val_native_result(THD *thd, Native *to)
return Item_field::val_native_result(thd, to);
}
+
table_map Item_default_value::used_tables() const
{
if (!field || !field->default_value)
diff --git a/sql/item.h b/sql/item.h
index 2e4383cf9ac..ad455457934 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -3324,7 +3324,6 @@ public:
Collect outer references
*/
virtual bool collect_outer_ref_processor(void *arg);
- Item *derived_field_transformer_for_having(THD *thd, uchar *arg);
friend bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name,
const char *table_name, List_iterator<Item> *it,
@@ -5452,6 +5451,7 @@ public:
return ref ? (*ref)->get_typelib() : NULL;
}
+ bool is_json_type() { return (*ref)->is_json_type(); }
bool walk(Item_processor processor, bool walk_subquery, void *arg)
{
if (ref && *ref)
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index a250a968418..68d49b90475 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2273,8 +2273,10 @@ char *Item_func_password::alloc(THD *thd, const char *password,
String *Item_func_encrypt::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
+
#ifdef HAVE_CRYPT
String *res =args[0]->val_str(str);
+
char salt[3],*salt_ptr;
if ((null_value=args[0]->null_value))
return 0;
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 9995c7c644d..82b30369734 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -856,7 +856,7 @@ public:
String *val_str(String *);
bool fix_length_and_dec()
{
- max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
+ max_length= NAME_CHAR_LEN * system_charset_info->mbmaxlen;
maybe_null=1;
return FALSE;
}
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 56ab0f648ee..519896065e5 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -5227,9 +5227,8 @@ bool subselect_hash_sj_engine::make_semi_join_conds()
tmp_table_ref->init_one_table(&empty_clex_str, &table_name, NULL, TL_READ);
tmp_table_ref->table= tmp_table;
- context= new (thd->mem_root) Name_resolution_context;
+ context= new Name_resolution_context;
context->init();
- context->select_lex= item_in->unit->first_select();
context->first_name_resolution_table=
context->last_name_resolution_table= tmp_table_ref;
semi_join_conds_context= context;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index a81cfd7ea82..581c94bd191 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -72,7 +72,6 @@ size_t Item_sum::ram_limitation(THD *thd)
bool Item_sum::init_sum_func_check(THD *thd)
{
SELECT_LEX *curr_sel= thd->lex->current_select;
- LEX *lex_s= (curr_sel ? curr_sel->parent_lex : thd->lex);
if (curr_sel && curr_sel->name_visibility_map.is_clear_all())
{
for (SELECT_LEX *sl= curr_sel; sl; sl= sl->context.outer_select())
@@ -88,9 +87,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
return TRUE;
}
/* Set a reference to the nesting set function if there is any */
- in_sum_func= lex_s->in_sum_func;
+ in_sum_func= thd->lex->in_sum_func;
/* Save a pointer to object to be used in items for nested set functions */
- lex_s->in_sum_func= this;
+ thd->lex->in_sum_func= this;
nest_level= thd->lex->current_select->nest_level;
ref_by= 0;
aggr_level= -1;
@@ -157,7 +156,6 @@ bool Item_sum::init_sum_func_check(THD *thd)
bool Item_sum::check_sum_func(THD *thd, Item **ref)
{
SELECT_LEX *curr_sel= thd->lex->current_select;
- LEX *lex_s= curr_sel->parent_lex;
nesting_map allow_sum_func(thd->lex->allow_sum_func);
allow_sum_func.intersect(curr_sel->name_visibility_map);
bool invalid= FALSE;
@@ -320,7 +318,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
if (sum_func() == SP_AGGREGATE_FUNC)
aggr_sel->set_custom_agg_func_used(true);
update_used_tables();
- lex_s->in_sum_func= in_sum_func;
+ thd->lex->in_sum_func= in_sum_func;
return FALSE;
}
diff --git a/sql/log.cc b/sql/log.cc
index c5a192d56d3..5fbfa0f75d4 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1692,7 +1692,7 @@ static int binlog_close_connection(handlerton *hton, THD *thd)
binlog_cache_mngr *const cache_mngr=
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
#ifdef WITH_WSREP
- if (cache_mngr && !cache_mngr->trx_cache.empty()) {
+ if (WSREP(thd) && cache_mngr && !cache_mngr->trx_cache.empty()) {
IO_CACHE* cache= cache_mngr->get_binlog_cache_log(true);
uchar *buf;
size_t len=0;
@@ -3571,6 +3571,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
opt_slave_sql_verify_checksum ? (enum_binlog_checksum_alg) binlog_checksum_options
: BINLOG_CHECKSUM_ALG_OFF;
s.checksum_alg= relay_log_checksum_alg;
+ s.set_relay_log_event();
}
else
s.checksum_alg= (enum_binlog_checksum_alg)binlog_checksum_options;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index a1562016aa4..de929330f2a 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -168,6 +168,7 @@ static const char *HA_ERR(int i)
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
+ case HA_ERR_PARTITION_LIST : return "HA_ERR_PARTITION_LIST";
}
return "No Error!";
}
@@ -6567,7 +6568,8 @@ int Format_description_log_event::do_apply_event(rpl_group_info *rgi)
original place when it comes to us; we'll know this by checking
log_pos ("artificial" events have log_pos == 0).
*/
- if (!is_artificial_event() && created && thd->transaction.all.ha_list)
+ if (!thd->rli_fake &&
+ !is_artificial_event() && created && thd->transaction.all.ha_list)
{
/* This is not an error (XA is safe), just an information */
rli->report(INFORMATION_LEVEL, 0, NULL,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 7599401dcb4..a2bbe1447e9 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -10120,7 +10120,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
uint max_part_no= MY_MAX(key1->max_part_no, key2->max_part_no);
- for (key2=key2->first(); key2; )
+ for (key2=key2->first(); ; )
{
/*
key1 consists of one or more ranges. tmp is the range currently
@@ -10134,6 +10134,16 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
^
tmp
*/
+ if (key1->min_flag & NO_MIN_RANGE &&
+ key1->max_flag & NO_MAX_RANGE)
+ {
+ if (key1->maybe_flag)
+ return new SEL_ARG(SEL_ARG::MAYBE_KEY);
+ return 0; // Always true OR
+ }
+ if (!key2)
+ break;
+
SEL_ARG *tmp=key1->find_range(key2);
/*
@@ -10204,6 +10214,13 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
key2->copy_min(tmp);
if (!(key1=key1->tree_delete(tmp)))
{ // Only one key in tree
+ if (key2->min_flag & NO_MIN_RANGE &&
+ key2->max_flag & NO_MAX_RANGE)
+ {
+ if (key2->maybe_flag)
+ return new SEL_ARG(SEL_ARG::MAYBE_KEY);
+ return 0; // Always true OR
+ }
key1=key2;
key1->make_root();
key2=key2_next;
diff --git a/sql/opt_split.cc b/sql/opt_split.cc
index d272638f00c..a356335855c 100644
--- a/sql/opt_split.cc
+++ b/sql/opt_split.cc
@@ -310,6 +310,8 @@ struct SplM_field_ext_info: public SplM_field_info
occurred also in the select list of this join
9. There are defined some keys usable for ref access of fields from C
with available statistics.
+ 10. The select doesn't use WITH ROLLUP (This limitation can probably be
+ lifted)
@retval
true if the answer is positive
@@ -326,7 +328,8 @@ bool JOIN::check_for_splittable_materialized()
(unit->first_select()->next_select()) || // !(3)
(derived->prohibit_cond_pushdown) || // !(4)
(derived->is_recursive_with_table()) || // !(5)
- (table_count == 0 || const_tables == top_join_tab_count)) // !(6)
+ (table_count == 0 || const_tables == top_join_tab_count) || // !(6)
+ rollup.state != ROLLUP::STATE_NONE) // (10)
return false;
if (group_list) // (7.1)
{
@@ -1045,16 +1048,16 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
Inject equalities for splitting used by the materialization join
@param
- remaining_tables used to filter out the equalities that cannot
+ excluded_tables used to filter out the equalities that cannot
be pushed.
@details
- This function is called by JOIN_TAB::fix_splitting that is used
- to fix the chosen splitting of a splittable materialized table T
- in the final query execution plan. In this plan the table T
- is joined just before the 'remaining_tables'. So all equalities
- usable for splitting whose right parts do not depend on any of
- remaining tables can be pushed into join for T.
+ This function injects equalities pushed into a derived table T for which
+ the split optimization has been chosen by the optimizer. The function
+ is called by JOIN::inject_splitting_cond_for_all_tables_with_split_op().
+ All equalities usable for splitting T whose right parts do not depend on
+ any of the 'excluded_tables' can be pushed into the where clause of the
+ derived table T.
The function also marks the select that specifies T as
UNCACHEABLE_DEPENDENT_INJECTED.
@@ -1063,7 +1066,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count,
true on failure
*/
-bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
+bool JOIN::inject_best_splitting_cond(table_map excluded_tables)
{
Item *inj_cond= 0;
List<Item> *inj_cond_list= &spl_opt_info->inj_cond_list;
@@ -1071,7 +1074,7 @@ bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
KEY_FIELD *added_key_field;
while ((added_key_field= li++))
{
- if (remaining_tables & added_key_field->val->used_tables())
+ if (excluded_tables & added_key_field->val->used_tables())
continue;
if (inj_cond_list->push_back(added_key_field->cond, thd->mem_root))
return true;
@@ -1088,7 +1091,7 @@ bool JOIN::inject_best_splitting_cond(table_map remaining_tables)
if (inj_cond)
inj_cond->fix_fields(thd,0);
- if (inject_cond_into_where(inj_cond))
+ if (inject_cond_into_where(inj_cond->copy_andor_structure(thd)))
return true;
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT_INJECTED;
@@ -1165,8 +1168,6 @@ bool JOIN_TAB::fix_splitting(SplM_plan_info *spl_plan,
memcpy((char *) md_join->best_positions,
(char *) spl_plan->best_positions,
sizeof(POSITION) * md_join->table_count);
- if (md_join->inject_best_splitting_cond(remaining_tables))
- return true;
/*
This is called for a proper work of JOIN::get_best_combination()
called for the join that materializes T
@@ -1210,7 +1211,8 @@ bool JOIN::fix_all_splittings_in_plan()
if (tab->table->is_splittable())
{
SplM_plan_info *spl_plan= cur_pos->spl_plan;
- if (tab->fix_splitting(spl_plan, all_tables & ~prev_tables,
+ if (tab->fix_splitting(spl_plan,
+ all_tables & ~prev_tables,
tablenr < const_tables ))
return true;
}
@@ -1218,3 +1220,44 @@ bool JOIN::fix_all_splittings_in_plan()
}
return false;
}
+
+
+/**
+ @brief
+ Inject splitting conditions into WHERE of split derived
+
+ @details
+ The function calls JOIN_TAB::inject_best_splitting_cond() for each
+ materialized derived table T used in this join for which the split
+ optimization has been chosen by the optimizer. It is done in order to
+ inject equalities pushed into the where clause of the specification
+ of T that would be helpful to employ the splitting technique.
+
+ @retval
+ false on success
+ true on failure
+*/
+
+bool JOIN::inject_splitting_cond_for_all_tables_with_split_opt()
+{
+ table_map prev_tables= 0;
+ table_map all_tables= (table_map(1) << table_count) - 1;
+ for (uint tablenr= 0; tablenr < table_count; tablenr++)
+ {
+ POSITION *cur_pos= &best_positions[tablenr];
+ JOIN_TAB *tab= cur_pos->table;
+ prev_tables|= tab->table->map;
+ if (!(tab->table->is_splittable() && cur_pos->spl_plan))
+ continue;
+ SplM_opt_info *spl_opt_info= tab->table->spl_opt_info;
+ JOIN *join= spl_opt_info->join;
+ /*
+ Currently the equalities referencing columns of SJM tables with
+ look-up access cannot be pushed into materialized derived.
+ */
+ if (join->inject_best_splitting_cond((all_tables & ~prev_tables) |
+ sjm_lookup_tables))
+ return true;
+ }
+ return false;
+}
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index e0c1d6dac4a..bff0f3d7ef6 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1600,6 +1600,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
{
SELECT_LEX *parent_lex= parent_join->select_lex;
TABLE_LIST *emb_tbl_nest= NULL;
+ TABLE_LIST *orig_tl;
List<TABLE_LIST> *emb_join_list= &parent_lex->top_join_list;
THD *thd= parent_join->thd;
DBUG_ENTER("convert_subq_to_sj");
@@ -1761,17 +1762,17 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
because view's tables are inserted after the view)
*/
- for (tl= (TABLE_LIST*)(parent_lex->table_list.first); tl->next_local; tl= tl->next_local)
+ for (orig_tl= (TABLE_LIST*)(parent_lex->table_list.first);
+ orig_tl->next_local;
+ orig_tl= orig_tl->next_local)
{}
- tl->next_local= subq_lex->join->tables_list;
+ orig_tl->next_local= subq_lex->join->tables_list;
/* A theory: no need to re-connect the next_global chain */
/* 3. Remove the original subquery predicate from the WHERE/ON */
- // The subqueries were replaced for Item_int(1) earlier
- subq_pred->reset_strategy(SUBS_SEMI_JOIN); // for subsequent executions
/*TODO: also reset the 'm_with_subquery' there. */
/* n. Adjust the parent_join->table_count counter */
@@ -1804,12 +1805,14 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
Add the subquery-induced equalities too.
*/
SELECT_LEX *save_lex= thd->lex->current_select;
+ table_map subq_pred_used_tables;
+
thd->lex->current_select=subq_lex;
if (subq_pred->left_expr->fix_fields_if_needed(thd, &subq_pred->left_expr))
- DBUG_RETURN(TRUE);
+ goto restore_tl_and_exit;
thd->lex->current_select=save_lex;
- table_map subq_pred_used_tables= subq_pred->used_tables();
+ subq_pred_used_tables= subq_pred->used_tables();
sj_nest->nested_join->sj_corr_tables= subq_pred_used_tables;
sj_nest->nested_join->sj_depends_on= subq_pred_used_tables |
subq_pred->left_expr->used_tables();
@@ -1852,7 +1855,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
new (thd->mem_root) Item_func_eq(thd, subq_pred->left_expr_orig,
subq_lex->ref_pointer_array[0]);
if (!item_eq)
- DBUG_RETURN(TRUE);
+ goto restore_tl_and_exit;
if (subq_pred->left_expr_orig != subq_pred->left_expr)
thd->change_item_tree(item_eq->arguments(), subq_pred->left_expr);
item_eq->in_equality_no= 0;
@@ -1873,7 +1876,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
Item_func_eq(thd, subq_pred->left_expr_orig->element_index(i),
subq_lex->ref_pointer_array[i]);
if (!item_eq)
- DBUG_RETURN(TRUE);
+ goto restore_tl_and_exit;
DBUG_ASSERT(subq_pred->left_expr->element_index(i)->is_fixed());
if (subq_pred->left_expr_orig->element_index(i) !=
subq_pred->left_expr->element_index(i))
@@ -1892,13 +1895,13 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
Item_row *row= new (thd->mem_root) Item_row(thd, subq_lex->pre_fix);
/* fix fields on subquery was call so they should be the same */
if (!row)
- DBUG_RETURN(TRUE);
+ goto restore_tl_and_exit;
DBUG_ASSERT(subq_pred->left_expr->cols() == row->cols());
nested_join->sj_outer_expr_list.push_back(&subq_pred->left_expr);
Item_func_eq *item_eq=
new (thd->mem_root) Item_func_eq(thd, subq_pred->left_expr_orig, row);
if (!item_eq)
- DBUG_RETURN(TRUE);
+ goto restore_tl_and_exit;
for (uint i= 0; i < row->cols(); i++)
{
if (row->element_index(i) != subq_lex->ref_pointer_array[i])
@@ -1917,9 +1920,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
we have in here).
*/
if (sj_nest->sj_on_expr->fix_fields_if_needed(thd, &sj_nest->sj_on_expr))
- {
- DBUG_RETURN(TRUE);
- }
+ goto restore_tl_and_exit;
/*
Walk through sj nest's WHERE and ON expressions and call
@@ -1944,9 +1945,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
emb_tbl_nest->on_expr->top_level_item();
if (emb_tbl_nest->on_expr->fix_fields_if_needed(thd,
&emb_tbl_nest->on_expr))
- {
- DBUG_RETURN(TRUE);
- }
+ goto restore_tl_and_exit;
}
else
{
@@ -1960,9 +1959,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
save_lex= thd->lex->current_select;
thd->lex->current_select=parent_join->select_lex;
if (parent_join->conds->fix_fields_if_needed(thd, &parent_join->conds))
- {
- DBUG_RETURN(1);
- }
+ goto restore_tl_and_exit;
+
thd->lex->current_select=save_lex;
parent_join->select_lex->where= parent_join->conds;
}
@@ -1975,9 +1973,16 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
parent_lex->ftfunc_list->push_front(ifm, thd->mem_root);
}
+ // The subqueries were replaced for Item_int(1) earlier
+ subq_pred->reset_strategy(SUBS_SEMI_JOIN); // for subsequent executions
+
parent_lex->have_merged_subqueries= TRUE;
/* Fatal error may have been set to by fix_after_pullout() */
DBUG_RETURN(thd->is_fatal_error);
+
+restore_tl_and_exit:
+ orig_tl->next_local= NULL;
+ DBUG_RETURN(TRUE);
}
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index a8459438be7..edcdd6d2b37 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -40,7 +40,7 @@
#include "ha_partition.h"
-partition_info *partition_info::get_clone(THD *thd)
+partition_info *partition_info::get_clone(THD *thd, bool empty_data_and_index_file)
{
MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("partition_info::get_clone");
@@ -60,21 +60,22 @@ partition_info *partition_info::get_clone(THD *thd)
{
List_iterator<partition_element> subpart_it(part->subpartitions);
partition_element *subpart;
- partition_element *part_clone= new (mem_root) partition_element();
+ partition_element *part_clone= new (mem_root) partition_element(*part);
if (!part_clone)
DBUG_RETURN(NULL);
-
- *part_clone= *part;
part_clone->subpartitions.empty();
while ((subpart= (subpart_it++)))
{
- partition_element *subpart_clone= new (mem_root) partition_element();
+ partition_element *subpart_clone= new (mem_root) partition_element(*subpart);
if (!subpart_clone)
DBUG_RETURN(NULL);
-
- *subpart_clone= *subpart;
+ if (empty_data_and_index_file)
+ subpart_clone->data_file_name= subpart_clone->index_file_name= NULL;
part_clone->subpartitions.push_back(subpart_clone, mem_root);
}
+
+ if (empty_data_and_index_file)
+ part_clone->data_file_name= part_clone->index_file_name= NULL;
clone->partitions.push_back(part_clone, mem_root);
part_clone->list_val_list.empty();
List_iterator<part_elem_value> list_val_it(part->list_val_list);
@@ -832,8 +833,13 @@ bool partition_info::has_unique_name(partition_element *element)
DBUG_RETURN(TRUE);
}
-void partition_info::vers_set_hist_part(THD *thd)
+int partition_info::vers_set_hist_part(THD *thd)
{
+ if (table->pos_in_table_list &&
+ table->pos_in_table_list->partition_names)
+ {
+ return HA_ERR_PARTITION_LIST;
+ }
if (vers_info->limit)
{
ha_partition *hp= (ha_partition*)(table->file);
@@ -841,9 +847,11 @@ void partition_info::vers_set_hist_part(THD *thd)
List_iterator<partition_element> it(partitions);
while (next != vers_info->hist_part)
next= it++;
+ DBUG_ASSERT(bitmap_is_set(&read_partitions, next->id));
ha_rows records= hp->part_records(next);
while ((next= it++) != vers_info->now_part)
{
+ DBUG_ASSERT(bitmap_is_set(&read_partitions, next->id));
ha_rows next_records= hp->part_records(next);
if (next_records == 0)
break;
@@ -856,13 +864,13 @@ void partition_info::vers_set_hist_part(THD *thd)
goto warn;
vers_info->hist_part= next;
}
- return;
+ return 0;
}
if (vers_info->interval.is_set())
{
if (vers_info->hist_part->range_value > thd->query_start())
- return;
+ return 0;
partition_element *next= NULL;
List_iterator<partition_element> it(partitions);
@@ -873,14 +881,15 @@ void partition_info::vers_set_hist_part(THD *thd)
{
vers_info->hist_part= next;
if (next->range_value > thd->query_start())
- return;
+ return 0;
}
}
- return;
+ return 0;
warn:
my_error(WARN_VERS_PART_FULL, MYF(ME_WARNING|ME_ERROR_LOG),
table->s->db.str, table->s->table_name.str,
vers_info->hist_part->partition_name);
+ return 0;
}
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 00ef815ce09..9fb20268738 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -327,7 +327,7 @@ public:
}
~partition_info() {}
- partition_info *get_clone(THD *thd);
+ partition_info *get_clone(THD *thd, bool empty_data_and_index_file= FALSE);
bool set_named_partition_bitmap(const char *part_name, size_t length);
bool set_partition_bitmaps(List<String> *partition_names);
bool set_partition_bitmaps_from_table(TABLE_LIST *table_list);
@@ -421,7 +421,7 @@ public:
vers_info->limit= limit;
return !limit;
}
- void vers_set_hist_part(THD *thd);
+ int vers_set_hist_part(THD *thd);
bool vers_setup_expression(THD *thd, uint32 alter_add= 0); /* Stage 1. */
partition_element *get_partition(uint part_id)
{
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 1eb7a096ca9..5ec887e13d7 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -467,8 +467,12 @@ bool net_send_error_packet(THD *thd, uint sql_errno, const char *err,
coming from server to have seq_no > 0, due to missing awareness
of "out-of-band" operations. Make these clients happy.
*/
- if (!net->pkt_nr)
- net->pkt_nr= 1;
+ if (!net->pkt_nr &&
+ (sql_errno == ER_CONNECTION_KILLED || sql_errno == ER_SERVER_SHUTDOWN ||
+ sql_errno == ER_QUERY_INTERRUPTED))
+ {
+ net->pkt_nr= 1;
+ }
ret= net_write_command(net,(uchar) 255, (uchar*) "", 0, (uchar*) buff,
length);
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 1c6a1326538..c146bab1243 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6641,8 +6641,8 @@ ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
ER_TABLE_IN_FK_CHECK
eng "Table is being used in foreign key check"
-ER_UNUSED_1
- eng "You should never see it"
+ER_VERS_NOT_ALLOWED
+ eng "Not allowed for system-versioned table %`s.%`s"
ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
eng "INSERT into autoincrement field which is not the first part in the composed primary key is unsafe"
diff --git a/sql/slave.cc b/sql/slave.cc
index 68ddc611c03..edea312c5ea 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4388,6 +4388,15 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
#ifdef WITH_WSREP
wsrep_after_statement(thd);
#endif /* WITH_WSREP */
+ DBUG_EXECUTE_IF(
+ "pause_sql_thread_on_fde",
+ if (ev && typ == FORMAT_DESCRIPTION_EVENT) {
+ DBUG_ASSERT(!debug_sync_set_action(
+ thd,
+ STRING_WITH_LEN(
+ "now SIGNAL paused_on_fde WAIT_FOR sql_thread_continue")));
+ });
+
DBUG_RETURN(exec_res);
}
mysql_mutex_unlock(&rli->data_lock);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 5132b0e2e85..be47a48fec2 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -4537,6 +4537,7 @@ restart:
wsrep_thd_is_local(thd) &&
!is_stat_table(&(*start)->db, &(*start)->alias) &&
thd->get_command() != COM_STMT_PREPARE &&
+ !thd->stmt_arena->is_stmt_prepare() &&
((thd->lex->sql_command == SQLCOM_INSERT ||
thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
thd->lex->sql_command == SQLCOM_REPLACE ||
@@ -6443,8 +6444,9 @@ find_field_in_tables(THD *thd, Item_ident *item,
TRUE, &(item->cached_field_index));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Check if there are sufficient access rights to the found field. */
- if (found && check_privileges &&
- check_column_grant_in_table_ref(thd, table_ref, name, length, found))
+ if (found && check_privileges && !is_temporary_table(table_ref) &&
+ check_column_grant_in_table_ref(thd, table_ref, name, length,
+ found))
found= WRONG_GRANT;
#endif
}
@@ -6907,7 +6909,6 @@ set_new_item_local_context(THD *thd, Item_ident *item, TABLE_LIST *table_ref)
if (!(context= new (thd->mem_root) Name_resolution_context))
return TRUE;
context->init();
- context->select_lex= table_ref->select_lex;
context->first_name_resolution_table=
context->last_name_resolution_table= table_ref;
item->context= context;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index da9835c188a..871b3733693 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -5183,18 +5183,19 @@ void LEX::free_arena_for_set_stmt()
DBUG_VOID_RETURN;
}
-void LEX::restore_set_statement_var()
+bool LEX::restore_set_statement_var()
{
+ bool err= false;
DBUG_ENTER("LEX::restore_set_statement_var");
if (!old_var_list.is_empty())
{
DBUG_PRINT("info", ("vars: %d", old_var_list.elements));
- sql_set_variables(thd, &old_var_list, false);
+ err= sql_set_variables(thd, &old_var_list, false);
old_var_list.empty();
free_arena_for_set_stmt();
}
DBUG_ASSERT(!is_arena_for_set_stmt());
- DBUG_VOID_RETURN;
+ DBUG_RETURN(err);
}
unit_common_op st_select_lex_unit::common_op()
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index eb21419c7af..a4ded8deb34 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3725,7 +3725,7 @@ public:
int print_explain(select_result_sink *output, uint8 explain_flags,
bool is_analyze, bool *printed_anything);
- void restore_set_statement_var();
+ bool restore_set_statement_var();
void init_last_field(Column_definition *field, const LEX_CSTRING *name,
const CHARSET_INFO *cs);
diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc
index 45f81da80c9..fb7fa26f245 100644
--- a/sql/sql_locale.cc
+++ b/sql/sql_locale.cc
@@ -563,8 +563,8 @@ MY_LOCALE my_locale_es_ES
10,
9,
',', /* decimal point es_ES */
- '\0', /* thousands_sep es_ES */
- "\x80\x80", /* grouping es_ES */
+ '.', /* thousands_sep es_ES */
+ "\x03\x03", /* grouping es_ES */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_ES *****/
@@ -2649,8 +2649,8 @@ MY_LOCALE my_locale_es_BO
10,
9,
',', /* decimal point es_BO */
- '\0', /* thousands_sep es_BO */
- "\x80\x80", /* grouping es_BO */
+ '.', /* thousands_sep es_BO */
+ "\x03\x03", /* grouping es_BO */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_BO *****/
@@ -2669,8 +2669,8 @@ MY_LOCALE my_locale_es_CL
10,
9,
',', /* decimal point es_CL */
- '\0', /* thousands_sep es_CL */
- "\x80\x80", /* grouping es_CL */
+ '.', /* thousands_sep es_CL */
+ "\x03\x03", /* grouping es_CL */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_CL *****/
@@ -2689,8 +2689,8 @@ MY_LOCALE my_locale_es_CO
10,
9,
',', /* decimal point es_CO */
- '\0', /* thousands_sep es_CO */
- "\x80\x80", /* grouping es_CO */
+ '.', /* thousands_sep es_CO */
+ "\x03\x03", /* grouping es_CO */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_CO *****/
@@ -2708,9 +2708,9 @@ MY_LOCALE my_locale_es_CR
&my_locale_typelib_ab_day_names_es_ES,
10,
9,
- '.', /* decimal point es_CR */
- '\0', /* thousands_sep es_CR */
- "\x80\x80", /* grouping es_CR */
+ ',', /* decimal point es_CR */
+ ' ', /* thousands_sep es_CR */
+ "\x03\x03", /* grouping es_CR */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_CR *****/
@@ -2729,8 +2729,8 @@ MY_LOCALE my_locale_es_DO
10,
9,
'.', /* decimal point es_DO */
- '\0', /* thousands_sep es_DO */
- "\x80\x80", /* grouping es_DO */
+ ',', /* thousands_sep es_DO */
+ "\x03\x03", /* grouping es_DO */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_DO *****/
@@ -2749,8 +2749,8 @@ MY_LOCALE my_locale_es_EC
10,
9,
',', /* decimal point es_EC */
- '\0', /* thousands_sep es_EC */
- "\x80\x80", /* grouping es_EC */
+ '.', /* thousands_sep es_EC */
+ "\x03\x03", /* grouping es_EC */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_EC *****/
@@ -2769,8 +2769,8 @@ MY_LOCALE my_locale_es_GT
10,
9,
'.', /* decimal point es_GT */
- '\0', /* thousands_sep es_GT */
- "\x80\x80", /* grouping es_GT */
+ ',', /* thousands_sep es_GT */
+ "\x03\x03", /* grouping es_GT */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_GT *****/
@@ -2789,8 +2789,8 @@ MY_LOCALE my_locale_es_HN
10,
9,
'.', /* decimal point es_HN */
- '\0', /* thousands_sep es_HN */
- "\x80\x80", /* grouping es_HN */
+ ',', /* thousands_sep es_HN */
+ "\x03\x03", /* grouping es_HN */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_HN *****/
@@ -2809,8 +2809,8 @@ MY_LOCALE my_locale_es_MX
10,
9,
'.', /* decimal point es_MX */
- '\0', /* thousands_sep es_MX */
- "\x80\x80", /* grouping es_MX */
+ ',', /* thousands_sep es_MX */
+ "\x03\x03", /* grouping es_MX */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_MX *****/
@@ -2829,8 +2829,8 @@ MY_LOCALE my_locale_es_NI
10,
9,
'.', /* decimal point es_NI */
- '\0', /* thousands_sep es_NI */
- "\x80\x80", /* grouping es_NI */
+ ',', /* thousands_sep es_NI */
+ "\x03\x03", /* grouping es_NI */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_NI *****/
@@ -2849,8 +2849,8 @@ MY_LOCALE my_locale_es_PA
10,
9,
'.', /* decimal point es_PA */
- '\0', /* thousands_sep es_PA */
- "\x80\x80", /* grouping es_PA */
+ ',', /* thousands_sep es_PA */
+ "\x03\x03", /* grouping es_PA */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_PA *****/
@@ -2869,8 +2869,8 @@ MY_LOCALE my_locale_es_PE
10,
9,
'.', /* decimal point es_PE */
- '\0', /* thousands_sep es_PE */
- "\x80\x80", /* grouping es_PE */
+ ',', /* thousands_sep es_PE */
+ "\x03\x03", /* grouping es_PE */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_PE *****/
@@ -2889,8 +2889,8 @@ MY_LOCALE my_locale_es_PR
10,
9,
'.', /* decimal point es_PR */
- '\0', /* thousands_sep es_PR */
- "\x80\x80", /* grouping es_PR */
+ ',', /* thousands_sep es_PR */
+ "\x03\x03", /* grouping es_PR */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_PR *****/
@@ -2909,8 +2909,8 @@ MY_LOCALE my_locale_es_PY
10,
9,
',', /* decimal point es_PY */
- '\0', /* thousands_sep es_PY */
- "\x80\x80", /* grouping es_PY */
+ '.', /* thousands_sep es_PY */
+ "\x03\x03", /* grouping es_PY */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_PY *****/
@@ -2929,8 +2929,8 @@ MY_LOCALE my_locale_es_SV
10,
9,
'.', /* decimal point es_SV */
- '\0', /* thousands_sep es_SV */
- "\x80\x80", /* grouping es_SV */
+ ',', /* thousands_sep es_SV */
+ "\x03\x03", /* grouping es_SV */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_SV *****/
@@ -2969,8 +2969,8 @@ MY_LOCALE my_locale_es_UY
10,
9,
',', /* decimal point es_UY */
- '\0', /* thousands_sep es_UY */
- "\x80\x80", /* grouping es_UY */
+ '.', /* thousands_sep es_UY */
+ "\x03\x03", /* grouping es_UY */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_UY *****/
@@ -2989,8 +2989,8 @@ MY_LOCALE my_locale_es_VE
10,
9,
',', /* decimal point es_VE */
- '\0', /* thousands_sep es_VE */
- "\x80\x80", /* grouping es_VE */
+ '.', /* thousands_sep es_VE */
+ "\x03\x03", /* grouping es_VE */
&global_errmsgs[es_ES]
);
/***** LOCALE END es_VE *****/
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 69702813f08..0d7b34327fb 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -214,7 +214,7 @@ static struct
/* support for Services */
-#include "sql_plugin_services.ic"
+#include "sql_plugin_services.inl"
/*
A mutex LOCK_plugin must be acquired before accessing the
diff --git a/sql/sql_plugin_services.ic b/sql/sql_plugin_services.inl
index 60ba38eae61..60ba38eae61 100644
--- a/sql/sql_plugin_services.ic
+++ b/sql/sql_plugin_services.inl
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 980e37a7686..49b342d660d 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3046,7 +3046,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
}
for (; sl; sl= sl->next_select_in_list())
{
- sl->parent_lex->in_sum_func= NULL;
if (sl->changed_elements & TOUCHED_SEL_COND)
{
/* remove option which was put by mysql_explain_union() */
@@ -3181,6 +3180,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
lex->result->set_thd(thd);
}
lex->allow_sum_func.clear_all();
+ lex->in_sum_func= NULL;
DBUG_VOID_RETURN;
}
@@ -4289,7 +4289,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
Restore original values of variables modified on handling
SET STATEMENT clause.
*/
- thd->lex->restore_set_statement_var();
+ error|= thd->lex->restore_set_statement_var();
/* The order is important */
lex->unit.cleanup();
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9311eb4fa18..4b92c4cb7a6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3094,6 +3094,14 @@ setup_subq_exit:
}
if (make_aggr_tables_info())
DBUG_RETURN(1);
+
+ /*
+ It could be that we've only done optimization stage 1 for
+ some of the derived tables, and never did stage 2.
+ Do it now, otherwise Explain data structure will not be complete.
+ */
+ if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE))
+ DBUG_RETURN(1);
}
/*
Even with zero matching rows, subqueries in the HAVING clause may
@@ -10399,6 +10407,9 @@ bool JOIN::get_best_combination()
hash_join= FALSE;
fix_semijoin_strategies_for_picked_join_order(this);
+
+ if (inject_splitting_cond_for_all_tables_with_split_opt())
+ DBUG_RETURN(TRUE);
JOIN_TAB_RANGE *root_range;
if (!(root_range= new (thd->mem_root) JOIN_TAB_RANGE))
@@ -14434,8 +14445,6 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
DBUG_RETURN(0);
}
- join->join_free();
-
if (send_row)
{
/*
@@ -14482,6 +14491,14 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
if (likely(!send_error))
result->send_eof(); // Should be safe
}
+ /*
+ JOIN::join_free() must be called after the virtual method
+ select::send_result_set_metadata() returned control since
+ implementation of this method could use data strutcures
+ that are released by the method JOIN::join_free().
+ */
+ join->join_free();
+
DBUG_RETURN(0);
}
@@ -18589,8 +18606,15 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
The test for item->marker == 4 is ensure we don't create a group-by
key over a bit field as heap tables can't handle that.
*/
- Field *new_field= (param->schema_table) ?
- item->create_field_for_schema(thd, table) :
+ Field *new_field;
+ if (param->schema_table)
+ {
+ if ((new_field= item->create_field_for_schema(thd, table)))
+ new_field->flags|= NO_DEFAULT_VALUE_FLAG;
+ }
+ else
+ {
+ new_field=
create_tmp_field(table, item, &copy_func,
tmp_from_field, &default_field[fieldnr],
group != 0,
@@ -18605,7 +18629,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
*/
item->marker == 4 || param->bit_fields_as_long,
force_copy_fields);
- if (!new_field)
+ }
+ if (unlikely(!new_field))
{
if (unlikely(thd->is_fatal_error))
goto err; // Got OOM
@@ -20847,11 +20872,8 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
*/
if (shortcut_for_distinct && found_records != join->found_records)
DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
- }
- else
- {
- join->thd->get_stmt_da()->inc_current_row_for_warning();
- join_tab->read_record.unlock_row(join_tab);
+
+ DBUG_RETURN(NESTED_LOOP_OK);
}
}
else
@@ -20861,9 +20883,11 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
with the beginning coinciding with the current partial join.
*/
join->join_examined_rows++;
- join->thd->get_stmt_da()->inc_current_row_for_warning();
- join_tab->read_record.unlock_row(join_tab);
}
+
+ join->thd->get_stmt_da()->inc_current_row_for_warning();
+ join_tab->read_record.unlock_row(join_tab);
+
DBUG_RETURN(NESTED_LOOP_OK);
}
@@ -22603,21 +22627,6 @@ make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
cond->marker=3; // Checked when read
return (COND*) 0;
}
- /*
- If cond is an equality injected for split optimization then
- a. when retain_ref_cond == false : cond is removed unconditionally
- (cond that supports ref access is removed by the preceding code)
- b. when retain_ref_cond == true : cond is removed if it does not
- support ref access
- */
- if (left_item->type() == Item::FIELD_ITEM &&
- is_eq_cond_injected_for_split_opt((Item_func_eq *) cond) &&
- (!retain_ref_cond ||
- !test_if_ref(root_cond, (Item_field*) left_item,right_item)))
- {
- cond->marker=3;
- return (COND*) 0;
- }
}
cond->marker=2;
cond->set_join_tab_idx(join_tab_idx_arg);
@@ -28981,6 +28990,12 @@ AGGR_OP::end_send()
table->reginfo.lock_type= TL_UNLOCK;
bool in_first_read= true;
+
+ /*
+ Reset the counter before copying rows from internal temporary table to
+ INSERT table.
+ */
+ join_tab->join->thd->get_stmt_da()->reset_current_row_for_warning();
while (rc == NESTED_LOOP_OK)
{
int error;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 8d65a6183a0..28bf33997a0 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1797,6 +1797,7 @@ public:
void add_keyuses_for_splitting();
bool inject_best_splitting_cond(table_map remaining_tables);
bool fix_all_splittings_in_plan();
+ bool inject_splitting_cond_for_all_tables_with_split_opt();
bool transform_in_predicates_into_in_subq(THD *thd);
private:
diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc
index 8d1a67eab85..03f2f1b117f 100644
--- a/sql/sql_sequence.cc
+++ b/sql/sql_sequence.cc
@@ -365,9 +365,14 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *org_table_list)
seq->reserved_until= seq->start;
error= seq->write_initial_sequence(table);
-
- if (trans_commit_stmt(thd))
- error= 1;
+ {
+ uint save_unsafe_rollback_flags=
+ thd->transaction.stmt.m_unsafe_rollback_flags;
+ if (trans_commit_stmt(thd))
+ error= 1;
+ thd->transaction.stmt.m_unsafe_rollback_flags=
+ save_unsafe_rollback_flags;
+ }
if (trans_commit_implicit(thd))
error= 1;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index cf3719b0cd0..e2c1940311c 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -9470,7 +9470,7 @@ ST_FIELD_INFO stat_fields_info[]=
{"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
OPEN_FRM_ONLY},
- {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
+ {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FULL_TABLE},
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1,
"Cardinality", OPEN_FULL_TABLE},
{"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9a51ce49248..53adea74613 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2010, 2021, MariaDB
+ Copyright (c) 2010, 2022, 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
@@ -5786,8 +5786,15 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
#ifdef WITH_PARTITION_STORAGE_ENGINE
/* Partition info is not handled by mysql_prepare_alter_table() call. */
if (src_table->table->part_info)
- thd->work_part_info= src_table->table->part_info->get_clone(thd);
-#endif
+ {
+ /*
+ The CREATE TABLE LIKE should not inherit the DATA DIRECTORY
+ and INDEX DIRECTORY from the base table.
+ So that TRUE argument for the get_clone.
+ */
+ thd->work_part_info= src_table->table->part_info->get_clone(thd, TRUE);
+ }
+#endif /*WITH_PARTITION_STORAGE_ENGINE*/
/*
Adjust description of source table before using it for creation of
@@ -8304,9 +8311,14 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
def->invisible= INVISIBLE_SYSTEM;
alter_info->flags|= ALTER_CHANGE_COLUMN;
if (field->flags & VERS_ROW_START)
- create_info->vers_info.as_row.start= def->field_name= Vers_parse_info::default_start;
+ create_info->vers_info.period.start=
+ create_info->vers_info.as_row.start=
+ def->field_name= Vers_parse_info::default_start;
+
else
- create_info->vers_info.as_row.end= def->field_name= Vers_parse_info::default_end;
+ create_info->vers_info.period.end=
+ create_info->vers_info.as_row.end=
+ def->field_name= Vers_parse_info::default_end;
new_create_list.push_back(def, thd->mem_root);
dropped_sys_vers_fields|= field->flags;
drop_it.remove();
@@ -11618,20 +11630,28 @@ bool Sql_cmd_create_table_like::execute(THD *thd)
tables, like mysql replication does. Also check if the requested
engine is allowed/supported.
*/
- if (WSREP(thd) &&
- !check_engine(thd, create_table->db.str, create_table->table_name.str,
- &create_info) &&
- (!thd->is_current_stmt_binlog_format_row() ||
- !create_info.tmp_table()))
- {
+ if (WSREP(thd))
+ {
+ handlerton *orig_ht= create_info.db_type;
+ if (!check_engine(thd, create_table->db.str,
+ create_table->table_name.str,
+ &create_info) &&
+ (!thd->is_current_stmt_binlog_format_row() ||
+ !create_info.tmp_table()))
+ {
#ifdef WITH_WSREP
- WSREP_TO_ISOLATION_BEGIN_ALTER(create_table->db.str, create_table->table_name.str,
- first_table, &alter_info, NULL)
- {
- WSREP_WARN("CREATE TABLE isolation failure");
- DBUG_RETURN(true);
- }
+ WSREP_TO_ISOLATION_BEGIN_ALTER(create_table->db.str, create_table->table_name.str,
+ first_table, &alter_info, NULL)
+ {
+ WSREP_WARN("CREATE TABLE isolation failure");
+ DBUG_RETURN(true);
+ }
#endif /* WITH_WSREP */
+ }
+ // check_engine will set db_type to NULL if e.g. TEMPORARY is
+ // not supported by the storage engine, this case is checked
+ // again in mysql_create_table
+ create_info.db_type= orig_ht;
}
/* Regular CREATE TABLE */
res= mysql_create_table(thd, create_table, &create_info, &alter_info);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 9091de619e6..81ed160560e 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -407,8 +407,18 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
bool res= FALSE;
DBUG_ENTER("mysql_create_view");
- /* This is ensured in the parser. */
- DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
+ /*
+ This is ensured in the parser.
+ NOTE: Originally, the assert below contained the extra condition
+ && !lex->result
+ but in this form the assert is failed in case CREATE VIEW run under
+ cursor (the case when the byte 'flags' in the COM_STMT_EXECUTE packet has
+ the flag CURSOR_TYPE_READ_ONLY set). For the cursor use case
+ thd->lex->result is assigned a pointer to the class Select_materialize
+ inside the function mysql_open_cursor() just before handling of a statement
+ will be started and the function mysql_create_view() called.
+ */
+ DBUG_ASSERT(!lex->proc_list.first &&
!lex->param_list.elements);
/*
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 31f29042388..6bbdcbf86cb 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -34,7 +34,7 @@
#include "sql_plugin.h"
#include "sql_priv.h"
#include "sql_class.h" // set_var.h: THD
-#include "sys_vars.ic"
+#include "sys_vars.inl"
#include "my_sys.h"
#include "events.h"
diff --git a/sql/sys_vars.ic b/sql/sys_vars.inl
index 84d1cd6b331..84d1cd6b331 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.inl
diff --git a/sql/table.cc b/sql/table.cc
index 4df5af7a6c3..ae4c7b2ff66 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8627,14 +8627,18 @@ void TABLE::vers_update_fields()
return;
}
- if (versioned(VERS_TIMESTAMP) &&
- vers_start_field()->store_timestamp(in_use->query_start(),
- in_use->query_start_sec_part()))
+ if (versioned(VERS_TIMESTAMP))
{
- DBUG_ASSERT(0);
+ if (vers_start_field()->store_timestamp(in_use->query_start(),
+ in_use->query_start_sec_part()))
+ {
+ DBUG_ASSERT(0);
+ }
+ vers_start_field()->set_has_explicit_value();
}
vers_end_field()->set_max();
+ vers_end_field()->set_has_explicit_value();
bitmap_set_bit(read_set, vers_end_field()->field_index);
file->column_bitmaps_signal();
if (vfield)
@@ -8647,6 +8651,7 @@ void TABLE::vers_update_end()
if (vers_end_field()->store_timestamp(in_use->query_start(),
in_use->query_start_sec_part()))
DBUG_ASSERT(0);
+ vers_end_field()->set_has_explicit_value();
}
/**
@@ -8956,6 +8961,24 @@ void TABLE_LIST::wrap_into_nested_join(List<TABLE_LIST> &join_list)
/**
+ Check whether optimization has been performed and a derived table either
+ been merged to upper select level or materialized.
+
+ @param table a TABLE_LIST object containing a derived table
+
+ @return true in case the derived table has been merged to surrounding select,
+ false otherwise
+*/
+
+static inline bool derived_table_optimization_done(TABLE_LIST *table)
+{
+ return table->derived &&
+ (table->derived->is_excluded() ||
+ table->is_materialized_derived());
+}
+
+
+/**
@brief
Initialize this derived table/view
@@ -9005,13 +9028,15 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view)
}
}
- if (init_view && !view)
+ if (init_view && !view &&
+ !derived_table_optimization_done(this))
{
/* This is all what we can do for a derived table for now. */
set_derived();
}
- if (!is_view())
+ if (!is_view() &&
+ !derived_table_optimization_done(this))
{
/* A subquery might be forced to be materialized due to a side-effect. */
if (!is_materialized_derived() && first_select->is_mergeable() &&
diff --git a/sql/table.h b/sql/table.h
index 32393396ae7..832b204cba5 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1721,7 +1721,9 @@ public:
bool vers_check_update(List<Item> &items);
int delete_row();
+ /* Used in majority of DML (called from fill_record()) */
void vers_update_fields();
+ /* Used in DELETE, DUP REPLACE and insert history row */
void vers_update_end();
void find_constraint_correlated_indexes();
void clone_handler_for_update();
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 98e40205681..80035a5b906 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -2628,9 +2628,9 @@ static struct my_option my_long_options[] =
{"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
- {"leap", 'l', "Print the leap second information from the given time zone file. By convention, when --leap is used the next argument is the timezonefile",
+ {"leap", 'l', "Print the leap second information from the given time zone file. By convention, when --leap is used the next argument is the timezonefile.",
&opt_leap, &opt_leap, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"verbose", 'v', "Write non critical warnings",
+ {"verbose", 'v', "Write non critical warnings.",
&opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -2640,6 +2640,15 @@ static struct my_option my_long_options[] =
};
+static char **default_argv;
+
+static void free_allocated_data()
+{
+ free_defaults(default_argv);
+ my_end(0);
+}
+
+
C_MODE_START
static my_bool get_one_option(int optid, const struct my_option *,
char *argument);
@@ -2651,11 +2660,21 @@ static void print_version(void)
MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
}
+static const char *default_timezone_dir= "/usr/share/zoneinfo/";
+
+
static void print_usage(void)
{
- fprintf(stderr, "Usage:\n");
- fprintf(stderr, " %s [options] timezonedir\n", my_progname);
- fprintf(stderr, " %s [options] timezonefile timezonename\n", my_progname);
+ fprintf(stdout, "Create SQL commands for loading system timezeone data for "
+ "MariaDB\n\n");
+ fprintf(stdout, "Usage:\n");
+ fprintf(stdout, " %s [options] timezonedir\n", my_progname);
+ fprintf(stdout, "or\n");
+ fprintf(stdout, " %s [options] timezonefile timezonename\n", my_progname);
+
+ fprintf(stdout, "\nA typical place for the system timezone directory is "
+ "\"%s\"\n", default_timezone_dir);
+
print_defaults("my",load_default_groups);
puts("");
my_print_help(my_long_options);
@@ -2676,9 +2695,11 @@ get_one_option(int optid, const struct my_option *opt, char *argument)
print_version();
puts("");
print_usage();
+ free_allocated_data();
exit(0);
case 'V':
print_version();
+ free_allocated_data();
exit(0);
}
return 0;
@@ -2700,7 +2721,6 @@ static const char *trunc_tables_const=
int
main(int argc, char **argv)
{
- char **default_argv;
const char *trunc_tables;
MY_INIT(argv[0]);
@@ -2713,7 +2733,7 @@ main(int argc, char **argv)
if ((argc != 1 && argc != 2) || (opt_leap && argc != 1))
{
print_usage();
- free_defaults(default_argv);
+ free_allocated_data();
return 1;
}
@@ -2808,7 +2828,7 @@ main(int argc, char **argv)
"END IF|\n"
"\\d ;\n");
- free_defaults(default_argv);
+ free_allocated_data();
my_end(0);
return 0;
}
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 7d682f6e997..9ad3ef0c1c0 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -2719,7 +2719,7 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
if (create_info->tmp_table())
{
/* CREATE TEMPORARY TABLE LIKE must be skipped from replication */
- WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s",
+ WSREP_DEBUG("CREATE TEMPORARY TABLE LIKE... skipped replication\n %s",
thd->query());
}
else if (!(thd->find_temporary_table(src_table)))
@@ -2729,21 +2729,17 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
}
else
{
- /* here we have CREATE TABLE LIKE <temporary table>
- the temporary table definition will be needed in slaves to
- enable the create to succeed
- */
- TABLE_LIST tbl;
- bzero((void*) &tbl, sizeof(tbl));
- tbl.db= src_table->db;
- tbl.table_name= tbl.alias= src_table->table_name;
- tbl.table= src_table->table;
+ /* Non-MERGE tables ignore this call. */
+ if (src_table->table->file->extra(HA_EXTRA_ADD_CHILDREN_LIST))
+ return (true);
+
char buf[2048];
String query(buf, sizeof(buf), system_charset_info);
query.length(0); // Have to zero it since constructor doesn't
- (void) show_create_table(thd, &tbl, &query, NULL, WITH_DB_NAME);
- WSREP_DEBUG("TMP TABLE: %s", query.ptr());
+ int result __attribute__((unused))=
+ show_create_table(thd, src_table, &query, NULL, WITH_DB_NAME);
+ WSREP_DEBUG("TMP TABLE: %s ret_code %d", query.ptr(), result);
thd->wsrep_TOI_pre_query= query.ptr();
thd->wsrep_TOI_pre_query_len= query.length();
@@ -2752,6 +2748,9 @@ bool wsrep_create_like_table(THD* thd, TABLE_LIST* table,
thd->wsrep_TOI_pre_query= NULL;
thd->wsrep_TOI_pre_query_len= 0;
+
+ /* Non-MERGE tables ignore this call. */
+ src_table->table->file->extra(HA_EXTRA_DETACH_CHILDREN);
}
return(false);