summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-12-01 19:51:14 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-12-01 19:51:14 +0200
commit589cf8dbf3accf57673d7e2f7a4435f7eaf33565 (patch)
treeaa38a67d10f71fc781188341857e34d437fa9199 /sql
parenta3531775b1efe06e2439a0c8ab668a2b69c859eb (diff)
parente30a05f4540b581df2e7d98bd7e812aeff603744 (diff)
downloadmariadb-git-589cf8dbf3accf57673d7e2f7a4435f7eaf33565.tar.gz
Merge 10.3 into 10.4
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc9
-rw-r--r--sql/ha_partition.cc2
-rw-r--r--sql/ha_partition.h20
-rw-r--r--sql/handler.cc9
-rw-r--r--sql/handler.h16
-rw-r--r--sql/item.cc11
-rw-r--r--sql/item.h5
-rw-r--r--sql/item_cmpfunc.cc11
-rw-r--r--sql/item_subselect.cc3
-rw-r--r--sql/item_subselect.h8
-rw-r--r--sql/log_event.cc7
-rw-r--r--sql/mdl.cc3
-rw-r--r--sql/opt_subselect.cc8
-rw-r--r--sql/rpl_gtid.cc4
-rw-r--r--sql/rpl_injector.cc56
-rw-r--r--sql/rpl_rli.cc12
-rw-r--r--sql/sp.cc6
-rw-r--r--sql/sp_head.cc8
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_admin.cc22
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h24
-rw-r--r--sql/sql_delete.cc4
-rw-r--r--sql/sql_derived.cc19
-rw-r--r--sql/sql_insert.cc13
-rw-r--r--sql/sql_parse.cc30
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_select.cc4
-rw-r--r--sql/sql_select.h11
-rw-r--r--sql/sql_show.cc21
-rw-r--r--sql/sql_statistics.cc4
-rw-r--r--sql/sql_table.cc4
-rw-r--r--sql/sql_tvc.cc6
-rw-r--r--sql/sql_type.cc44
-rw-r--r--sql/sql_type.h38
-rw-r--r--sql/sql_union.cc1
-rw-r--r--sql/sys_vars.cc2
-rw-r--r--sql/table.cc4
-rw-r--r--sql/threadpool_common.cc3
-rw-r--r--sql/transaction.cc2
-rw-r--r--sql/unireg.cc4
-rw-r--r--sql/xa.cc4
43 files changed, 247 insertions, 223 deletions
diff --git a/sql/field.cc b/sql/field.cc
index a7d5f6b3328..5a694b50fe0 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1887,13 +1887,8 @@ bool Field::compatible_field_size(uint field_metadata,
int Field::store(const char *to, size_t length, CHARSET_INFO *cs,
enum_check_fields check_level)
{
- int res;
- THD *thd= get_thd();
- enum_check_fields old_check_level= thd->count_cuted_fields;
- thd->count_cuted_fields= check_level;
- res= store(to, length, cs);
- thd->count_cuted_fields= old_check_level;
- return res;
+ Check_level_instant_set check_level_save(get_thd(), check_level);
+ return store(to, length, cs);
}
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 9f5f9766605..609e2135a99 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -4345,7 +4345,7 @@ int ha_partition::write_row(const uchar * buf)
tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
error= m_file[part_id]->ha_write_row(buf);
- if (have_auto_increment && !table->s->next_number_keypart)
+ if (!error && have_auto_increment && !table->s->next_number_keypart)
set_auto_increment_if_higher(table->next_number_field);
reenable_binlog(thd);
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 7d10dc19683..08b7d7cf8f2 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -92,7 +92,6 @@ public:
bool auto_inc_initialized;
mysql_mutex_t auto_inc_mutex; /**< protecting auto_inc val */
ulonglong next_auto_inc_val; /**< first non reserved value */
- ulonglong prev_auto_inc_val; /**< stored next_auto_inc_val */
/**
Hash of partition names. Initialized in the first ha_partition::open()
for the table_share. After that it is read-only, i.e. no locking required.
@@ -104,7 +103,6 @@ public:
Partition_share()
: auto_inc_initialized(false),
next_auto_inc_val(0),
- prev_auto_inc_val(0),
partition_name_hash_initialized(false),
partition_names(NULL)
{
@@ -430,24 +428,6 @@ private:
MY_BITMAP m_locked_partitions;
/** Stores shared auto_increment etc. */
Partition_share *part_share;
- /** Fix spurious -Werror=overloaded-virtual in GCC 9 */
- virtual void restore_auto_increment(ulonglong prev_insert_id) override
- {
- handler::restore_auto_increment(prev_insert_id);
- }
- /** Store and restore next_auto_inc_val over duplicate key errors. */
- void store_auto_increment() override
- {
- DBUG_ASSERT(part_share);
- part_share->prev_auto_inc_val= part_share->next_auto_inc_val;
- handler::store_auto_increment();
- }
- void restore_auto_increment() override
- {
- DBUG_ASSERT(part_share);
- part_share->next_auto_inc_val= part_share->prev_auto_inc_val;
- handler::restore_auto_increment();
- }
void sum_copy_info(handler *file);
void sum_copy_infos();
void reset_copy_info() override;
diff --git a/sql/handler.cc b/sql/handler.cc
index 2553cd22a59..ed12830ce20 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -3310,7 +3310,6 @@ int handler::update_auto_increment()
THD *thd= table->in_use;
struct system_variables *variables= &thd->variables;
int result=0, tmp;
- enum enum_check_fields save_count_cuted_fields;
DBUG_ENTER("handler::update_auto_increment");
/*
@@ -3452,10 +3451,10 @@ int handler::update_auto_increment()
nr, append ? nb_reserved_values : 0));
/* Store field without warning (Warning will be printed by insert) */
- save_count_cuted_fields= thd->count_cuted_fields;
- thd->count_cuted_fields= CHECK_FIELD_IGNORE;
- tmp= table->next_number_field->store((longlong)nr, TRUE);
- thd->count_cuted_fields= save_count_cuted_fields;
+ {
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
+ tmp= table->next_number_field->store((longlong)nr, TRUE);
+ }
if (unlikely(tmp)) // Out of range value in store
{
diff --git a/sql/handler.h b/sql/handler.h
index c516ea4bfc4..0c8be2154a9 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -3149,10 +3149,6 @@ private:
*/
Handler_share **ha_share;
- /** Stores next_insert_id for handling duplicate key errors. */
- ulonglong m_prev_insert_id;
-
-
public:
handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
:table_share(share_arg), table(0),
@@ -3177,7 +3173,7 @@ public:
auto_inc_intervals_count(0),
m_psi(NULL), set_top_table_fields(FALSE), top_table(0),
top_table_field(0), top_table_fields(0),
- m_lock_type(F_UNLCK), ha_share(NULL), m_prev_insert_id(0)
+ m_lock_type(F_UNLCK), ha_share(NULL)
{
DBUG_PRINT("info",
("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
@@ -3858,16 +3854,6 @@ public:
insert_id_for_cur_row;
}
- /** Store and restore next_insert_id over duplicate key errors. */
- virtual void store_auto_increment()
- {
- m_prev_insert_id= next_insert_id;
- }
- virtual void restore_auto_increment()
- {
- restore_auto_increment(m_prev_insert_id);
- }
-
virtual void update_create_info(HA_CREATE_INFO *create_info) {}
int check_old_types();
virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
diff --git a/sql/item.cc b/sql/item.cc
index 26e99fe752e..f700bcfe680 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1419,18 +1419,13 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions)
int res;
TABLE *table= field->table;
THD *thd= table->in_use;
- enum_check_fields tmp= thd->count_cuted_fields;
- my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
- sql_mode_t sql_mode= thd->variables.sql_mode;
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
+ Sql_mode_save sql_mode(thd);
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
thd->variables.sql_mode|= MODE_INVALID_DATES;
- thd->count_cuted_fields= CHECK_FIELD_IGNORE;
-
+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
res= save_in_field(field, no_conversions);
-
- thd->count_cuted_fields= tmp;
dbug_tmp_restore_column_map(table->write_set, old_map);
- thd->variables.sql_mode= sql_mode;
return res;
}
diff --git a/sql/item.h b/sql/item.h
index 2b49487d677..e2e18ce9b86 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -951,6 +951,11 @@ public:
void set_name_no_truncate(THD *thd, const char *str, uint length,
CHARSET_INFO *cs);
void init_make_send_field(Send_field *tmp_field, const Type_handler *h);
+ void share_name_with(const Item *item)
+ {
+ name= item->name;
+ is_autogenerated_name= item->is_autogenerated_name;
+ }
virtual void cleanup();
virtual void make_send_field(THD *thd, Send_field *field);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index bf992886eda..c43dbcaab78 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -319,19 +319,18 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item,
if ((*item)->const_item() && !(*item)->is_expensive())
{
TABLE *table= field->table;
- sql_mode_t orig_sql_mode= thd->variables.sql_mode;
- enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
+ Sql_mode_save sql_mode(thd);
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
my_bitmap_map *old_maps[2] = { NULL, NULL };
ulonglong UNINIT_VAR(orig_field_val); /* original field value if valid */
/* table->read_set may not be set if we come here from a CREATE TABLE */
if (table && table->read_set)
- dbug_tmp_use_all_columns(table, old_maps,
+ dbug_tmp_use_all_columns(table, old_maps,
table->read_set, table->write_set);
/* For comparison purposes allow invalid dates like 2000-01-32 */
- thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
+ thd->variables.sql_mode= (thd->variables.sql_mode & ~MODE_NO_ZERO_DATE) |
MODE_INVALID_DATES;
- thd->count_cuted_fields= CHECK_FIELD_IGNORE;
/*
Store the value of the field/constant because the call to save_in_field
@@ -368,8 +367,6 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item,
/* orig_field_val must be a valid value that can be restored back. */
DBUG_ASSERT(!result);
}
- thd->variables.sql_mode= orig_sql_mode;
- thd->count_cuted_fields= orig_count_cuted_fields;
if (table && table->read_set)
dbug_tmp_restore_column_maps(table->read_set, table->write_set, old_maps);
}
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 7887724358d..e2058475d0e 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1484,7 +1484,8 @@ Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
pushed_cond_guards(NULL), do_not_convert_to_sj(FALSE), is_jtbm_merged(FALSE),
is_jtbm_const_tab(FALSE), is_flattenable_semijoin(FALSE),
is_registered_semijoin(FALSE),
- upper_item(0)
+ upper_item(0),
+ converted_from_in_predicate(FALSE)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
DBUG_PRINT("info", ("in_strategy: %u", (uint)in_strategy));
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 99bb5b190c2..16a4735359b 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -610,12 +610,18 @@ public:
Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
+ /*
+ SET to TRUE if IN subquery is converted from an IN predicate
+ */
+ bool converted_from_in_predicate;
+
Item_in_subselect(THD *thd_arg, Item * left_expr, st_select_lex *select_lex);
Item_in_subselect(THD *thd_arg):
Item_exists_subselect(thd_arg), left_expr_cache(0), first_execution(TRUE),
in_strategy(SUBS_NOT_TRANSFORMED),
pushed_cond_guards(NULL), func(NULL), do_not_convert_to_sj(FALSE),
- is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE), upper_item(0) {}
+ is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE), upper_item(0),
+ converted_from_in_predicate(FALSE) {}
void cleanup();
subs_type substype() { return IN_SUBS; }
void reset()
diff --git a/sql/log_event.cc b/sql/log_event.cc
index b06336669f3..6871eeda79e 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -7570,10 +7570,10 @@ error:
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
else if (! thd->in_multi_stmt_transaction_mode())
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
else
thd->mdl_context.release_statement_locks();
@@ -9047,7 +9047,8 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi)
"COMMIT /* implicit, from Xid_log_event */");
thd->variables.option_bits&= ~OPTION_GTID_BEGIN;
res= trans_commit(thd); /* Automatically rolls back on error. */
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
+
#ifdef WITH_WSREP
if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
if ((!res || (WSREP(thd) && thd->wsrep_trx().state() == wsrep::transaction::s_must_replay )) && sub_id)
diff --git a/sql/mdl.cc b/sql/mdl.cc
index 54128c2ee97..ebe1bb75927 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -3036,6 +3036,9 @@ void MDL_context::rollback_to_savepoint(const MDL_savepoint &mdl_savepoint)
void MDL_context::release_transactional_locks()
{
DBUG_ENTER("MDL_context::release_transactional_locks");
+ /* Fail if there are active transactions */
+ DBUG_ASSERT(!(current_thd->server_status &
+ (SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY)));
release_locks_stored_before(MDL_STATEMENT, NULL);
release_locks_stored_before(MDL_TRANSACTION, NULL);
DBUG_VOID_RETURN;
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 62af68262ba..f7349e7a1bf 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -868,6 +868,7 @@ bool subquery_types_allow_materialization(THD* thd, Item_in_subselect *in_subs)
bool all_are_fields= TRUE;
uint32 total_key_length = 0;
+ bool converted_from_in_predicate= in_subs->converted_from_in_predicate;
for (uint i= 0; i < elements; i++)
{
Item *outer= in_subs->left_expr->element_index(i);
@@ -875,8 +876,11 @@ bool subquery_types_allow_materialization(THD* thd, Item_in_subselect *in_subs)
all_are_fields &= (outer->real_item()->type() == Item::FIELD_ITEM &&
inner->real_item()->type() == Item::FIELD_ITEM);
total_key_length += inner->max_length;
- if (!inner->type_handler()->subquery_type_allows_materialization(inner,
- outer))
+ if (!inner->
+ type_handler()->
+ subquery_type_allows_materialization(inner,
+ outer,
+ converted_from_in_predicate))
{
trace_transform.add("possible", false);
trace_transform.add("cause", "types mismatch");
diff --git a/sql/rpl_gtid.cc b/sql/rpl_gtid.cc
index f58df09623c..88e6447ddcc 100644
--- a/sql/rpl_gtid.cc
+++ b/sql/rpl_gtid.cc
@@ -441,7 +441,7 @@ rpl_slave_state::truncate_state_table(THD *thd)
close_thread_tables(thd);
ha_commit_trans(thd, TRUE);
}
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
reenable_binlog(thd);
@@ -988,7 +988,7 @@ end:
ha_rollback_trans(thd, FALSE);
}
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
thd->lex->restore_backup_query_tables_list(&lex_backup);
if (err)
diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc
index 597a357e4e2..442d28fceb3 100644
--- a/sql/rpl_injector.cc
+++ b/sql/rpl_injector.cc
@@ -68,34 +68,34 @@ injector::transaction::~transaction()
*/
int injector::transaction::commit()
{
- DBUG_ENTER("injector::transaction::commit()");
- int error= m_thd->binlog_flush_pending_rows_event(true);
- /*
- Cluster replication does not preserve statement or
- transaction boundaries of the master. Instead, a new
- transaction on replication slave is started when a new GCI
- (global checkpoint identifier) is issued, and is committed
- when the last event of the check point has been received and
- processed. This ensures consistency of each cluster in
- cluster replication, and there is no requirement for stronger
- consistency: MySQL replication is asynchronous with other
- engines as well.
-
- A practical consequence of that is that row level replication
- stream passed through the injector thread never contains
- COMMIT events.
- Here we should preserve the server invariant that there is no
- outstanding statement transaction when the normal transaction
- is committed by committing the statement transaction
- explicitly.
- */
- trans_commit_stmt(m_thd);
- if (!trans_commit(m_thd))
- {
- close_thread_tables(m_thd);
- m_thd->mdl_context.release_transactional_locks();
- }
- DBUG_RETURN(error);
+ DBUG_ENTER("injector::transaction::commit()");
+ int error= m_thd->binlog_flush_pending_rows_event(true);
+ /*
+ Cluster replication does not preserve statement or
+ transaction boundaries of the master. Instead, a new
+ transaction on replication slave is started when a new GCI
+ (global checkpoint identifier) is issued, and is committed
+ when the last event of the check point has been received and
+ processed. This ensures consistency of each cluster in
+ cluster replication, and there is no requirement for stronger
+ consistency: MySQL replication is asynchronous with other
+ engines as well.
+
+ A practical consequence of that is that row level replication
+ stream passed through the injector thread never contains
+ COMMIT events.
+ Here we should preserve the server invariant that there is no
+ outstanding statement transaction when the normal transaction
+ is committed by committing the statement transaction
+ explicitly.
+ */
+ trans_commit_stmt(m_thd);
+ if (!trans_commit(m_thd))
+ {
+ close_thread_tables(m_thd);
+ m_thd->release_transactional_locks();
+ }
+ DBUG_RETURN(error);
}
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 241d8321749..39b2fa38515 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1702,7 +1702,7 @@ scan_all_gtid_slave_pos_table(THD *thd, int (*cb)(THD *, LEX_CSTRING *, void *),
{
my_error(ER_FILE_NOT_FOUND, MYF(0), path, my_errno);
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
return 1;
}
else
@@ -1715,7 +1715,7 @@ scan_all_gtid_slave_pos_table(THD *thd, int (*cb)(THD *, LEX_CSTRING *, void *),
err= ha_discover_table_names(thd, &MYSQL_SCHEMA_NAME, dirp, &tl, false);
my_dirend(dirp);
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
if (err)
return err;
@@ -2000,7 +2000,7 @@ end:
ha_commit_trans(thd, FALSE);
ha_commit_trans(thd, TRUE);
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
return err;
@@ -2282,7 +2282,7 @@ void rpl_group_info::cleanup_context(THD *thd, bool error)
if (unlikely(error))
{
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
if (thd == rli->sql_driver_thd)
{
@@ -2396,10 +2396,10 @@ void rpl_group_info::slave_close_thread_tables(THD *thd)
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
else if (! thd->in_multi_stmt_transaction_mode())
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
else
thd->mdl_context.release_statement_locks();
diff --git a/sql/sp.cc b/sql/sp.cc
index 081edcd725e..0b553ebf7a1 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1181,8 +1181,6 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
- enum_check_fields saved_count_cuted_fields;
-
bool store_failed= FALSE;
DBUG_ENTER("sp_create_routine");
DBUG_PRINT("enter", ("type: %s name: %.*s",
@@ -1216,8 +1214,7 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
/* Reset sql_mode during data dictionary operations. */
thd->variables.sql_mode= 0;
- saved_count_cuted_fields= thd->count_cuted_fields;
- thd->count_cuted_fields= CHECK_FIELD_WARN;
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_WARN);
if (!(table= open_proc_table_for_update(thd)))
{
@@ -1477,7 +1474,6 @@ log:
ret= FALSE;
done:
- thd->count_cuted_fields= saved_count_cuted_fields;
thd->variables.sql_mode= saved_mode;
DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
DBUG_RETURN(ret);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index e91364b0c0a..aa4f80907f5 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -2311,10 +2311,10 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
else if (! thd->in_multi_stmt_transaction_mode())
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
else
thd->mdl_context.release_statement_locks();
}
@@ -3442,10 +3442,10 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
else if (! thd->in_multi_stmt_transaction_mode())
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
else
thd->mdl_context.release_statement_locks();
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 57e8411b084..0769e1eb395 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -9312,6 +9312,8 @@ static bool show_global_privileges(THD *thd, ACL_USER_BASE *acl_entry,
add_user_parameters(thd, &global, (ACL_USER *)acl_entry,
(want_access & GRANT_ACL));
+ else if (want_access & GRANT_ACL)
+ global.append(STRING_WITH_LEN(" WITH GRANT OPTION"));
protocol->prepare_for_resend();
protocol->store(global.ptr(),global.length(),global.charset());
if (protocol->write())
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 37aab267511..0a6e76d117f 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2010, 2015, Oracle and/or its affiliates.
- Copyright (c) 2011, 2019, MariaDB
+ Copyright (c) 2011, 2020, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -43,7 +43,7 @@ static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list)
trans_rollback_stmt(thd);
trans_rollback(thd);
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
/*
table_list->table has been closed and freed. Do not reference
@@ -116,7 +116,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
acquire the exclusive lock to satisfy MDL asserts and avoid
deadlocks.
*/
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
/*
Attempt to do full-blown table open in mysql_admin_table() has failed.
Let us try to open at least a .FRM for this table.
@@ -285,7 +285,7 @@ end:
}
/* In case of a temporary table there will be no metadata lock. */
if (unlikely(error) && has_mdl_lock)
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
DBUG_RETURN(error);
}
@@ -614,7 +614,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
trans_rollback(thd);
close_thread_tables(thd);
table->table= NULL;
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
table->mdl_request.init(MDL_key::TABLE, table->db.str, table->table_name.str,
MDL_SHARED_NO_READ_WRITE, MDL_TRANSACTION);
}
@@ -674,7 +674,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
trans_rollback_stmt(thd);
trans_rollback(thd);
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
DBUG_PRINT("admin", ("simple error, admin next table"));
continue;
case -1: // error, message could be written to net
@@ -741,7 +741,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
trans_commit_stmt(thd);
trans_commit(thd);
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
lex->reset_query_tables_list(FALSE);
/*
Restore Query_tables_list::sql_command value to make statement
@@ -874,7 +874,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
thd->open_options|= extra_open_options;
close_thread_tables(thd);
table->table= NULL;
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
table->mdl_request.init(MDL_key::TABLE, table->db.str, table->table_name.str,
MDL_SHARED_NO_READ_WRITE, MDL_TRANSACTION);
table->mdl_request.set_type(MDL_SHARED_READ);
@@ -1106,7 +1106,7 @@ send_result_message:
trans_commit_stmt(thd);
trans_commit(thd);
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
/* Clear references to TABLE and MDL_ticket after releasing them. */
table->mdl_request.ticket= NULL;
@@ -1259,7 +1259,7 @@ send_result_message:
goto err;
}
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
/*
If it is CHECK TABLE v1, v2, v3, and v1, v2, v3 are views, we will run
@@ -1297,7 +1297,7 @@ err:
table->table= 0;
}
close_thread_tables(thd); // Shouldn't be needed
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
thd->resume_subsequent_commits(suspended_wfc);
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 4be70abb7db..868d76572e3 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -9149,7 +9149,7 @@ close_mysql_tables(THD *thd)
if (! thd->in_sub_stmt)
trans_commit_stmt(thd);
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
/*
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 041574485fe..573e4318682 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -4824,7 +4824,7 @@ void destroy_thd(MYSQL_THD thd)
void reset_thd(MYSQL_THD thd)
{
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
thd->free_items();
free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 41b69742834..845e392eff7 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4574,6 +4574,13 @@ public:
locked_tables_mode= mode_arg;
}
void leave_locked_tables_mode();
+ /* Relesae transactional locks if there are no active transactions */
+ void release_transactional_locks()
+ {
+ if (!(server_status &
+ (SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY)))
+ mdl_context.release_transactional_locks();
+ }
int decide_logging_format(TABLE_LIST *tables);
/*
In Some cases when decide_logging_format is called it does not have all
@@ -6745,6 +6752,23 @@ class Switch_to_definer_security_ctx
};
+class Check_level_instant_set
+{
+ THD *m_thd;
+ enum_check_fields m_check_level;
+public:
+ Check_level_instant_set(THD *thd, enum_check_fields temporary_value)
+ :m_thd(thd), m_check_level(thd->count_cuted_fields)
+ {
+ thd->count_cuted_fields= temporary_value;
+ }
+ ~Check_level_instant_set()
+ {
+ m_thd->count_cuted_fields= m_check_level;
+ }
+};
+
+
/**
This class resembles the SQL Standard schema qualified object name:
<schema qualified name> ::= [ <schema name> <period> ] <qualified identifier>
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index a4ef698590c..5d006a7518c 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -260,7 +260,7 @@ int update_portion_of_time(THD *thd, TABLE *table,
uint dst_fieldno= lcond ? table->s->period.end_fieldno
: table->s->period.start_fieldno;
- table->file->store_auto_increment();
+ ulonglong prev_insert_id= table->file->next_insert_id;
store_record(table, record[1]);
if (likely(!res))
res= src->save_in_field(table->field[dst_fieldno], true);
@@ -276,7 +276,7 @@ int update_portion_of_time(THD *thd, TABLE *table,
TRG_ACTION_AFTER, true);
restore_record(table, record[1]);
if (res)
- table->file->restore_auto_increment();
+ table->file->restore_auto_increment(prev_insert_id);
if (likely(!res) && lcond && rcond)
res= table->period_make_insert(period_conds.end.item,
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 3b312225937..1e416c307cf 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1402,7 +1402,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
DBUG_RETURN(false);
st_select_lex_unit *unit= derived->get_unit();
- st_select_lex *sl= unit->first_select();
+ st_select_lex *first_sl= unit->first_select();
+ st_select_lex *sl= first_sl;
if (derived->prohibit_cond_pushdown)
DBUG_RETURN(false);
@@ -1461,6 +1462,20 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
if (!extracted_cond_copy)
continue;
+ /*
+ Rename the columns of all non-first selects of a union to be compatible
+ by names with the columns of the first select. It will allow to use copies
+ of the same expression pushed into having clauses of different selects.
+ */
+ if (sl != first_sl)
+ {
+ DBUG_ASSERT(sl->item_list.elements == first_sl->item_list.elements);
+ List_iterator_fast<Item> it(sl->item_list);
+ List_iterator_fast<Item> nm_it(unit->types);
+ while (Item *item= it++)
+ item->share_name_with(nm_it++);
+ }
+
/* Collect fields that are used in the GROUP BY of sl */
if (sl->have_window_funcs())
{
@@ -1481,7 +1496,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
&remaining_cond,
&Item::derived_field_transformer_for_where,
(uchar *) sl);
-
+
if (!remaining_cond)
continue;
/*
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 7dd83d625e8..b8d11cd778f 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1721,7 +1721,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
int error, trg_error= 0;
char *key=0;
MY_BITMAP *save_read_set, *save_write_set;
- table->file->store_auto_increment();
+ ulonglong prev_insert_id= table->file->next_insert_id;
ulonglong insert_id_for_cur_row= 0;
ulonglong prev_insert_id_for_cur_row= 0;
DBUG_ENTER("write_record");
@@ -1870,7 +1870,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (res == VIEW_CHECK_ERROR)
goto before_trg_err;
- table->file->restore_auto_increment();
+ table->file->restore_auto_increment(prev_insert_id);
info->touched++;
if (different_records)
{
@@ -2064,7 +2064,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if (!(thd->variables.old_behavior &
OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE))
table->file->print_error(error, MYF(ME_WARNING));
- table->file->restore_auto_increment();
+ table->file->restore_auto_increment(prev_insert_id);
goto ok_or_after_trg_err;
}
@@ -2087,7 +2087,7 @@ err:
table->file->print_error(error,MYF(0));
before_trg_err:
- table->file->restore_auto_increment();
+ table->file->restore_auto_increment(prev_insert_id);
if (key)
my_safe_afree(key, table->s->max_unique_length);
table->column_bitmaps_set(save_read_set, save_write_set);
@@ -3061,7 +3061,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
if (thd->mdl_context.clone_ticket(&di->grl_protection) ||
thd->mdl_context.clone_ticket(&di->table_list.mdl_request))
{
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
di->handler_thread_initialized= TRUE;
goto err;
}
@@ -3276,7 +3276,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->set_killed(KILL_CONNECTION_HARD); // If error
close_thread_tables(thd); // Free the table
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
mysql_cond_broadcast(&di->cond_client); // Safety
mysql_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table
@@ -4766,6 +4766,7 @@ bool select_create::send_eof()
WSREP_ERROR("Appending table key for CTAS failed: %s, %d",
(wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void", rcode);
+ abort_result_set();
DBUG_RETURN(true);
}
/* If commit fails, we should be able to reset the OK status. */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8cb25197ea2..036c1215ea6 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2057,7 +2057,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
locks.
*/
trans_rollback_implicit(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
thd->cleanup_after_query();
@@ -2122,7 +2122,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ulonglong options= (ulonglong) (uchar) packet[0];
if (trans_commit_implicit(thd))
break;
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
if (check_global_access(thd,RELOAD_ACL))
break;
general_log_print(thd, command, NullS);
@@ -2157,7 +2157,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (trans_commit_implicit(thd))
break;
close_thread_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
my_ok(thd);
break;
}
@@ -2993,7 +2993,7 @@ err:
/* Close tables and release metadata locks. */
close_thread_tables(thd);
DBUG_ASSERT(!thd->locked_tables_mode);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
return TRUE;
}
@@ -3733,7 +3733,7 @@ mysql_execute_command(THD *thd)
/* Commit the normal transaction if one is active. */
bool commit_failed= trans_commit_implicit(thd);
/* Release metadata locks acquired in this transaction. */
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
if (commit_failed)
{
WSREP_DEBUG("implicit commit failed, MDL released: %lld",
@@ -5011,7 +5011,7 @@ mysql_execute_command(THD *thd)
{
res= trans_commit_implicit(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
}
if (thd->global_read_lock.is_acquired() &&
@@ -5026,7 +5026,7 @@ mysql_execute_command(THD *thd)
res= trans_commit_implicit(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
if (res)
goto error;
@@ -5644,7 +5644,7 @@ mysql_execute_command(THD *thd)
DBUG_PRINT("info", ("Executing SQLCOM_BEGIN thd: %p", thd));
if (trans_begin(thd, lex->start_transaction_opt))
{
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
WSREP_DEBUG("BEGIN failed, MDL released: %lld",
(longlong) thd->thread_id);
WSREP_DEBUG("stmt_da, sql_errno: %d", (thd->get_stmt_da()->is_error()) ? thd->get_stmt_da()->sql_errno() : 0);
@@ -5663,7 +5663,7 @@ mysql_execute_command(THD *thd)
(thd->variables.completion_type == 2 &&
lex->tx_release != TVL_NO));
bool commit_failed= trans_commit(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
if (commit_failed)
{
WSREP_DEBUG("COMMIT failed, MDL released: %lld",
@@ -5701,7 +5701,7 @@ mysql_execute_command(THD *thd)
(thd->variables.completion_type == 2 &&
lex->tx_release != TVL_NO));
bool rollback_failed= trans_rollback(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
if (rollback_failed)
{
@@ -6004,7 +6004,6 @@ mysql_execute_command(THD *thd)
case SQLCOM_XA_COMMIT:
{
bool commit_failed= trans_xa_commit(thd);
- thd->mdl_context.release_transactional_locks();
if (commit_failed)
{
WSREP_DEBUG("XA commit failed, MDL released: %lld",
@@ -6022,7 +6021,6 @@ mysql_execute_command(THD *thd)
case SQLCOM_XA_ROLLBACK:
{
bool rollback_failed= trans_xa_rollback(thd);
- thd->mdl_context.release_transactional_locks();
if (rollback_failed)
{
WSREP_DEBUG("XA rollback failed, MDL released: %lld",
@@ -6227,7 +6225,7 @@ finish:
*/
THD_STAGE_INFO(thd, stage_rollback_implicit);
trans_rollback_implicit(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
else if (stmt_causes_implicit_commit(thd, CF_IMPLICIT_COMMIT_END))
{
@@ -6241,7 +6239,7 @@ finish:
/* Commit the normal transaction if one is active. */
trans_commit_implicit(thd);
thd->get_stmt_da()->set_overwrite_status(false);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
}
else if (! thd->in_sub_stmt && ! thd->in_multi_stmt_transaction_mode())
@@ -6256,7 +6254,7 @@ finish:
- If in autocommit mode, or outside a transactional context,
automatically release metadata locks of the current statement.
*/
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
else if (! thd->in_sub_stmt)
{
@@ -6281,7 +6279,7 @@ finish:
{
WSREP_DEBUG("Forcing release of transactional locks for thd: %lld",
(longlong) thd->thread_id);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
/*
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 849d1895fa1..ee504028074 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -4270,7 +4270,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (thd->transaction_rollback_request)
{
trans_rollback_implicit(thd);
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
}
/* Preserve CHANGE MASTER attributes */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 123d20698be..9671880f1e0 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -24035,8 +24035,7 @@ cmp_buffer_with_ref(THD *thd, TABLE *table, TABLE_REF *tab_ref)
bool
cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
{
- enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
- thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
bool result= 0;
@@ -24048,7 +24047,6 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
break;
}
}
- thd->count_cuted_fields= save_count_cuted_fields;
dbug_tmp_restore_column_map(table->write_set, old_map);
return result;
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 3ac8c152ffc..e14907d73bc 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1900,18 +1900,11 @@ public:
{
enum store_key_result result;
THD *thd= to_field->table->in_use;
- enum_check_fields saved_count_cuted_fields= thd->count_cuted_fields;
- sql_mode_t orig_sql_mode= thd->variables.sql_mode;
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
+ Sql_mode_save sql_mode(thd);
thd->variables.sql_mode&= ~(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE);
thd->variables.sql_mode|= MODE_INVALID_DATES;
-
- thd->count_cuted_fields= CHECK_FIELD_IGNORE;
-
result= copy_inner();
-
- thd->count_cuted_fields= saved_count_cuted_fields;
- thd->variables.sql_mode= orig_sql_mode;
-
return result;
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 29ee8ef2fb1..1fdd2d7c8d0 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3732,7 +3732,6 @@ static bool show_status_array(THD *thd, const char *wild,
char name_buffer[NAME_CHAR_LEN];
int len;
SHOW_VAR tmp, *var;
- enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
bool res= FALSE;
CHARSET_INFO *charset= system_charset_info;
DBUG_ENTER("show_status_array");
@@ -3855,7 +3854,6 @@ static bool show_status_array(THD *thd, const char *wild,
}
}
end:
- thd->count_cuted_fields= save_count_cuted_fields;
DBUG_RETURN(res);
}
@@ -4583,8 +4581,7 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root,
Open_tables_backup *open_tables_state_backup,
bool can_deadlock)
{
- Query_arena i_s_arena(mem_root,
- Query_arena::STMT_CONVENTIONAL_EXECUTION),
+ Query_arena i_s_arena(mem_root, Query_arena::STMT_CONVENTIONAL_EXECUTION),
backup_arena, *old_arena;
LEX *old_lex= thd->lex, temp_lex, *lex;
LEX_CSTRING db_name, table_name;
@@ -5098,12 +5095,9 @@ end:
class Warnings_only_error_handler : public Internal_error_handler
{
public:
- bool handle_condition(THD *thd,
- uint sql_errno,
- const char* sqlstate,
+ bool handle_condition(THD *thd, uint sql_errno, const char* sqlstate,
Sql_condition::enum_warning_level *level,
- const char* msg,
- Sql_condition ** cond_hdl)
+ const char* msg, Sql_condition ** cond_hdl)
{
if (sql_errno == ER_TRG_NO_DEFINER || sql_errno == ER_TRG_NO_CREATION_CTX)
return true;
@@ -8721,13 +8715,6 @@ static int optimize_schema_tables_memory_usage(TABLE_LIST *table_list)
DBUG_ASSERT(table->s->keys == 0);
DBUG_ASSERT(table->s->uniques == 0);
- // XXX HACK HACK HACK: in a stored function, RETURN (SELECT ...)
- // enables warnings (in THD::sp_eval_expr) for the whole val_xxx/store pair,
- // while the intention is to warn only for store(). Until this is
- // fixed let's avoid data truncation warnings in I_S->fill_table()
- if (thd->count_cuted_fields == CHECK_FIELD_IGNORE)
- {
-
uchar *cur= table->field[0]->ptr;
/* first recinfo could be a NULL bitmap, not an actual Field */
from_recinfo= to_recinfo= p->start_recinfo + (cur != table->record[0]);
@@ -8761,7 +8748,6 @@ static int optimize_schema_tables_memory_usage(TABLE_LIST *table_list)
to_recinfo++;
}
p->recinfo= to_recinfo;
- } // XXX end of HACK HACK HACK
// TODO switch from Aria to Memory if all blobs were optimized away?
if (instantiate_tmp_table(table, p->keyinfo, p->start_recinfo, &p->recinfo,
@@ -8924,6 +8910,7 @@ bool get_schema_tables_result(JOIN *join,
}
Switch_to_definer_security_ctx backup_ctx(thd, table_list);
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
if (table_list->schema_table->fill_table(thd, table_list, cond))
{
result= 1;
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index ed569d6eab8..717deeabe18 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -2893,7 +2893,6 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
Field **field_ptr;
KEY *key_info, *key_info_end;
TABLE_SHARE *table_share= table->s;
- enum_check_fields old_check_level= thd->count_cuted_fields;
DBUG_ENTER("read_statistics_for_table");
DEBUG_SYNC(thd, "statistics_mem_alloc_start1");
@@ -2909,7 +2908,7 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
}
/* Don't write warnings for internal field conversions */
- thd->count_cuted_fields= CHECK_FIELD_IGNORE;
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_IGNORE);
/* Read statistics from the statistical table table_stats */
Table_statistics *read_stats= table_share->stats_cb.table_stats;
@@ -2991,7 +2990,6 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
}
}
- thd->count_cuted_fields= old_check_level;
table_share->stats_cb.end_stats_load();
DBUG_RETURN(0);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 942b838c692..6a52b7d418e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -10149,16 +10149,14 @@ do_continue:;
if (use_inplace)
{
table->s->frm_image= &frm;
- enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
/*
Set the truncated column values of thd as warning
for alter table.
*/
- thd->count_cuted_fields = CHECK_FIELD_WARN;
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_WARN);
int res= mysql_inplace_alter_table(thd, table_list, table, &altered_table,
&ha_alter_info,
&target_mdl_request, &alter_ctx);
- thd->count_cuted_fields= save_count_cuted_fields;
my_free(const_cast<uchar*>(frm.str));
if (res)
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index 763fd8ec45b..916047c4b0f 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -828,7 +828,8 @@ static bool cmp_row_types(Item* item1, Item* item2)
Item *inner= item1->element_index(i);
Item *outer= item2->element_index(i);
if (!inner->type_handler()->subquery_type_allows_materialization(inner,
- outer))
+ outer,
+ true))
return true;
}
return false;
@@ -894,7 +895,7 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
for (uint i=1; i < arg_count; i++)
{
- if (!args[i]->const_item() || cmp_row_types(args[0], args[i]))
+ if (!args[i]->const_item() || cmp_row_types(args[i], args[0]))
return this;
}
@@ -974,6 +975,7 @@ Item *Item_func_in::in_predicate_to_in_subs_transformer(THD *thd,
if (!(in_subs=
new (thd->mem_root) Item_in_subselect(thd, args[0], sq_select)))
goto err;
+ in_subs->converted_from_in_predicate= TRUE;
sq= in_subs;
if (negated)
sq= negate_expression(thd, in_subs);
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index ad356b4c874..36f128a3a0b 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -19,6 +19,7 @@
#include "sql_const.h"
#include "sql_class.h"
#include "sql_time.h"
+#include "sql_string.h"
#include "item.h"
#include "log.h"
#include "tztime.h"
@@ -6683,7 +6684,8 @@ uint Type_handler_timestamp_common::Item_decimal_precision(const Item *item) con
bool Type_handler_real_result::
subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const
+ const Item *outer,
+ bool is_in_predicate) const
{
DBUG_ASSERT(inner->cmp_type() == REAL_RESULT);
return outer->cmp_type() == REAL_RESULT;
@@ -6692,7 +6694,8 @@ bool Type_handler_real_result::
bool Type_handler_int_result::
subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const
+ const Item *outer,
+ bool is_in_predicate) const
{
DBUG_ASSERT(inner->cmp_type() == INT_RESULT);
return outer->cmp_type() == INT_RESULT;
@@ -6701,7 +6704,8 @@ bool Type_handler_int_result::
bool Type_handler_decimal_result::
subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const
+ const Item *outer,
+ bool is_in_predicate) const
{
DBUG_ASSERT(inner->cmp_type() == DECIMAL_RESULT);
return outer->cmp_type() == DECIMAL_RESULT;
@@ -6710,23 +6714,37 @@ bool Type_handler_decimal_result::
bool Type_handler_string_result::
subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const
+ const Item *outer,
+ bool is_in_predicate) const
{
DBUG_ASSERT(inner->cmp_type() == STRING_RESULT);
- return outer->cmp_type() == STRING_RESULT &&
- outer->collation.collation == inner->collation.collation &&
- /*
- Materialization also is unable to work when create_tmp_table() will
- create a blob column because item->max_length is too big.
- The following test is copied from varstring_type_handler().
- */
- !inner->too_big_for_varchar();
+ if (outer->cmp_type() == STRING_RESULT &&
+ /*
+ Materialization also is unable to work when create_tmp_table() will
+ create a blob column because item->max_length is too big.
+ The following test is copied from varstring_type_handler().
+ */
+ !inner->too_big_for_varchar())
+ {
+ if (outer->collation.collation == inner->collation.collation)
+ return true;
+ if (is_in_predicate)
+ {
+ Charset inner_col(inner->collation.collation);
+ if (inner_col.encoding_allows_reinterpret_as(outer->
+ collation.collation) &&
+ inner_col.eq_collation_specific_names(outer->collation.collation))
+ return true;
+ }
+ }
+ return false;
}
bool Type_handler_temporal_result::
subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const
+ const Item *outer,
+ bool is_in_predicate) const
{
DBUG_ASSERT(inner->cmp_type() == TIME_RESULT);
return mysql_timestamp_type() ==
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 939c651233c..f8ebc269788 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -3718,9 +3718,21 @@ public:
Item *target_expr, Item *target_value,
Item_bool_func2 *source,
Item *source_expr, Item *source_const) const= 0;
+
+ /*
+ @brief
+ Check if an IN subquery allows materialization or not
+ @param
+ inner expression on the inner side of the IN subquery
+ outer expression on the outer side of the IN subquery
+ is_in_predicate SET to true if IN subquery was converted from an
+ IN predicate or we are checking if materialization
+ strategy can be used for an IN predicate
+ */
virtual bool
subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const= 0;
+ const Item *outer,
+ bool is_in_predicate) const= 0;
/**
Make a simple constant replacement item for a constant "src",
so the new item can futher be used for comparison with "cmp", e.g.:
@@ -3966,7 +3978,8 @@ public:
return 0;
}
bool subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const
+ const Item *outer,
+ bool is_in_predicate) const
{
DBUG_ASSERT(0);
return false;
@@ -4313,7 +4326,8 @@ public:
const Field *field) const;
int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const;
bool subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const;
+ const Item *outer,
+ bool is_in_predicate) const;
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
Sort_param *param) const;
void sortlength(THD *thd,
@@ -4399,7 +4413,8 @@ public:
return item_val.is_null() ? 0 : my_decimal(field).cmp(item_val.ptr());
}
bool subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const;
+ const Item *outer,
+ bool is_in_predicate) const;
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
Sort_param *param) const;
@@ -4624,7 +4639,8 @@ public:
const Type_handler *type_handler_for_comparison() const;
int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const;
bool subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const;
+ const Item *outer,
+ bool is_in_predicate) const;
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field,
Sort_param *param) const;
@@ -4733,7 +4749,8 @@ public:
Item_bool_func2 *source,
Item *source_expr, Item *source_const) const;
bool subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const;
+ const Item *outer,
+ bool is_in_predicate) const;
bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
Item **items, uint nitems) const;
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
@@ -4855,7 +4872,8 @@ public:
Item_bool_func2 *source,
Item *source_expr, Item *source_const) const;
bool subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const;
+ const Item *outer,
+ bool is_in_predicate) const;
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
bool set_comparator_func(Arg_comparator *cmp) const;
@@ -6185,7 +6203,8 @@ public:
return blob_type_handler(item);
}
bool subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const
+ const Item *outer,
+ bool is_in_predicate) const
{
return false; // Materialization does not work with BLOB columns
}
@@ -6304,7 +6323,8 @@ public:
return true;
}
bool subquery_type_allows_materialization(const Item *inner,
- const Item *outer) const
+ const Item *outer,
+ bool is_in_predicate) const
{
return false; // Materialization does not work with GEOMETRY columns
}
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 994e3665267..027d5882722 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -2102,6 +2102,7 @@ bool st_select_lex::cleanup()
delete join;
join= 0;
}
+ leaf_tables.empty();
for (SELECT_LEX_UNIT *lex_unit= first_inner_unit(); lex_unit ;
lex_unit= lex_unit->next_unit())
{
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 8e3b49bb6f7..4c3028b0a00 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -4123,7 +4123,7 @@ static bool fix_autocommit(sys_var *self, THD *thd, enum_var_type type)
if (trans_commit_stmt(thd) || trans_commit(thd))
{
thd->variables.option_bits&= ~OPTION_AUTOCOMMIT;
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
WSREP_DEBUG("autocommit, MDL TRX lock released: %lld",
(longlong) thd->thread_id);
return true;
diff --git a/sql/table.cc b/sql/table.cc
index 38777de34a7..084b441e4c6 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8499,7 +8499,7 @@ int TABLE::period_make_insert(Item *src, Field *dst)
{
THD *thd= in_use;
- file->store_auto_increment();
+ ulonglong prev_insert_id= file->next_insert_id;
store_record(this, record[1]);
int res= src->save_in_field(dst, true);
@@ -8519,7 +8519,7 @@ int TABLE::period_make_insert(Item *src, Field *dst)
restore_record(this, record[1]);
if (res)
- file->restore_auto_increment();
+ file->restore_auto_increment(prev_insert_id);
return res;
}
diff --git a/sql/threadpool_common.cc b/sql/threadpool_common.cc
index f40a958e62a..3320b9fc0cc 100644
--- a/sql/threadpool_common.cc
+++ b/sql/threadpool_common.cc
@@ -209,12 +209,11 @@ void tp_callback(TP_connection *c)
error:
c->thd= 0;
- delete c;
-
if (thd)
{
threadpool_remove_connection(thd);
}
+ delete c;
worker_context.restore();
}
diff --git a/sql/transaction.cc b/sql/transaction.cc
index aecee04c364..135d274e6c6 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -138,7 +138,7 @@ bool trans_begin(THD *thd, uint flags)
Release transactional metadata locks only after the
transaction has been committed.
*/
- thd->mdl_context.release_transactional_locks();
+ thd->release_transactional_locks();
// The RO/RW options are mutually exclusive.
DBUG_ASSERT(!((flags & MYSQL_START_TRANS_OPT_READ_ONLY) &&
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 41481d253ee..17222efe791 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1028,7 +1028,6 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
TABLE table;
TABLE_SHARE share;
Create_field *field;
- enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
DBUG_ENTER("make_empty_rec");
/* We need a table to generate columns for default values */
@@ -1047,7 +1046,7 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
null_pos= buff;
List_iterator<Create_field> it(create_fields);
- thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values
+ Check_level_instant_set check_level_save(thd, CHECK_FIELD_WARN);
while ((field=it++))
{
Record_addr addr(buff + field->offset + data_offset,
@@ -1094,6 +1093,5 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options,
*(null_pos + null_count / 8)|= ~(((uchar) 1 << (null_count & 7)) - 1);
err:
- thd->count_cuted_fields= old_count_cuted_fields;
DBUG_RETURN(error);
} /* make_empty_rec */
diff --git a/sql/xa.cc b/sql/xa.cc
index de7fdf51011..6275532e035 100644
--- a/sql/xa.cc
+++ b/sql/xa.cc
@@ -513,11 +513,13 @@ bool trans_xa_prepare(THD *thd)
/**
Commit and terminate the a XA transaction.
+ Transactional locks are released if transaction ended
@param thd Current thread
@retval FALSE Success
@retval TRUE Failure
+
*/
bool trans_xa_commit(THD *thd)
@@ -601,6 +603,7 @@ bool trans_xa_commit(THD *thd)
xid_cache_delete(thd, &thd->transaction.xid_state);
trans_track_end_trx(thd);
+ thd->mdl_context.release_transactional_locks();
DBUG_RETURN(res);
}
@@ -608,6 +611,7 @@ bool trans_xa_commit(THD *thd)
/**
Roll back and terminate a XA transaction.
+ Transactional locks are released if transaction ended
@param thd Current thread