summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-04-16 12:12:26 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-04-16 12:12:26 +0300
commitaf912664989e0c3ee9cdb6caf8ec439029e7405c (patch)
tree9ab694ec5d18e0ab998eb4f52ee86129e5fbd3ae /sql
parent5679a2b6b342abc9d80bcf784a1a35f240be9d87 (diff)
parent6577a7a8f20538df80b851698e21095311aae190 (diff)
downloadmariadb-git-af912664989e0c3ee9cdb6caf8ec439029e7405c.tar.gz
Merge 10.3 into 10.4
In main.index_merge_myisam we remove the test that was added in commit a2d24def8cc42d27c72d833abfb39ef24a2b96ba because it duplicates the test case that was added in commit 5af12e463549e4bbc2ce6ab720d78937d5e5db4e.
Diffstat (limited to 'sql')
-rw-r--r--sql/field_comp.cc22
-rw-r--r--sql/handler.cc32
-rw-r--r--sql/handler.h13
-rw-r--r--sql/opt_range.cc33
-rw-r--r--sql/sql_lex.cc10
-rw-r--r--sql/sql_partition.cc18
-rw-r--r--sql/sql_string.h2
-rw-r--r--sql/sql_table.cc25
-rw-r--r--sql/sql_update.cc6
-rw-r--r--sql/sys_vars.cc2
10 files changed, 104 insertions, 59 deletions
diff --git a/sql/field_comp.cc b/sql/field_comp.cc
index eb4ae42aa4d..ab97c8ccf08 100644
--- a/sql/field_comp.cc
+++ b/sql/field_comp.cc
@@ -67,10 +67,12 @@ static uint compress_zlib(THD *thd, char *to, const char *from, uint length)
stream.zfree= 0;
stream.opaque= 0;
- if (deflateInit2(&stream, level, Z_DEFLATED, wbits, 8, strategy) == Z_OK &&
- deflate(&stream, Z_FINISH) == Z_STREAM_END &&
- deflateEnd(&stream) == Z_OK)
- return (uint) (stream.next_out - (Bytef*) to);
+ if (deflateInit2(&stream, level, Z_DEFLATED, wbits, 8, strategy) == Z_OK)
+ {
+ int res= deflate(&stream, Z_FINISH);
+ if (deflateEnd(&stream) == Z_OK && res == Z_STREAM_END)
+ return (uint) (stream.next_out - (Bytef*) to);
+ }
}
return 0;
}
@@ -117,12 +119,14 @@ static int uncompress_zlib(String *to, const uchar *from, uint from_length,
stream.zfree= 0;
stream.opaque= 0;
- if (inflateInit2(&stream, wbits) == Z_OK &&
- inflate(&stream, Z_FINISH) == Z_STREAM_END &&
- inflateEnd(&stream) == Z_OK)
+ if (inflateInit2(&stream, wbits) == Z_OK)
{
- to->length(stream.total_out);
- return 0;
+ int res= inflate(&stream, Z_FINISH);
+ if (inflateEnd(&stream) == Z_OK && res == Z_STREAM_END)
+ {
+ to->length(stream.total_out);
+ return 0;
+ }
}
my_error(ER_ZLIB_Z_DATA_ERROR, MYF(0));
return 1;
diff --git a/sql/handler.cc b/sql/handler.cc
index 178830a87b1..2f64ff923e7 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1,5 +1,5 @@
/* 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
@@ -1994,29 +1994,33 @@ int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
#ifndef DBUG_OFF
-/**
- @note
- This does not need to be multi-byte safe or anything
-*/
-static char* xid_to_str(char *buf, XID *xid)
+/** Converts XID to string.
+
+@param[out] buf output buffer
+@param[in] xid XID to convert
+
+@return pointer to converted string
+
+@note This does not need to be multi-byte safe or anything */
+char *xid_to_str(char *buf, const XID &xid)
{
int i;
char *s=buf;
*s++='\'';
- for (i=0; i < xid->gtrid_length+xid->bqual_length; i++)
+ for (i= 0; i < xid.gtrid_length + xid.bqual_length; i++)
{
- uchar c=(uchar)xid->data[i];
+ uchar c= (uchar) xid.data[i];
/* is_next_dig is set if next character is a number */
bool is_next_dig= FALSE;
if (i < XIDDATASIZE)
{
- char ch= xid->data[i+1];
+ char ch= xid.data[i + 1];
is_next_dig= (ch >= '0' && ch <='9');
}
- if (i == xid->gtrid_length)
+ if (i == xid.gtrid_length)
{
*s++='\'';
- if (xid->bqual_length)
+ if (xid.bqual_length)
{
*s++='.';
*s++='\'';
@@ -2139,7 +2143,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
{
DBUG_EXECUTE("info",{
char buf[XIDDATASIZE*4+6];
- _db_doprnt_("ignore xid %s", xid_to_str(buf, info->list+i));
+ _db_doprnt_("ignore xid %s", xid_to_str(buf, info->list[i]));
});
xid_cache_insert(info->list + i);
info->found_foreign_xids++;
@@ -2166,7 +2170,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
{
DBUG_EXECUTE("info",{
char buf[XIDDATASIZE*4+6];
- _db_doprnt_("commit xid %s", xid_to_str(buf, info->list+i));
+ _db_doprnt_("commit xid %s", xid_to_str(buf, info->list[i]));
});
}
}
@@ -2177,7 +2181,7 @@ static my_bool xarecover_handlerton(THD *unused, plugin_ref plugin,
{
DBUG_EXECUTE("info",{
char buf[XIDDATASIZE*4+6];
- _db_doprnt_("rollback xid %s", xid_to_str(buf, info->list+i));
+ _db_doprnt_("rollback xid %s", xid_to_str(buf, info->list[i]));
});
}
}
diff --git a/sql/handler.h b/sql/handler.h
index e9b52b16aa8..0c9d60b7c90 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -2,7 +2,7 @@
#define HANDLER_INCLUDED
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2019, MariaDB
+ Copyright (c) 2009, 2020, MariaDB
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -5083,4 +5083,15 @@ void print_keydup_error(TABLE *table, KEY *key, myf errflag);
int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info);
int del_global_table_stat(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table);
+#ifndef DBUG_OFF
+/** Converts XID to string.
+
+@param[out] buf output buffer
+@param[in] xid XID to convert
+
+@return pointer to converted string
+
+@note This does not need to be multi-byte safe or anything */
+char *xid_to_str(char *buf, const XID &xid);
+#endif // !DBUG_OFF
#endif /* HANDLER_INCLUDED */
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 0528dfcadc6..899d1fc9782 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2019, MariaDB
+ Copyright (c) 2008, 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
@@ -357,7 +357,8 @@ QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
bool update_tbl_stats,
- double read_time);
+ double read_time,
+ bool ror_scans_required);
static
TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree,
double read_time);
@@ -2637,7 +2638,7 @@ static int fill_used_fields_bitmap(PARAM *param)
force_quick_range is really needed.
RETURN
- -1 if impossible select (i.e. certainly no rows will be selected)
+ -1 if error or impossible select (i.e. certainly no rows will be selected)
0 if can't use quick_select
1 if found usable ranges and quick select has been successfully created.
*/
@@ -2737,7 +2738,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
{
thd->no_errors=0;
free_root(&alloc,MYF(0)); // Return memory & allocator
- DBUG_RETURN(0); // Can't use range
+ DBUG_RETURN(-1); // Error
}
key_parts= param.key_parts;
@@ -2805,7 +2806,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
{
thd->no_errors=0;
free_root(&alloc,MYF(0)); // Return memory & allocator
- DBUG_RETURN(0); // Can't use range
+ DBUG_RETURN(-1); // Error
}
thd->mem_root= &alloc;
@@ -2861,6 +2862,13 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
tree= NULL;
}
}
+ else if (thd->is_error())
+ {
+ thd->no_errors=0;
+ thd->mem_root= param.old_root;
+ free_root(&alloc, MYF(0));
+ DBUG_RETURN(-1);
+ }
}
/*
@@ -2910,7 +2918,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
/* Get best 'range' plan and prepare data for making other plans */
if ((range_trp= get_key_scans_params(&param, tree,
only_single_index_range_scan, TRUE,
- best_read_time)))
+ best_read_time, FALSE)))
{
best_trp= range_trp;
best_read_time= best_trp->read_cost;
@@ -5078,7 +5086,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
"tree in SEL_IMERGE"););
Json_writer_object trace_idx(thd);
- if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, read_time)))
+ if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE,
+ read_time, TRUE)))
{
/*
One of index scans in this index_merge is more expensive than entire
@@ -5440,7 +5449,7 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
index merge retrievals are not well calibrated
*/
trp= get_key_scans_params(param, *imerge->trees, FALSE, TRUE,
- read_time);
+ read_time, TRUE);
}
DBUG_RETURN(trp);
@@ -7324,6 +7333,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
index_read_must_be_used if TRUE, assume 'index only' option will be set
(except for clustered PK indexes)
read_time don't create read plans with cost > read_time.
+ ror_scans_required set to TRUE for index merge
RETURN
Best range read plan
NULL if no plan found or error occurred
@@ -7332,7 +7342,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
bool update_tbl_stats,
- double read_time)
+ double read_time,
+ bool ror_scans_required)
{
uint idx, UNINIT_VAR(best_idx);
SEL_ARG *key_to_read= NULL;
@@ -7386,7 +7397,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
found_records= check_quick_select(param, idx, read_index_only, key,
update_tbl_stats, &mrr_flags,
&buf_size, &cost, &is_ror_scan);
- if (!is_ror_scan &&
+ if (ror_scans_required && !is_ror_scan &&
!optimizer_flag(param->thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))
continue;
@@ -9773,7 +9784,7 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
if (key2->next_key_part)
{
key1->use_count--; // Incremented in and_all_keys
- return and_all_keys(param, key1, key2, clone_flag);
+ return and_all_keys(param, key1, key2->next_key_part, clone_flag);
}
key2->use_count--; // Key2 doesn't have a tree
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 39e8f42b409..ebc73e54674 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -7460,7 +7460,8 @@ Item *LEX::create_item_limit(THD *thd, const Lex_ident_cli_st *ca)
if (unlikely(!(item= new (thd->mem_root)
Item_splocal(thd, rh, &sa,
spv->offset, spv->type_handler(),
- pos.pos(), pos.length()))))
+ clone_spec_offset ? 0 : pos.pos(),
+ clone_spec_offset ? 0 : pos.length()))))
return NULL;
#ifdef DBUG_ASSERT_EXISTS
item->m_sp= sphead;
@@ -7559,14 +7560,15 @@ Item *LEX::create_item_ident_sp(THD *thd, Lex_ident_sys_st *name,
}
Query_fragment pos(thd, sphead, start, end);
+ uint f_pos= clone_spec_offset ? 0 : pos.pos();
+ uint f_length= clone_spec_offset ? 0 : pos.length();
Item_splocal *splocal= spv->field_def.is_column_type_ref() ?
new (thd->mem_root) Item_splocal_with_delayed_data_type(thd, rh, name,
spv->offset,
- pos.pos(),
- pos.length()) :
+ f_pos, f_length) :
new (thd->mem_root) Item_splocal(thd, rh, name,
spv->offset, spv->type_handler(),
- pos.pos(), pos.length());
+ f_pos, f_length);
if (unlikely(splocal == NULL))
return NULL;
#ifdef DBUG_ASSERT_EXISTS
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 82a77d3638f..e4015baa40c 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -6012,6 +6012,24 @@ the generated partition syntax in a correct manner.
*partition_changed= true;
}
}
+
+ // 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_string.h b/sql/sql_string.h
index 7d7d9f08748..3050a5ef464 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -79,7 +79,7 @@ public:
Well_formed_prefix(CHARSET_INFO *cs, const char *str, size_t length)
:Well_formed_prefix_status(cs, str, str + length, length), m_str(str)
{ }
- Well_formed_prefix(CHARSET_INFO *cs, LEX_STRING str, size_t nchars)
+ Well_formed_prefix(CHARSET_INFO *cs, LEX_CSTRING str, size_t nchars)
:Well_formed_prefix_status(cs, str.str, str.str + str.length, nchars),
m_str(str.str)
{ }
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 7c4a4956a93..695d8ee729c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4397,11 +4397,8 @@ bool validate_comment_length(THD *thd, LEX_CSTRING *comment, size_t max_len,
if (comment->length == 0)
DBUG_RETURN(false);
- if (max_len > comment->length)
- max_len= comment->length;
-
size_t tmp_len=
- Well_formed_prefix(system_charset_info, comment->str, max_len).length();
+ Well_formed_prefix(system_charset_info, *comment, max_len).length();
if (tmp_len < comment->length)
{
if (thd->is_strict_mode())
@@ -10586,7 +10583,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
bool make_versioned= !from->versioned() && to->versioned();
bool make_unversioned= from->versioned() && !to->versioned();
bool keep_versioned= from->versioned() && to->versioned();
- bool drop_history= false; // XXX
Field *to_row_start= NULL, *to_row_end= NULL, *from_row_end= NULL;
MYSQL_TIME query_start;
DBUG_ENTER("copy_data_between_tables");
@@ -10717,10 +10713,6 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
{
from_row_end= from->vers_end_field();
}
- else if (keep_versioned && drop_history)
- {
- from_row_end= from->vers_end_field();
- }
if (from_row_end)
bitmap_set_bit(from->read_set, from_row_end->field_index);
@@ -10757,6 +10749,13 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
error= 1;
break;
}
+
+ if (make_unversioned)
+ {
+ if (!from_row_end->is_max())
+ continue; // Drop history rows.
+ }
+
if (unlikely(++thd->progress.counter >= time_to_report_progress))
{
time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10;
@@ -10776,20 +10775,12 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
copy_ptr->do_copy(copy_ptr);
}
- if (drop_history && from_row_end && !from_row_end->is_max())
- continue;
-
if (make_versioned)
{
to_row_start->set_notnull();
to_row_start->store_time(&query_start);
to_row_end->set_max();
}
- else if (make_unversioned)
- {
- if (!from_row_end->is_max())
- continue; // Drop history rows.
- }
prev_insert_id= to->file->next_insert_id;
if (to->default_field)
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 0d2860de19f..2095f99d1ac 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2011, 2016, 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
@@ -2589,6 +2589,9 @@ int multi_update::send_data(List<Item> &not_used_values)
TABLE *tmp_table= tmp_tables[offset];
if (copy_funcs(tmp_table_param[offset].items_to_copy, thd))
DBUG_RETURN(1);
+ /* rowid field is NULL if join tmp table has null row from outer join */
+ if (tmp_table->field[0]->is_null())
+ continue;
/* Store regular updated fields in the row. */
DBUG_ASSERT(1 + unupdated_check_opt_tables.elements ==
tmp_table_param[offset].func_count);
@@ -2786,6 +2789,7 @@ int multi_update::do_updates()
uint field_num= 0;
do
{
+ DBUG_ASSERT(!tmp_table->field[field_num]->is_null());
String rowid;
tmp_table->field[field_num]->val_str(&rowid);
if (unlikely((local_error= tbl->file->ha_rnd_pos(tbl->record[0],
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 1c47f652f4c..2eabec54b6e 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -5814,7 +5814,7 @@ vio_keepalive_opts opt_vio_keepalive;
static Sys_var_int Sys_keepalive_time(
"tcp_keepalive_time",
- "Timeout, in milliseconds, with no activity until the first TCP keep-alive packet is sent."
+ "Timeout, in seconds, with no activity until the first TCP keep-alive packet is sent."
"If set to 0, system dependent default is used.",
AUTO_SET GLOBAL_VAR(opt_vio_keepalive.idle),
CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, INT_MAX32/1000), DEFAULT(0),