summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-06-01 10:38:09 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-06-01 10:38:09 +0300
commit9c7a456a92262bdb44b85a05aa9f87369c5b063c (patch)
treeae2354c36aa3220a6ca5e8becc41491b52b9881c /sql
parent2a4f72b7d2ac30a771a14d097608b0ce282e021c (diff)
parent77d8da57d744505838a7830afbc437e54cc03c50 (diff)
downloadmariadb-git-9c7a456a92262bdb44b85a05aa9f87369c5b063c.tar.gz
Merge 10.4 into 10.5
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_partition.cc19
-rw-r--r--sql/ha_partition.h5
-rw-r--r--sql/handler.cc42
-rw-r--r--sql/handler.h2
-rw-r--r--sql/mdl.h6
-rw-r--r--sql/sql_admin.cc9
-rw-r--r--sql/sql_base.cc25
-rw-r--r--sql/sql_base.h2
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_trigger.cc11
-rw-r--r--sql/sql_update.cc2
11 files changed, 85 insertions, 40 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 18c6ca5a63c..6b7f6a880d9 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -2385,25 +2385,6 @@ void ha_partition::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
}
}
-/*
- Change comments specific to handler
-
- SYNOPSIS
- update_table_comment()
- comment Original comment
-
- RETURN VALUE
- new comment
-
- DESCRIPTION
- No comment changes so far
-*/
-
-char *ha_partition::update_table_comment(const char *comment)
-{
- return (char*) comment; /* Nothing to change */
-}
-
/**
Handle delete and rename table
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 60a2d7f6762..b77e20f3e9c 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -525,10 +525,6 @@ public:
Meta data routines to CREATE, DROP, RENAME table and often used at
ALTER TABLE (update_create_info used from ALTER TABLE and SHOW ..).
- update_table_comment is used in SHOW TABLE commands to provide a
- chance for the handler to add any interesting comments to the table
- comments not provided by the users comment.
-
create_partitioning_metadata is called before opening a new handler object
with openfrm to call create. It is used to create any local handler
object needed in opening the object in openfrm
@@ -544,7 +540,6 @@ public:
override;
bool check_if_updates_are_ignored(const char *op) const override;
void update_create_info(HA_CREATE_INFO *create_info) override;
- char *update_table_comment(const char *comment) override;
int change_partitions(HA_CREATE_INFO *create_info, const char *path,
ulonglong * const copied, ulonglong * const deleted,
const uchar *pack_frm_data, size_t pack_frm_len)
diff --git a/sql/handler.cc b/sql/handler.cc
index c6031e252a6..112ed23939e 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -7217,10 +7217,24 @@ int handler::ha_update_row(const uchar *old_data, const uchar *new_data)
error= binlog_log_row(table, old_data, new_data, log_func);
}
#ifdef WITH_WSREP
- if (WSREP_NNULL(ha_thd()) && table_share->tmp_table == NO_TMP_TABLE &&
- ht->flags & HTON_WSREP_REPLICATION &&
- !error && (error= wsrep_after_row(ha_thd())))
- return error;
+ THD *thd= ha_thd();
+ if (WSREP_NNULL(thd))
+ {
+ /* for streaming replication, the following wsrep_after_row()
+ may replicate a fragment, so we have to declare potential PA
+ unsafe before that */
+ if (table->s->primary_key == MAX_KEY && wsrep_thd_is_local(thd))
+ {
+ WSREP_DEBUG("marking trx as PA unsafe pk %d", table->s->primary_key);
+ if (thd->wsrep_cs().mark_transaction_pa_unsafe())
+ WSREP_DEBUG("session does not have active transaction,"
+ " can not mark as PA unsafe");
+ }
+
+ if (!error && table_share->tmp_table == NO_TMP_TABLE &&
+ ht->flags & HTON_WSREP_REPLICATION)
+ error= wsrep_after_row(thd);
+ }
#endif /* WITH_WSREP */
}
return error;
@@ -7281,11 +7295,23 @@ int handler::ha_delete_row(const uchar *buf)
error= binlog_log_row(table, buf, 0, log_func);
}
#ifdef WITH_WSREP
- if (WSREP_NNULL(ha_thd()) && table_share->tmp_table == NO_TMP_TABLE &&
- ht->flags & HTON_WSREP_REPLICATION &&
- !error && (error= wsrep_after_row(ha_thd())))
+ THD *thd= ha_thd();
+ if (WSREP_NNULL(thd))
{
- return error;
+ /* for streaming replication, the following wsrep_after_row()
+ may replicate a fragment, so we have to declare potential PA
+ unsafe before that */
+ if (table->s->primary_key == MAX_KEY && wsrep_thd_is_local(thd))
+ {
+ WSREP_DEBUG("marking trx as PA unsafe pk %d", table->s->primary_key);
+ if (thd->wsrep_cs().mark_transaction_pa_unsafe())
+ WSREP_DEBUG("session does not have active transaction,"
+ " can not mark as PA unsafe");
+ }
+
+ if (!error && table_share->tmp_table == NO_TMP_TABLE &&
+ ht->flags & HTON_WSREP_REPLICATION)
+ error= wsrep_after_row(thd);
}
#endif /* WITH_WSREP */
}
diff --git a/sql/handler.h b/sql/handler.h
index 9ae115c59a7..4e98560a869 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -4055,8 +4055,6 @@ public:
/* end of the list of admin commands */
virtual int indexes_are_disabled(void) {return 0;}
- virtual char *update_table_comment(const char * comment)
- { return (char*) comment;}
virtual void append_create_info(String *packet) {}
/**
If index == MAX_KEY then a check for table is made and if index <
diff --git a/sql/mdl.h b/sql/mdl.h
index 45d28cc3068..52c48768329 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -1,7 +1,7 @@
#ifndef MDL_H
#define MDL_H
/* Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
- Copyright (c) 2020, MariaDB
+ Copyright (c) 2020, 2021, 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
@@ -905,6 +905,10 @@ public:
m_tickets[MDL_TRANSACTION].is_empty() &&
m_tickets[MDL_EXPLICIT].is_empty());
}
+ bool has_explicit_locks() const
+ {
+ return !m_tickets[MDL_EXPLICIT].is_empty();
+ }
inline bool has_transactional_locks() const
{
return !m_tickets[MDL_TRANSACTION].is_empty();
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 94381d1bee1..227116a82b2 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -565,8 +565,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_PRINT("admin", ("table: '%s'.'%s'", db, table->table_name.str));
DEBUG_SYNC(thd, "admin_command_kill_before_modify");
- if (thd->is_killed())
- break;
strxmov(table_name, db, ".", table->table_name.str, NullS);
thd->open_options|= extra_open_options;
table->lock_type= lock_type;
@@ -581,6 +579,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
: lock_type >= TL_WRITE_ALLOW_WRITE
? MDL_SHARED_WRITE : MDL_SHARED_READ);
+ if (thd->check_killed())
+ {
+ fatal_error= true;
+ result_code= HA_ADMIN_FAILED;
+ goto send_result;
+ }
+
/* open only one table from local list of command */
while (1)
{
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index f9f9856f4c0..1476d708d75 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2554,7 +2554,17 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count)
/* If no tables left, do an automatic UNLOCK TABLES */
if (thd->lock && thd->lock->table_count == 0)
+ {
+ /*
+ We have to rollback any open transactions here.
+ This is required in the case where the server has been killed
+ but some transations are still open (as part of locked tables).
+ If we don't do this, we will get an assert in unlock_locked_tables().
+ */
+ ha_rollback_trans(thd, FALSE);
+ ha_rollback_trans(thd, TRUE);
unlock_locked_tables(thd);
+ }
}
@@ -9207,6 +9217,21 @@ int dynamic_column_error_message(enum_dyncol_func_result rc)
return rc;
}
+
+/**
+ Turn on the SELECT_DESCRIBE flag for the primary SELECT_LEX of the statement
+ being processed in case the statement is EXPLAIN UPDATE/DELETE.
+
+ @param lex current LEX
+*/
+
+void promote_select_describe_flag_if_needed(LEX *lex)
+{
+ if (lex->describe)
+ lex->first_select_lex()->options|= SELECT_DESCRIBE;
+}
+
+
/**
@} (end of group Data_Dictionary)
*/
diff --git a/sql/sql_base.h b/sql/sql_base.h
index ccfacaf9086..0c90a95b5b0 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -516,6 +516,8 @@ bool extend_table_list(THD *thd, TABLE_LIST *tables,
Prelocking_strategy *prelocking_strategy,
bool has_prelocking_list);
+void promote_select_describe_flag_if_needed(LEX *lex);
+
/**
A context of open_tables() function, used to recover
from a failed open_table() or open_routine() attempt.
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index cf411d01f38..870eecdd494 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -365,6 +365,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
query_plan.select_lex= thd->lex->first_select_lex();
query_plan.table= table;
+ promote_select_describe_flag_if_needed(thd->lex);
+
if (mysql_prepare_delete(thd, table_list, &conds, &delete_while_scanning))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index b8042a90872..a99078362d6 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2004, 2012, Oracle and/or its affiliates.
- Copyright (c) 2010, 2018, MariaDB
+ Copyright (c) 2010, 2021, 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
@@ -647,8 +647,13 @@ end:
thd->lex->spname->m_name.str, static_cast<uint>(thd->lex->spname->m_name.length));
}
- if (mdl_request_for_trn.ticket)
- thd->mdl_context.release_lock(mdl_request_for_trn.ticket);
+ /* In Locked_tables_list::reopen_tables(),
+ MDL_context::set_transaction_duration_for_all_locks() may have been invoked,
+ converting our explicit MDL to transaction scope. In that case, we will not
+ release the lock, to avoid a debug assertion failure. */
+ if (MDL_ticket *ticket= mdl_request_for_trn.ticket)
+ if (thd->mdl_context.has_explicit_locks())
+ thd->mdl_context.release_lock(ticket);
DBUG_RETURN(result);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 578a05d18ae..c14585f44c5 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -468,6 +468,8 @@ int mysql_update(THD *thd,
want_privilege= (table_list->view ? UPDATE_ACL :
table_list->grant.want_privilege);
#endif
+ promote_select_describe_flag_if_needed(thd->lex);
+
if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
DBUG_RETURN(1);