summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-04-08 10:36:41 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-04-08 10:36:41 +0300
commitccc06931c3c7be094f6dcddeb45589f06cf0c8af (patch)
treeacfd8ed3cae2ee65cf6ddca6d96b907ea172d1dd /sql
parent9075973dbf2ef69e95d427e3a979be23435692e3 (diff)
parent476966b3fb05ce8c061a4b77a0ab0b722bb0d192 (diff)
downloadmariadb-git-ccc06931c3c7be094f6dcddeb45589f06cf0c8af.tar.gz
Merge 10.4 into 10.5
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc17
-rw-r--r--sql/field.h1
-rw-r--r--sql/log.cc18
-rw-r--r--sql/opt_trace.cc21
-rw-r--r--sql/rowid_filter.cc29
-rw-r--r--sql/rowid_filter.h2
-rw-r--r--sql/sql_partition.cc39
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_table.cc37
-rw-r--r--sql/sql_update.cc1
-rw-r--r--sql/table.h1
-rw-r--r--sql/unireg.cc7
-rw-r--r--sql/wsrep_high_priority_service.cc6
-rw-r--r--sql/wsrep_thd.cc7
14 files changed, 125 insertions, 63 deletions
diff --git a/sql/field.cc b/sql/field.cc
index a2cfbe65294..04c45dfb546 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -11077,3 +11077,20 @@ void Field::print_key_value_binary(String *out, const uchar* key, uint32 length)
{
out->append_semi_hex((const char*)key, length, charset());
}
+
+
+Virtual_column_info* Virtual_column_info::clone(THD *thd)
+{
+ Virtual_column_info* dst= new (thd->mem_root) Virtual_column_info(*this);
+ if (!dst)
+ return NULL;
+ if (expr)
+ {
+ dst->expr= expr->get_copy(thd);
+ if (!dst->expr)
+ return NULL;
+ }
+ if (!thd->make_lex_string(&dst->name, name.str, name.length))
+ return NULL;
+ return dst;
+};
diff --git a/sql/field.h b/sql/field.h
index 05955db2a58..d709a84e0fe 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -596,6 +596,7 @@ public:
name.str= NULL;
name.length= 0;
};
+ Virtual_column_info* clone(THD *thd);
~Virtual_column_info() {};
enum_vcol_info_type get_vcol_type() const
{
diff --git a/sql/log.cc b/sql/log.cc
index 72833c7c173..fce768b2e4c 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2408,9 +2408,6 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
int error= 1;
DBUG_ENTER("binlog_savepoint_set");
- if (wsrep_emulate_bin_log)
- DBUG_RETURN(0);
-
char buf[1024];
String log_query(buf, sizeof(buf), &my_charset_bin);
@@ -2443,9 +2440,6 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
{
DBUG_ENTER("binlog_savepoint_rollback");
- if (wsrep_emulate_bin_log)
- DBUG_RETURN(0);
-
/*
Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
non-transactional table. Otherwise, truncate the binlog cache starting
@@ -11011,18 +11005,20 @@ void wsrep_register_binlog_handler(THD *thd, bool trx)
back a statement or a transaction. However, notifications do not happen
if the binary log is set as read/write.
*/
- //binlog_cache_mngr *cache_mngr= thd_get_cache_mngr(thd);
binlog_cache_mngr *cache_mngr=
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
/* cache_mngr may be missing e.g. in mtr test ev51914.test */
- if (cache_mngr && cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF)
+ if (cache_mngr)
{
/*
Set an implicit savepoint in order to be able to truncate a trx-cache.
*/
- my_off_t pos= 0;
- binlog_trans_log_savepos(thd, &pos);
- cache_mngr->trx_cache.set_prev_position(pos);
+ if (cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF)
+ {
+ my_off_t pos= 0;
+ binlog_trans_log_savepos(thd, &pos);
+ cache_mngr->trx_cache.set_prev_position(pos);
+ }
/*
Set callbacks in order to be able to call commmit or rollback.
diff --git a/sql/opt_trace.cc b/sql/opt_trace.cc
index a8676eec411..ddec6d5ed2d 100644
--- a/sql/opt_trace.cc
+++ b/sql/opt_trace.cc
@@ -24,6 +24,8 @@
#include "my_json_writer.h"
#include "sp_head.h"
+#include "rowid_filter.h"
+
const char I_S_table_name[]= "OPTIMIZER_TRACE";
/**
@@ -664,14 +666,17 @@ void print_best_access_for_table(THD *thd, POSITION *pos,
{
DBUG_ASSERT(thd->trace_started());
- Json_writer_object trace_best_access(thd, "chosen_access_method");
- trace_best_access.add("type", type == JT_ALL ? "scan" :
- join_type_str[type]);
- trace_best_access.add("records", pos->records_read);
- trace_best_access.add("cost", pos->read_time);
- trace_best_access.add("uses_join_buffering", pos->use_join_buffer);
- trace_best_access.add("filter_used",
- pos->range_rowid_filter_info != NULL);
+ Json_writer_object obj(thd, "chosen_access_method");
+ obj.add("type", type == JT_ALL ? "scan" : join_type_str[type]);
+ obj.add("records", pos->records_read);
+ obj.add("cost", pos->read_time);
+ obj.add("uses_join_buffering", pos->use_join_buffer);
+ if (pos->range_rowid_filter_info)
+ {
+ uint key_no= pos->range_rowid_filter_info->key_no;
+ obj.add("rowid_filter_key",
+ pos->table->table->key_info[key_no].name);
+ }
}
diff --git a/sql/rowid_filter.cc b/sql/rowid_filter.cc
index d6c633aa3e2..1d9363693cb 100644
--- a/sql/rowid_filter.cc
+++ b/sql/rowid_filter.cc
@@ -20,6 +20,7 @@
#include "opt_range.h"
#include "rowid_filter.h"
#include "sql_select.h"
+#include "opt_trace.h"
inline
@@ -403,9 +404,37 @@ void TABLE::init_cost_info_for_usable_range_rowid_filters(THD *thd)
}
prune_range_rowid_filters();
+
+ if (unlikely(thd->trace_started()))
+ trace_range_rowid_filters(thd);
}
+void TABLE::trace_range_rowid_filters(THD *thd) const
+{
+ if (!range_rowid_filter_cost_info_elems)
+ return;
+
+ Range_rowid_filter_cost_info **p= range_rowid_filter_cost_info_ptr;
+ Range_rowid_filter_cost_info **end= p + range_rowid_filter_cost_info_elems;
+
+ Json_writer_object js_obj(thd);
+ js_obj.add_table_name(this);
+ Json_writer_array js_arr(thd, "rowid_filters");
+
+ for (; p < end; p++)
+ (*p)->trace_info(thd);
+}
+
+
+void Range_rowid_filter_cost_info::trace_info(THD *thd)
+{
+ Json_writer_object js_obj(thd);
+ js_obj.add("key", table->key_info[key_no].name);
+ js_obj.add("build_cost", b);
+ js_obj.add("rows", est_elements);
+}
+
/**
@brief
Choose the best range filter for the given access of the table
diff --git a/sql/rowid_filter.h b/sql/rowid_filter.h
index a9930dcbca8..467b6884ca6 100644
--- a/sql/rowid_filter.h
+++ b/sql/rowid_filter.h
@@ -452,6 +452,8 @@ public:
double get_a() { return a; }
+ void trace_info(THD *thd);
+
friend
void TABLE::prune_range_rowid_filters();
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index ce2ee1b5aa2..ef8ef5114a8 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -6751,9 +6751,9 @@ static void release_log_entries(partition_info *part_info)
alter_partition_lock_handling()
lpt Struct carrying parameters
RETURN VALUES
- NONE
+ true on error
*/
-static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
+static bool alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
{
THD *thd= lpt->thd;
@@ -6767,23 +6767,9 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
lpt->table= 0;
lpt->table_list->table= 0;
if (thd->locked_tables_mode)
- {
- Diagnostics_area *stmt_da= NULL;
- Diagnostics_area tmp_stmt_da(true);
-
- if (unlikely(thd->is_error()))
- {
- /* reopen might fail if we have a previous error, use a temporary da. */
- stmt_da= thd->get_stmt_da();
- thd->set_stmt_da(&tmp_stmt_da);
- }
+ return thd->locked_tables_list.reopen_tables(thd, false);
- if (unlikely(thd->locked_tables_list.reopen_tables(thd, false)))
- sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
-
- if (stmt_da)
- thd->set_stmt_da(stmt_da);
- }
+ return false;
}
@@ -6984,6 +6970,8 @@ err_exclusive_lock:
thd->set_stmt_da(&tmp_stmt_da);
}
+ /* NB: error status is not needed here, the statement fails with
+ the original error. */
if (unlikely(thd->locked_tables_list.reopen_tables(thd, false)))
sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE");
@@ -7207,13 +7195,14 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_ERROR("fail_drop_partition_8") ||
(write_log_completed(lpt, FALSE), FALSE) ||
ERROR_INJECT_CRASH("crash_drop_partition_9") ||
- ERROR_INJECT_ERROR("fail_drop_partition_9") ||
- (alter_partition_lock_handling(lpt), FALSE))
+ ERROR_INJECT_ERROR("fail_drop_partition_9"))
{
handle_alter_part_error(lpt, action_completed, TRUE, frm_install,
close_table_on_failure);
goto err;
}
+ if (alter_partition_lock_handling(lpt))
+ goto err;
}
else if ((alter_info->partition_flags & ALTER_PARTITION_ADD) &&
(part_info->part_type == RANGE_PARTITION ||
@@ -7284,13 +7273,14 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_ERROR("fail_add_partition_9") ||
(write_log_completed(lpt, FALSE), FALSE) ||
ERROR_INJECT_CRASH("crash_add_partition_10") ||
- ERROR_INJECT_ERROR("fail_add_partition_10") ||
- (alter_partition_lock_handling(lpt), FALSE))
+ ERROR_INJECT_ERROR("fail_add_partition_10"))
{
handle_alter_part_error(lpt, action_completed, FALSE, frm_install,
close_table_on_failure);
goto err;
}
+ if (alter_partition_lock_handling(lpt))
+ goto err;
}
else
{
@@ -7389,13 +7379,14 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_ERROR("fail_change_partition_11") ||
(write_log_completed(lpt, FALSE), FALSE) ||
ERROR_INJECT_CRASH("crash_change_partition_12") ||
- ERROR_INJECT_ERROR("fail_change_partition_12") ||
- (alter_partition_lock_handling(lpt), FALSE))
+ ERROR_INJECT_ERROR("fail_change_partition_12"))
{
handle_alter_part_error(lpt, action_completed, FALSE, frm_install,
close_table_on_failure);
goto err;
}
+ if (alter_partition_lock_handling(lpt))
+ goto err;
}
downgrade_mdl_if_lock_tables_mode(thd, mdl_ticket, MDL_SHARED_NO_READ_WRITE);
/*
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9f4ddb4f357..129dae9eedb 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7818,6 +7818,8 @@ best_access_path(JOIN *join,
filter->get_cmp_gain(rows);
tmp-= filter->get_adjusted_gain(rows) - filter->get_cmp_gain(rows);
DBUG_ASSERT(tmp >= 0);
+ trace_access_idx.add("rowid_filter_key",
+ s->table->key_info[filter->key_no].name);
}
}
trace_access_idx.add("rows", records).add("cost", tmp);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 58ca31bf933..6ab224abee5 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4383,6 +4383,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
const Virtual_column_info *dup_check;
while ((dup_check= dup_it++) && dup_check != check)
{
+ if (!dup_check->name.length || dup_check->automatic_name)
+ continue;
if (!lex_string_cmp(system_charset_info,
&check->name, &dup_check->name))
{
@@ -8703,8 +8705,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
key_part_length= 0; // Use whole field
}
key_part_length /= kfield->charset()->mbmaxlen;
- key_parts.push_back(new Key_part_spec(&cfield->field_name,
- key_part_length),
+ key_parts.push_back(new (thd->mem_root) Key_part_spec(
+ &cfield->field_name, key_part_length),
thd->mem_root);
}
if (table->s->tmp_table == NO_TMP_TABLE)
@@ -8770,7 +8772,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
tmp_name.str= key_name;
tmp_name.length= strlen(key_name);
/* We dont need LONG_UNIQUE_HASH_FIELD flag because it will be autogenerated */
- key= new Key(key_type, &tmp_name, &key_create_info,
+ key= new (thd->mem_root) Key(key_type, &tmp_name, &key_create_info,
MY_TEST(key_info->flags & HA_GENERATED_KEY),
&key_parts, key_info->option_list, DDL_options());
key->without_overlaps= key_info->without_overlaps;
@@ -8850,26 +8852,37 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
}
+ // NB: `check` is TABLE resident, we must keep it intact.
+ if (keep)
+ {
+ check= check->clone(thd);
+ if (!check)
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ goto err;
+ }
+ }
+
if (share->period.constr_name.streq(check->name.str))
{
- if (!drop_period && !keep)
+ if (drop_period)
+ {
+ keep= false;
+ }
+ else if(!keep)
{
my_error(ER_PERIOD_CONSTRAINT_DROP, MYF(0), check->name.str,
share->period.name.str);
goto err;
}
- keep= keep && !drop_period;
-
- DBUG_ASSERT(create_info->period_info.constr == NULL || drop_period);
-
- if (keep)
+ else
{
- Item *expr_copy= check->expr->get_copy(thd);
- check= new Virtual_column_info();
- check->expr= expr_copy;
+ DBUG_ASSERT(create_info->period_info.constr == NULL);
create_info->period_info.constr= check;
+ create_info->period_info.constr->automatic_name= true;
}
}
+
/* see if the constraint depends on *only* on dropped fields */
if (keep && dropped_fields)
{
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index c3ade4288d2..2ca03620b17 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -463,6 +463,7 @@ int mysql_update(THD *thd,
my_error(ER_NOT_CONSTANT_EXPRESSION, MYF(0), "FOR PORTION OF");
DBUG_RETURN(true);
}
+ table->no_cache= true;
}
old_covering_keys= table->covering_keys; // Keys used in WHERE
diff --git a/sql/table.h b/sql/table.h
index ce8f204f3ac..ddd33142fd7 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1591,6 +1591,7 @@ public:
void init_cost_info_for_usable_range_rowid_filters(THD *thd);
void prune_range_rowid_filters();
+ void trace_range_rowid_filters(THD *thd) const;
Range_rowid_filter_cost_info *
best_range_rowid_filter_for_partial_join(uint access_key_no,
double records,
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 79403ff339d..6860d2c6347 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -57,6 +57,13 @@ static bool make_empty_rec(THD *, uchar *, uint, List<Create_field> &, uint,
*/
static uchar *extra2_write_len(uchar *pos, size_t len)
{
+ /* TODO: should be
+ if (len > 0 && len <= 255)
+ *pos++= (uchar)len;
+ ...
+ because extra2_read_len() uses 0 for 2-byte lengths.
+ extra2_str_size() must be fixed too.
+ */
if (len <= 255)
*pos++= (uchar)len;
else
diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc
index d73b9cb09ce..992883aa797 100644
--- a/sql/wsrep_high_priority_service.cc
+++ b/sql/wsrep_high_priority_service.cc
@@ -478,11 +478,15 @@ Wsrep_applier_service::Wsrep_applier_service(THD* thd)
thd->wsrep_cs().open(wsrep::client_id(thd->thread_id));
thd->wsrep_cs().before_command();
thd->wsrep_cs().debug_log_level(wsrep_debug);
-
+ if (!thd->slave_thread)
+ thd->system_thread_info.rpl_sql_info=
+ new rpl_sql_thread_info(thd->wsrep_rgi->rli->mi->rpl_filter);
}
Wsrep_applier_service::~Wsrep_applier_service()
{
+ if (!m_thd->slave_thread)
+ delete m_thd->system_thread_info.rpl_sql_info;
m_thd->wsrep_cs().after_command_before_result();
m_thd->wsrep_cs().after_command_after_result();
m_thd->wsrep_cs().close();
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index b605ff0496d..94d01b273c5 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -53,11 +53,6 @@ static void wsrep_replication_process(THD *thd,
Wsrep_applier_service applier_service(thd);
- /* thd->system_thread_info.rpl_sql_info isn't initialized. */
- if (!thd->slave_thread)
- thd->system_thread_info.rpl_sql_info=
- new rpl_sql_thread_info(thd->wsrep_rgi->rli->mi->rpl_filter);
-
WSREP_INFO("Starting applier thread %llu", thd->thread_id);
enum wsrep::provider::status
ret= Wsrep_server_state::get_provider().run_applier(&applier_service);
@@ -68,8 +63,6 @@ static void wsrep_replication_process(THD *thd,
mysql_cond_broadcast(&COND_wsrep_slave_threads);
mysql_mutex_unlock(&LOCK_wsrep_slave_threads);
- if (!thd->slave_thread)
- delete thd->system_thread_info.rpl_sql_info;
delete thd->wsrep_rgi->rli->mi;
delete thd->wsrep_rgi->rli;