diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-04-16 12:12:26 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-04-16 12:12:26 +0300 |
commit | af912664989e0c3ee9cdb6caf8ec439029e7405c (patch) | |
tree | 9ab694ec5d18e0ab998eb4f52ee86129e5fbd3ae /sql | |
parent | 5679a2b6b342abc9d80bcf784a1a35f240be9d87 (diff) | |
parent | 6577a7a8f20538df80b851698e21095311aae190 (diff) | |
download | mariadb-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.cc | 22 | ||||
-rw-r--r-- | sql/handler.cc | 32 | ||||
-rw-r--r-- | sql/handler.h | 13 | ||||
-rw-r--r-- | sql/opt_range.cc | 33 | ||||
-rw-r--r-- | sql/sql_lex.cc | 10 | ||||
-rw-r--r-- | sql/sql_partition.cc | 18 | ||||
-rw-r--r-- | sql/sql_string.h | 2 | ||||
-rw-r--r-- | sql/sql_table.cc | 25 | ||||
-rw-r--r-- | sql/sql_update.cc | 6 | ||||
-rw-r--r-- | sql/sys_vars.cc | 2 |
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(¶m, 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> ¬_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), |