summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-05-30 11:04:27 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-05-30 11:04:27 +0300
commit6da14d7b4a935466de55a6aa87db14bc359dbd30 (patch)
treea2d1a73a6bf6bbe0dab2857fd87fa782969412f4 /sql
parent4783494a5e21939424ecca92bf23d2df65528266 (diff)
parent2e1d10ecacc8ccfc0bda8a199c741ee36df981be (diff)
downloadmariadb-git-6da14d7b4a935466de55a6aa87db14bc359dbd30.tar.gz
Merge 10.3 into 10.4
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_partition.cc17
-rw-r--r--sql/handler.cc13
-rw-r--r--sql/handler.h8
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/opt_range.h1
-rw-r--r--sql/opt_range_mrr.cc1
-rw-r--r--sql/rpl_parallel.cc6
-rw-r--r--sql/rpl_rli.cc65
-rw-r--r--sql/rpl_rli.h21
-rw-r--r--sql/slave.cc31
-rw-r--r--sql/sql_class.h5
-rw-r--r--sql/sql_partition.cc48
-rw-r--r--sql/sql_select.cc10
-rw-r--r--sql/sql_table.cc44
-rw-r--r--sql/table.cc8
-rw-r--r--sql/unireg.cc2
16 files changed, 207 insertions, 74 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 6af69fc67b6..b9342a327e2 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -2240,7 +2240,8 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
sub_elem= subpart_it++;
DBUG_ASSERT(sub_elem);
part= i * num_subparts + j;
- DBUG_ASSERT(part < m_file_tot_parts && m_file[part]);
+ DBUG_ASSERT(part < m_file_tot_parts);
+ DBUG_ASSERT(m_file[part]);
dummy_info.data_file_name= dummy_info.index_file_name = NULL;
m_file[part]->update_create_info(&dummy_info);
sub_elem->data_file_name = (char*) dummy_info.data_file_name;
@@ -3909,7 +3910,8 @@ int ha_partition::external_lock(THD *thd, int lock_type)
MY_BITMAP *used_partitions;
DBUG_ENTER("ha_partition::external_lock");
- DBUG_ASSERT(!auto_increment_lock && !auto_increment_safe_stmt_log_lock);
+ DBUG_ASSERT(!auto_increment_lock);
+ DBUG_ASSERT(!auto_increment_safe_stmt_log_lock);
if (lock_type == F_UNLCK)
used_partitions= &m_locked_partitions;
@@ -4188,8 +4190,8 @@ void ha_partition::unlock_row()
bool ha_partition::was_semi_consistent_read()
{
DBUG_ENTER("ha_partition::was_semi_consistent_read");
- DBUG_ASSERT(m_last_part < m_tot_parts &&
- bitmap_is_set(&(m_part_info->read_partitions), m_last_part));
+ DBUG_ASSERT(m_last_part < m_tot_parts);
+ DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), m_last_part));
DBUG_RETURN(m_file[m_last_part]->was_semi_consistent_read());
}
@@ -7101,8 +7103,8 @@ int ha_partition::partition_scan_set_up(uchar * buf, bool idx_read_flag)
DBUG_ASSERT(m_part_spec.start_part < m_tot_parts);
m_ordered_scan_ongoing= m_ordered;
}
- DBUG_ASSERT(m_part_spec.start_part < m_tot_parts &&
- m_part_spec.end_part < m_tot_parts);
+ DBUG_ASSERT(m_part_spec.start_part < m_tot_parts);
+ DBUG_ASSERT(m_part_spec.end_part < m_tot_parts);
DBUG_RETURN(0);
}
@@ -10549,7 +10551,8 @@ void ha_partition::get_auto_increment(ulonglong offset, ulonglong increment,
DBUG_PRINT("enter", ("offset: %lu inc: %lu desired_values: %lu "
"first_value: %lu", (ulong) offset, (ulong) increment,
(ulong) nb_desired_values, (ulong) *first_value));
- DBUG_ASSERT(increment && nb_desired_values);
+ DBUG_ASSERT(increment);
+ DBUG_ASSERT(nb_desired_values);
*first_value= 0;
if (table->s->next_number_keypart)
{
diff --git a/sql/handler.cc b/sql/handler.cc
index a7e7e2554cb..cc7eedd18f2 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4380,6 +4380,19 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
/**
+ End bulk insert
+*/
+
+int handler::ha_end_bulk_insert()
+{
+ DBUG_ENTER("handler::ha_end_bulk_insert");
+ DBUG_EXECUTE_IF("crash_end_bulk_insert",
+ { extra(HA_EXTRA_FLUSH) ; DBUG_SUICIDE();});
+ estimation_rows_to_insert= 0;
+ DBUG_RETURN(end_bulk_insert());
+}
+
+/**
Bulk update row: public interface.
@sa handler::bulk_update_row()
diff --git a/sql/handler.h b/sql/handler.h
index c764915cc51..cdcb117da97 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -3301,13 +3301,7 @@ public:
start_bulk_insert(rows, flags);
DBUG_VOID_RETURN;
}
- int ha_end_bulk_insert()
- {
- DBUG_ENTER("handler::ha_end_bulk_insert");
- estimation_rows_to_insert= 0;
- int ret= end_bulk_insert();
- DBUG_RETURN(ret);
- }
+ int ha_end_bulk_insert();
int ha_bulk_update_row(const uchar *old_data, const uchar *new_data,
ha_rows *dup_key_found);
int ha_delete_all_rows();
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d0859ad5573..99b8457cf20 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -340,7 +340,6 @@ static bool max_long_data_size_used= false;
static bool volatile select_thread_in_use, signal_thread_in_use;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_short_log_format= 0, opt_silent_startup= 0;
-bool my_disable_leak_check= false;
uint kill_cached_threads;
static uint wake_thread;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 73def7bde92..11d9f80865a 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -672,6 +672,7 @@ public:
bool statement_should_be_aborted() const
{
return
+ thd->killed ||
thd->is_fatal_error ||
thd->is_error() ||
alloced_sel_args > SEL_ARG::MAX_SEL_ARGS;
diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc
index 267d764bb3b..20413f5df63 100644
--- a/sql/opt_range_mrr.cc
+++ b/sql/opt_range_mrr.cc
@@ -79,6 +79,7 @@ range_seq_t sel_arg_range_seq_init(void *init_param, uint n_ranges, uint flags)
SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
seq->param->range_count=0;
seq->at_start= TRUE;
+ seq->param->max_key_parts= 0;
seq->stack[0].key_tree= NULL;
seq->stack[0].min_key= seq->param->min_key;
seq->stack[0].min_key_flag= 0;
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 9344312fe62..88e036d4481 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -93,18 +93,18 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev)
/* Do not update position if an earlier event group caused an error abort. */
DBUG_ASSERT(qev->typ == rpl_parallel_thread::queued_event::QUEUED_POS_UPDATE);
+ rli= qev->rgi->rli;
e= qev->entry_for_queued;
- if (e->stop_on_error_sub_id < (uint64)ULONGLONG_MAX || e->force_abort)
+ if (e->stop_on_error_sub_id < (uint64)ULONGLONG_MAX ||
+ (e->force_abort && !rli->stop_for_until))
return;
- rli= qev->rgi->rli;
mysql_mutex_lock(&rli->data_lock);
cmp= strcmp(rli->group_relay_log_name, qev->event_relay_log_name);
if (cmp < 0)
{
rli->group_relay_log_pos= qev->future_event_relay_log_pos;
strmake_buf(rli->group_relay_log_name, qev->event_relay_log_name);
- rli->notify_group_relay_log_name_update();
} else if (cmp == 0 &&
rli->group_relay_log_pos < qev->future_event_relay_log_pos)
rli->group_relay_log_pos= qev->future_event_relay_log_pos;
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 49b2e00882e..2c3e3d5a838 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -62,6 +62,7 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery)
slave_running(MYSQL_SLAVE_NOT_RUN), until_condition(UNTIL_NONE),
until_log_pos(0), retried_trans(0), executed_entries(0),
sql_delay(0), sql_delay_end(0),
+ until_relay_log_names_defer(false),
m_flags(0)
{
DBUG_ENTER("Relay_log_info::Relay_log_info");
@@ -503,6 +504,8 @@ void Relay_log_info::clear_until_condition()
until_condition= Relay_log_info::UNTIL_NONE;
until_log_name[0]= 0;
until_log_pos= 0;
+ until_relay_log_names_defer= false;
+
DBUG_VOID_RETURN;
}
@@ -993,7 +996,6 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
{
group_relay_log_pos= rgi->future_event_relay_log_pos;
strmake_buf(group_relay_log_name, rgi->event_relay_log_name);
- notify_group_relay_log_name_update();
} else if (cmp == 0 && group_relay_log_pos < rgi->future_event_relay_log_pos)
group_relay_log_pos= rgi->future_event_relay_log_pos;
@@ -1283,29 +1285,78 @@ err:
autoincrement or if we have transactions).
Should be called ONLY if until_condition != UNTIL_NONE !
+
+ In the parallel execution mode and UNTIL_MASTER_POS the file name is
+ presented by future_event_master_log_name which may be ahead of
+ group_master_log_name. Log_event::log_pos does relate to it nevertheless
+ so the pair comprises a correct binlog coordinate.
+ Internal group events and events that have zero log_pos also
+ produce the zero for the local log_pos which may not lead to the
+ function falsely return true.
+ In UNTIL_RELAY_POS the original caching and notification are simplified
+ to straightforward files comparison when the current event can't be
+ a part of an event group.
+
RETURN VALUE
true - condition met or error happened (condition seems to have
bad log file name)
false - condition not met
*/
-bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos)
+bool Relay_log_info::is_until_satisfied(Log_event *ev)
{
const char *log_name;
ulonglong log_pos;
+ /* Prevents stopping within transaction; needed solely for Relay UNTIL. */
+ bool in_trans= false;
+
DBUG_ENTER("Relay_log_info::is_until_satisfied");
if (until_condition == UNTIL_MASTER_POS)
{
log_name= (mi->using_parallel() ? future_event_master_log_name
: group_master_log_name);
- log_pos= master_beg_pos;
+ log_pos= (get_flag(Relay_log_info::IN_TRANSACTION) || !ev || !ev->log_pos) ?
+ (mi->using_parallel() ? 0 : group_master_log_pos) :
+ ev->log_pos - ev->data_written;
}
else
{
DBUG_ASSERT(until_condition == UNTIL_RELAY_POS);
- log_name= group_relay_log_name;
- log_pos= group_relay_log_pos;
+ if (!mi->using_parallel())
+ {
+ log_name= group_relay_log_name;
+ log_pos= group_relay_log_pos;
+ }
+ else
+ {
+ log_name= event_relay_log_name;
+ log_pos= event_relay_log_pos;
+ in_trans= get_flag(Relay_log_info::IN_TRANSACTION);
+ /*
+ until_log_names_cmp_result is set to UNKNOWN either
+ - by a non-group event *and* only when it is in the middle of a group
+ - or by a group event when the preceding group made the above
+ non-group event to defer the resetting.
+ */
+ if ((ev && !Log_event::is_group_event(ev->get_type_code())))
+ {
+ if (in_trans)
+ {
+ until_relay_log_names_defer= true;
+ }
+ else
+ {
+ until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
+ until_relay_log_names_defer= false;
+ }
+ }
+ else if (!in_trans && until_relay_log_names_defer)
+ {
+ until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
+ until_relay_log_names_defer= false;
+ }
+ }
}
DBUG_PRINT("info", ("group_master_log_name='%s', group_master_log_pos=%llu",
@@ -1359,8 +1410,8 @@ bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos)
}
DBUG_RETURN(((until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_EQUAL &&
- log_pos >= until_log_pos) ||
- until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_GREATER));
+ (log_pos >= until_log_pos && !in_trans)) ||
+ until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_GREATER));
}
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index fafe8ead63d..f89b40b1efc 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -219,7 +219,7 @@ public:
*/
char future_event_master_log_name[FN_REFLEN];
- /*
+ /*
Original log name and position of the group we're currently executing
(whose coordinates are group_relay_log_name/pos in the relay log)
in the master's binlog. These concern the *group*, because in the master's
@@ -419,7 +419,7 @@ public:
void close_temporary_tables();
/* Check if UNTIL condition is satisfied. See slave.cc for more. */
- bool is_until_satisfied(my_off_t);
+ bool is_until_satisfied(Log_event *ev);
inline ulonglong until_pos()
{
DBUG_ASSERT(until_condition == UNTIL_MASTER_POS ||
@@ -427,7 +427,13 @@ public:
return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos :
group_relay_log_pos);
}
-
+ inline char *until_name()
+ {
+ DBUG_ASSERT(until_condition == UNTIL_MASTER_POS ||
+ until_condition == UNTIL_RELAY_POS);
+ return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_name :
+ group_relay_log_name);
+ }
/**
Helper function to do after statement completion.
@@ -564,6 +570,15 @@ private:
relay_log.info had 4 lines. Now it has 5 lines.
*/
static const int LINES_IN_RELAY_LOG_INFO_WITH_DELAY= 5;
+ /*
+ Hint for when to stop event distribution by sql driver thread.
+ The flag is set ON by a non-group event when this event is in the middle
+ of a group (e.g a transaction group) so it's too early
+ to refresh the current-relay-log vs until-log cached comparison result.
+ And it is checked and to decide whether it's a right time to do so
+ when the being processed group has been fully scheduled.
+ */
+ bool until_relay_log_names_defer;
/*
Holds the state of the data in the relay log.
diff --git a/sql/slave.cc b/sql/slave.cc
index 6dd31151715..31025b835b2 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -4311,12 +4311,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
rli->until_condition == Relay_log_info::UNTIL_RELAY_POS) &&
(ev->server_id != global_system_variables.server_id ||
rli->replicate_same_server_id) &&
- rli->is_until_satisfied((rli->get_flag(Relay_log_info::IN_TRANSACTION) || !ev->log_pos)
- ? rli->group_master_log_pos
- : ev->log_pos - ev->data_written))
+ rli->is_until_satisfied(ev))
{
- sql_print_information("Slave SQL thread stopped because it reached its"
- " UNTIL position %llu", rli->until_pos());
/*
Setting abort_slave flag because we do not want additional
message about error in query execution to be printed.
@@ -5559,10 +5555,14 @@ pthread_handler_t handle_slave_sql(void *arg)
}
if ((rli->until_condition == Relay_log_info::UNTIL_MASTER_POS ||
rli->until_condition == Relay_log_info::UNTIL_RELAY_POS) &&
- rli->is_until_satisfied(rli->group_master_log_pos))
+ rli->is_until_satisfied(NULL))
{
sql_print_information("Slave SQL thread stopped because it reached its"
- " UNTIL position %llu", rli->until_pos());
+ " UNTIL position %llu in %s %s file",
+ rli->until_pos(), rli->until_name(),
+ rli->until_condition ==
+ Relay_log_info::UNTIL_MASTER_POS ?
+ "binlog" : "relaylog");
mysql_mutex_unlock(&rli->data_lock);
goto err;
}
@@ -5641,7 +5641,24 @@ pthread_handler_t handle_slave_sql(void *arg)
err:
if (mi->using_parallel())
rli->parallel.wait_for_done(thd, rli);
+ /* Gtid_list_log_event::do_apply_event has already reported the GTID until */
+ if (rli->stop_for_until && rli->until_condition != Relay_log_info::UNTIL_GTID)
+ {
+ if (global_system_variables.log_warnings > 2)
+ sql_print_information("Slave SQL thread UNTIL stop was requested at position "
+ "%llu in %s %s file",
+ rli->until_log_pos, rli->until_log_name,
+ rli->until_condition ==
+ Relay_log_info::UNTIL_MASTER_POS ?
+ "binlog" : "relaylog");
+ sql_print_information("Slave SQL thread stopped because it reached its"
+ " UNTIL position %llu in %s %s file",
+ rli->until_pos(), rli->until_name(),
+ rli->until_condition ==
+ Relay_log_info::UNTIL_MASTER_POS ?
+ "binlog" : "relaylog");
+ };
/* Thread stopped. Print the current replication position to the log */
{
StringBuffer<100> tmp;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 1cef262cffa..02ecb87038c 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2009, 2019, MariaDB Corporation.
+ Copyright (c) 2009, 2020, MariaDB Corporation.
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
@@ -4013,7 +4013,8 @@ public:
The worst things that can happen is that we get
a suboptimal error message.
*/
- if (likely((killed_err= (err_info*) alloc(sizeof(*killed_err)))))
+ killed_err= (err_info*) alloc_root(&main_mem_root, sizeof(*killed_err));
+ if (likely(killed_err))
{
killed_err->no= killed_errno_arg;
::strmake((char*) killed_err->msg, killed_err_msg_arg,
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 9a08973562c..9a212cd2246 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -5981,6 +5981,37 @@ the generated partition syntax in a correct manner.
*partition_changed= TRUE;
}
}
+ /*
+ Prohibit inplace when partitioned by primary key and the primary key is changed.
+ */
+ if (!*partition_changed &&
+ tab_part_info->part_field_array &&
+ !tab_part_info->part_field_list.elements &&
+ table->s->primary_key != MAX_KEY)
+ {
+
+ if (alter_info->flags & (ALTER_DROP_SYSTEM_VERSIONING |
+ ALTER_ADD_SYSTEM_VERSIONING))
+ {
+ *partition_changed= true;
+ }
+ else
+ {
+ KEY *primary_key= table->key_info + table->s->primary_key;
+ List_iterator_fast<Alter_drop> drop_it(alter_info->drop_list);
+ const char *primary_name= primary_key->name.str;
+ const Alter_drop *drop;
+ drop_it.rewind();
+ while ((drop= drop_it++))
+ {
+ if (drop->type == Alter_drop::KEY &&
+ 0 == my_strcasecmp(system_charset_info, primary_name, drop->name))
+ break;
+ }
+ if (drop)
+ *partition_changed= TRUE;
+ }
+ }
}
if (thd->work_part_info)
{
@@ -6013,23 +6044,6 @@ the generated partition syntax in a correct manner.
}
}
- // In case of PARTITION BY KEY(), check if primary key has changed
- // System versioning also implicitly adds/removes primary key parts
- if (alter_info->partition_flags == 0 && part_info->list_of_part_fields
- && part_info->part_field_list.elements == 0)
- {
- if (alter_info->flags & (ALTER_DROP_SYSTEM_VERSIONING |
- ALTER_ADD_SYSTEM_VERSIONING))
- *partition_changed= true;
-
- List_iterator<Key> it(alter_info->key_list);
- Key *key;
- while((key= it++) && !*partition_changed)
- {
- if (key->type == Key::PRIMARY)
- *partition_changed= true;
- }
- }
/*
Set up partition default_engine_type either from the create_info
or from the previus table
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ee74cfa8e97..568a3ed6062 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1029,10 +1029,16 @@ int SELECT_LEX::vers_setup_conds(THD *thd, TABLE_LIST *tables)
if (vers_conditions.is_set())
{
+ if (vers_conditions.was_set() &&
+ table->lock_type > TL_READ_NO_INSERT &&
+ !vers_conditions.delete_history)
+ {
+ my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table->alias.str);
+ DBUG_RETURN(-1);
+ }
+
if (vers_conditions.type == SYSTEM_TIME_ALL)
continue;
-
- lock_type= TL_READ; // ignore TL_WRITE, history is immutable anyway
}
bool timestamps_only= table->table->versioned(VERS_TIMESTAMP);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index ff6c2873dfc..1c5aac08584 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4402,6 +4402,25 @@ bool validate_comment_length(THD *thd, LEX_CSTRING *comment, size_t max_len,
Well_formed_prefix(system_charset_info, *comment, max_len).length();
if (tmp_len < comment->length)
{
+#if MARIADB_VERSION_ID < 100500
+ if (comment->length <= max_len)
+ {
+ if (thd->is_strict_mode())
+ {
+ my_error(ER_INVALID_CHARACTER_STRING, MYF(0),
+ system_charset_info->csname, comment->str);
+ DBUG_RETURN(true);
+ }
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_INVALID_CHARACTER_STRING,
+ ER_THD(thd, ER_INVALID_CHARACTER_STRING),
+ system_charset_info->csname, comment->str);
+ comment->length= tmp_len;
+ DBUG_RETURN(false);
+ }
+#else
+#error do it in TEXT_STRING_sys
+#endif
if (thd->is_strict_mode())
{
my_error(err_code, MYF(0), name, static_cast<ulong>(max_len));
@@ -7910,16 +7929,13 @@ blob_length_by_type(enum_field_types type)
}
-static void append_drop_column(THD *thd, bool dont, String *str,
- Field *field)
+static inline
+void append_drop_column(THD *thd, String *str, Field *field)
{
- if (!dont)
- {
- if (str->length())
- str->append(STRING_WITH_LEN(", "));
- str->append(STRING_WITH_LEN("DROP COLUMN "));
- append_identifier(thd, str, &field->field_name);
- }
+ if (str->length())
+ str->append(STRING_WITH_LEN(", "));
+ str->append(STRING_WITH_LEN("DROP COLUMN "));
+ append_identifier(thd, str, &field->field_name);
}
@@ -8175,7 +8191,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
field->invisible < INVISIBLE_SYSTEM)
{
StringBuffer<NAME_LEN*3> tmp;
- append_drop_column(thd, false, &tmp, field);
+ append_drop_column(thd, &tmp, field);
my_error(ER_MISSING, MYF(0), table->s->table_name.str, tmp.c_ptr());
goto err;
}
@@ -8228,10 +8244,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
!vers_system_invisible)
{
StringBuffer<NAME_LEN*3> tmp;
- append_drop_column(thd, dropped_sys_vers_fields & VERS_SYS_START_FLAG,
- &tmp, table->vers_start_field());
- append_drop_column(thd, dropped_sys_vers_fields & VERS_SYS_END_FLAG,
- &tmp, table->vers_end_field());
+ if (!(dropped_sys_vers_fields & VERS_SYS_START_FLAG))
+ append_drop_column(thd, &tmp, table->vers_start_field());
+ if (!(dropped_sys_vers_fields & VERS_SYS_END_FLAG))
+ append_drop_column(thd, &tmp, table->vers_end_field());
my_error(ER_MISSING, MYF(0), table->s->table_name.str, tmp.c_ptr());
goto err;
}
diff --git a/sql/table.cc b/sql/table.cc
index 92dfa59e648..a4de5d9c930 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -8383,9 +8383,10 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
int TABLE::update_virtual_field(Field *vf)
{
- DBUG_ASSERT(!in_use->is_error());
- Query_arena backup_arena;
DBUG_ENTER("TABLE::update_virtual_field");
+ Query_arena backup_arena;
+ Counting_error_handler count_errors;
+ in_use->push_internal_handler(&count_errors);
in_use->set_n_backup_active_arena(expr_arena, &backup_arena);
bitmap_clear_all(&tmp_set);
vf->vcol_info->expr->walk(&Item::update_vcol_processor, 0, &tmp_set);
@@ -8393,7 +8394,8 @@ int TABLE::update_virtual_field(Field *vf)
vf->vcol_info->expr->save_in_field(vf, 0);
DBUG_RESTORE_WRITE_SET(vf);
in_use->restore_active_arena(expr_arena, &backup_arena);
- DBUG_RETURN(in_use->is_error());
+ in_use->pop_internal_handler();
+ DBUG_RETURN(count_errors.errors);
}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 2b162e9a374..7990a67081e 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009, 2018, MariaDB Corporation
+ Copyright (c) 2009, 2020, MariaDB Corporation.
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