From c91aeb3771cec9475052d8c022a16007322ffccd Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Tue, 23 Jul 2024 15:34:23 +0700 Subject: [PATCH 01/12] MDEV-34634 Types mismatch when cloning items causes debug assertion New runtime diagnostic introduced with MDEV-34490 has detected that `Item_int_with_ref` incorrectly returns an instance of its ancestor class `Item_int`. This commit fixes that. In addition, this commit reverts a part of the diagnostic related to `clone_item()` checks. As it turned out, `clone_item()` is not required to return an object of the same class as the cloned one. For example, look at `Item_param::clone_item()`: it can return objects of `Item_null`, `Item_int`, `Item_string`, etc, depending on the object state. So the runtime type diagnostic is not applicable to `clone_item()` and is disabled with this commit. As the similar diagnostic failures are expected to appear again in the future, this commit introduces a new test file in the main suite: item_types.test, and new test cases may be added to this file Reviewer: Oleksandr Byelkin --- mysql-test/main/item_types.result | 16 +++++++++ mysql-test/main/item_types.test | 15 +++++++++ sql/item.cc | 24 ++++++------- sql/item.h | 56 ++++++++++++++----------------- sql/sql_select.cc | 4 +-- 5 files changed, 71 insertions(+), 44 deletions(-) create mode 100644 mysql-test/main/item_types.result create mode 100644 mysql-test/main/item_types.test diff --git a/mysql-test/main/item_types.result b/mysql-test/main/item_types.result new file mode 100644 index 00000000000..865b4f612ae --- /dev/null +++ b/mysql-test/main/item_types.result @@ -0,0 +1,16 @@ +# +# MDEV-34634 Types mismatch when cloning items causes debug assertion +# +CREATE TABLE t1 (a DATETIME); +SET optimizer_switch='derived_merge=off'; +SELECT * FROM (SELECT * FROM t1) AS t1 WHERE a=''; +a +Warnings: +Warning 1292 Truncated incorrect datetime value: '' +DROP TABLE t1; +CREATE TABLE t1 (c YEAR); +CREATE TABLE t2 (c INT); +SELECT * FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.c<=>5; +c c +DROP TABLE t1, t2; +SET optimizer_switch=default; diff --git a/mysql-test/main/item_types.test b/mysql-test/main/item_types.test new file mode 100644 index 00000000000..f43bfe1a8ac --- /dev/null +++ b/mysql-test/main/item_types.test @@ -0,0 +1,15 @@ +--echo # +--echo # MDEV-34634 Types mismatch when cloning items causes debug assertion +--echo # + +CREATE TABLE t1 (a DATETIME); +SET optimizer_switch='derived_merge=off'; +SELECT * FROM (SELECT * FROM t1) AS t1 WHERE a=''; +DROP TABLE t1; + +CREATE TABLE t1 (c YEAR); +CREATE TABLE t2 (c INT); +SELECT * FROM t1 JOIN t2 ON t1.c=t2.c WHERE t1.c<=>5; +DROP TABLE t1, t2; + +SET optimizer_switch=default; diff --git a/sql/item.cc b/sql/item.cc index 9ba00944c85..35d7eaefd01 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3847,7 +3847,7 @@ void Item_decimal::set_decimal_value(my_decimal *value_par) } -Item *Item_decimal::do_clone_const_item(THD *thd) const +Item *Item_decimal::clone_item(THD *thd) const { return new (thd->mem_root) Item_decimal(thd, name.str, &decimal_value, decimals, max_length); @@ -3868,7 +3868,7 @@ my_decimal *Item_float::val_decimal(my_decimal *decimal_value) } -Item *Item_float::do_clone_const_item(THD *thd) const +Item *Item_float::clone_item(THD *thd) const { return new (thd->mem_root) Item_float(thd, name.str, value, decimals, max_length); @@ -4032,7 +4032,7 @@ Item *Item_null::safe_charset_converter(THD *thd, CHARSET_INFO *tocs) return this; } -Item *Item_null::do_clone_const_item(THD *thd) const +Item *Item_null::clone_item(THD *thd) const { return new (thd->mem_root) Item_null(thd, name.str); } @@ -4873,7 +4873,7 @@ Item *Item_param::value_clone_item(THD *thd) const /* see comments in the header file */ Item * -Item_param::do_clone_const_item(THD *thd) const +Item_param::clone_item(THD *thd) const { // There's no "default". See comments in Item_param::save_in_field(). switch (state) { @@ -6953,7 +6953,7 @@ int Item_string::save_in_field(Field *field, bool no_conversions) } -Item *Item_string::do_clone_const_item(THD *thd) const +Item *Item_string::clone_item(THD *thd) const { LEX_CSTRING val; str_value.get_value(&val); @@ -7017,7 +7017,7 @@ int Item_int::save_in_field(Field *field, bool no_conversions) } -Item *Item_int::do_clone_const_item(THD *thd) const +Item *Item_int::clone_item(THD *thd) const { return new (thd->mem_root) Item_int(thd, name.str, value, max_length, unsigned_flag); } @@ -7046,7 +7046,7 @@ int Item_decimal::save_in_field(Field *field, bool no_conversions) } -Item *Item_int_with_ref::do_clone_const_item(THD *thd) const +Item *Item_int_with_ref::clone_item(THD *thd) const { DBUG_ASSERT(ref->const_item()); /* @@ -7142,7 +7142,7 @@ Item *Item_uint::neg(THD *thd) } -Item *Item_uint::do_clone_const_item(THD *thd) const +Item *Item_uint::clone_item(THD *thd) const { return new (thd->mem_root) Item_uint(thd, name.str, value, max_length); } @@ -7380,7 +7380,7 @@ void Item_date_literal::print(String *str, enum_query_type query_type) } -Item *Item_date_literal::do_clone_const_item(THD *thd) const +Item *Item_date_literal::clone_item(THD *thd) const { return new (thd->mem_root) Item_date_literal(thd, &cached_time); } @@ -7405,7 +7405,7 @@ void Item_datetime_literal::print(String *str, enum_query_type query_type) } -Item *Item_datetime_literal::do_clone_const_item(THD *thd) const +Item *Item_datetime_literal::clone_item(THD *thd) const { return new (thd->mem_root) Item_datetime_literal(thd, &cached_time, decimals); } @@ -7430,7 +7430,7 @@ void Item_time_literal::print(String *str, enum_query_type query_type) } -Item *Item_time_literal::do_clone_const_item(THD *thd) const +Item *Item_time_literal::clone_item(THD *thd) const { return new (thd->mem_root) Item_time_literal(thd, &cached_time, decimals); } @@ -10389,7 +10389,7 @@ void Item_cache_temporal::store_packed(longlong val_arg, Item *example_arg) } -Item *Item_cache_temporal::do_clone_const_item(THD *thd) const +Item *Item_cache_temporal::clone_item(THD *thd) const { Item_cache *tmp= type_handler()->Item_get_cache(thd, this); Item_cache_temporal *item= static_cast(tmp); diff --git a/sql/item.h b/sql/item.h index 19f95c5875f..b531647e8bf 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1698,21 +1698,17 @@ public: } /* - Clones the constant item + Clones the constant item (not necessary returning the same item type) Return value: - pointer to a clone of the Item - - nullptr if the item is not clonable */ - Item *clone_const_item(THD *thd) const - { - Item *clone= do_clone_const_item(thd); - if (clone) - { - // Make sure the clone is of same type as this item - DBUG_ASSERT(typeid(*clone) == typeid(*this)); - } - return clone; - } + - nullptr if the item is not clonable + + Note: the clone may have item type different from this + (i.e., instance of another basic constant class may be returned). + For real clones look at build_clone()/get_copy() methods + */ + virtual Item *clone_item(THD *thd) const { return nullptr; } virtual cond_result eq_cmp_result() const { return COND_OK; } inline uint float_length(uint decimals_par) const @@ -2588,12 +2584,6 @@ protected: deep copies (clones) of the item where possible */ virtual Item* do_build_clone(THD *thd) const = 0; - - /* - Service function for public method clone_const_item(). See comments for - clone_const_item() above - */ - virtual Item *do_clone_const_item(THD *thd) const { return nullptr; } }; MEM_ROOT *get_thd_memroot(THD *thd); @@ -3820,7 +3810,7 @@ public: const Type_handler *type_handler() const override { return &type_handler_null; } bool basic_const_item() const override { return true; } - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; bool const_is_null() const override { return true; } bool is_null() override { return true; } @@ -4270,7 +4260,7 @@ public: basic_const_item returned TRUE. */ Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override; - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; void set_param_type_and_swap_value(Item_param *from); Rewritable_query_parameter *get_rewritable_query_parameter() override @@ -4369,7 +4359,7 @@ public: String *val_str(String*) override; int save_in_field(Field *field, bool no_conversions) override; bool is_order_clause_position() const override { return true; } - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; void print(String *str, enum_query_type query_type) override; Item *neg(THD *thd) override; uint decimal_precision() const override @@ -4417,7 +4407,7 @@ public: Item_uint(THD *thd, ulonglong i): Item_int(thd, i, 10) {} Item_uint(THD *thd, const char *str_arg, longlong i, uint length); double val_real() override { return ulonglong2double((ulonglong)value); } - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; Item *neg(THD *thd) override; uint decimal_precision() const override { return max_length; } Item *do_get_copy(THD *thd) const override @@ -4468,7 +4458,7 @@ public: const my_decimal *const_ptr_my_decimal() const override { return &decimal_value; } int save_in_field(Field *field, bool no_conversions) override; - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; void print(String *str, enum_query_type query_type) override { decimal_value.to_string(&str_value); @@ -4521,7 +4511,7 @@ public: } String *val_str(String*) override; my_decimal *val_decimal(my_decimal *) override; - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; Item *neg(THD *thd) override; void print(String *str, enum_query_type query_type) override; Item *do_get_copy(THD *thd) const override @@ -4644,7 +4634,7 @@ public: int save_in_field(Field *field, bool no_conversions) override; const Type_handler *type_handler() const override { return &type_handler_varchar; } - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs) override { return const_charset_converter(thd, tocs, true); @@ -5067,7 +5057,7 @@ public: { return cached_time.get_mysql_time(); } - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; longlong val_int() override { return update_null() ? 0 : cached_time.to_longlong(); @@ -5117,7 +5107,7 @@ public: { return cached_time.get_mysql_time(); } - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; longlong val_int() override { return cached_time.to_longlong(); } double val_real() override { return cached_time.to_double(); } String *val_str(String *to) override @@ -5168,7 +5158,7 @@ public: { return cached_time.get_mysql_time(); } - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; longlong val_int() override { return update_null() ? 0 : cached_time.to_longlong(); @@ -5256,6 +5246,9 @@ public: cached_time.copy_to_mysql_time(ltime); return (null_value= false); } + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; @@ -6299,8 +6292,11 @@ public: { return ref->save_in_field(field, no_conversions); } - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; Item *real_item() override { return ref; } + Item *do_get_copy(THD *thd) const override + { return get_item_copy(thd, this); } + Item *do_build_clone(THD *thd) const override { return get_copy(thd); } }; #ifdef MYSQL_SERVER @@ -7209,7 +7205,7 @@ public: is a constant and need not be optimized further. Important when storing packed datetime values. */ - Item *do_clone_const_item(THD *thd) const override; + Item *clone_item(THD *thd) const override; Item *convert_to_basic_const_item(THD *thd) override; virtual Item *make_literal(THD *) =0; }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 92f0a8fa578..b86ffed8619 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -16632,7 +16632,7 @@ change_cond_ref_to_const(THD *thd, I_List *save_list, if (can_change_cond_ref_to_const(func, right_item, left_item, field_value_owner, field, value)) { - Item *tmp=value->clone_const_item(thd); + Item *tmp=value->clone_item(thd); if (tmp) { tmp->collation.set(right_item->collation); @@ -16662,7 +16662,7 @@ change_cond_ref_to_const(THD *thd, I_List *save_list, else if (can_change_cond_ref_to_const(func, left_item, right_item, field_value_owner, field, value)) { - Item *tmp= value->clone_const_item(thd); + Item *tmp= value->clone_item(thd); if (tmp) { tmp->collation.set(left_item->collation); From 26f31bdd5261890e705f9bfebf08dec0d552e47e Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 24 Jul 2024 16:41:29 +0200 Subject: [PATCH 02/12] The test should be not for AddressSanitizer used becouse stack check tests and this check switched off --- ...ug_nonembedded.result => json_debug_nonembedded_noasan.result} | 0 ..._debug_nonembedded.test => json_debug_nonembedded_noasan.test} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename mysql-test/main/{json_debug_nonembedded.result => json_debug_nonembedded_noasan.result} (100%) rename mysql-test/main/{json_debug_nonembedded.test => json_debug_nonembedded_noasan.test} (100%) diff --git a/mysql-test/main/json_debug_nonembedded.result b/mysql-test/main/json_debug_nonembedded_noasan.result similarity index 100% rename from mysql-test/main/json_debug_nonembedded.result rename to mysql-test/main/json_debug_nonembedded_noasan.result diff --git a/mysql-test/main/json_debug_nonembedded.test b/mysql-test/main/json_debug_nonembedded_noasan.test similarity index 100% rename from mysql-test/main/json_debug_nonembedded.test rename to mysql-test/main/json_debug_nonembedded_noasan.test From 7788593547c557657d3d081d397cfddb515226df Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Fri, 14 Jun 2024 14:05:48 +1000 Subject: [PATCH 03/12] MDEV-19052 Range-type window frame supports only numeric datatype When there is no bounds on the upper or lower part of the window, it doesn't matter if the type is numeric. It also doesn't matter how many ORDER BY items there are in the query. Reviewers: Sergei Petrunia and Oleg Smirnov --- mysql-test/main/win.result | 60 +++++++++++++++++-- mysql-test/main/win.test | 46 +++++++++++--- .../encryption/r/tempfiles_encrypted.result | 60 +++++++++++++++++-- sql/sql_window.cc | 5 +- 4 files changed, 151 insertions(+), 20 deletions(-) diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 533173797b5..cf51315f612 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -1247,15 +1247,10 @@ insert into t1 values (1,1,'foo'); insert into t1 values (2,2,'bar'); select count(*) over (order by a,b -range between unbounded preceding and current row) as count +range between 1 preceding and current row) as count from t1; ERROR HY000: RANGE-type frame requires ORDER BY clause with single sort key select -count(*) over (order by c -range between unbounded preceding and current row) as count -from t1; -ERROR HY000: Numeric datatype is required for RANGE-type frame -select count(*) over (order by a range between 'abcd' preceding and current row) as count from t1; @@ -1277,6 +1272,59 @@ rows between current row and 3.14 following) as count from t1; ERROR HY000: Integer is required for ROWS-type frame # +# MDEV-19052 Range-type window frame supports only numeric datatype +# +select +count(*) over (order by c +range between unbounded preceding and current row) +from t1; +count(*) over (order by c +range between unbounded preceding and current row) +1 +2 +select +count(*) over (order by c +range between current row and unbounded following) +from t1; +count(*) over (order by c +range between current row and unbounded following) +2 +1 +select +count(*) over (order by c +range between unbounded preceding and unbounded following) +from t1; +count(*) over (order by c +range between unbounded preceding and unbounded following) +2 +2 +create table t2 (a int, b varchar(5)); +insert into t2 values (1,'a'), (2, 'b'), (3, 'c'); +select sum(a) over (order by b range between unbounded preceding and current row) from t2; +sum(a) over (order by b range between unbounded preceding and current row) +1 +3 +6 +insert into t1 values (3,3,'goo'); +insert into t1 values (3,1,'har'); +insert into t1 values (1,4,'har'); +select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) from t1; +a b sum(b) over (order by a, b desc range between unbounded preceding and current row) +1 4 4 +1 1 5 +2 2 7 +3 3 10 +3 1 11 +select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) from t1; +a b sum(b) over (order by a desc, b range between unbounded preceding and current row) +3 1 1 +3 3 4 +2 2 6 +1 1 7 +1 4 11 +drop table t2; +delete from t1 where a >= 3 or b = 4; +# # EXCLUDE clause is parsed but not supported # select diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index fa2034a145d..d8771f158fe 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -784,13 +784,7 @@ insert into t1 values (2,2,'bar'); --error ER_RANGE_FRAME_NEEDS_SIMPLE_ORDERBY select count(*) over (order by a,b - range between unbounded preceding and current row) as count -from t1; - ---error ER_WRONG_TYPE_FOR_RANGE_FRAME -select - count(*) over (order by c - range between unbounded preceding and current row) as count + range between 1 preceding and current row) as count from t1; --error ER_WRONG_TYPE_FOR_RANGE_FRAME @@ -818,6 +812,41 @@ select rows between current row and 3.14 following) as count from t1; +--echo # +--echo # MDEV-19052 Range-type window frame supports only numeric datatype +--echo # + +select + count(*) over (order by c + range between unbounded preceding and current row) +from t1; + +select + count(*) over (order by c + range between current row and unbounded following) +from t1; + +select + count(*) over (order by c + range between unbounded preceding and unbounded following) +from t1; + +create table t2 (a int, b varchar(5)); +insert into t2 values (1,'a'), (2, 'b'), (3, 'c'); + +select sum(a) over (order by b range between unbounded preceding and current row) from t2; + +insert into t1 values (3,3,'goo'); +insert into t1 values (3,1,'har'); +insert into t1 values (1,4,'har'); + +select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) from t1; + +select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) from t1; + +drop table t2; +delete from t1 where a >= 3 or b = 4; + --echo # --echo # EXCLUDE clause is parsed but not supported --echo # @@ -843,6 +872,9 @@ select exclude group) as count from t1; + + + # EXCLUDE NO OTHERS means 'don't exclude anything' select count(*) over (order by a diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index 67347191261..edf7acba24f 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -1253,15 +1253,10 @@ insert into t1 values (1,1,'foo'); insert into t1 values (2,2,'bar'); select count(*) over (order by a,b -range between unbounded preceding and current row) as count +range between 1 preceding and current row) as count from t1; ERROR HY000: RANGE-type frame requires ORDER BY clause with single sort key select -count(*) over (order by c -range between unbounded preceding and current row) as count -from t1; -ERROR HY000: Numeric datatype is required for RANGE-type frame -select count(*) over (order by a range between 'abcd' preceding and current row) as count from t1; @@ -1283,6 +1278,59 @@ rows between current row and 3.14 following) as count from t1; ERROR HY000: Integer is required for ROWS-type frame # +# MDEV-19052 Range-type window frame supports only numeric datatype +# +select +count(*) over (order by c +range between unbounded preceding and current row) +from t1; +count(*) over (order by c +range between unbounded preceding and current row) +1 +2 +select +count(*) over (order by c +range between current row and unbounded following) +from t1; +count(*) over (order by c +range between current row and unbounded following) +2 +1 +select +count(*) over (order by c +range between unbounded preceding and unbounded following) +from t1; +count(*) over (order by c +range between unbounded preceding and unbounded following) +2 +2 +create table t2 (a int, b varchar(5)); +insert into t2 values (1,'a'), (2, 'b'), (3, 'c'); +select sum(a) over (order by b range between unbounded preceding and current row) from t2; +sum(a) over (order by b range between unbounded preceding and current row) +1 +3 +6 +insert into t1 values (3,3,'goo'); +insert into t1 values (3,1,'har'); +insert into t1 values (1,4,'har'); +select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) from t1; +a b sum(b) over (order by a, b desc range between unbounded preceding and current row) +1 4 4 +1 1 5 +2 2 7 +3 3 10 +3 1 11 +select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) from t1; +a b sum(b) over (order by a desc, b range between unbounded preceding and current row) +3 1 1 +3 3 4 +2 2 6 +1 1 7 +1 4 11 +drop table t2; +delete from t1 where a >= 3 or b = 4; +# # EXCLUDE clause is parsed but not supported # select diff --git a/sql/sql_window.cc b/sql/sql_window.cc index 2be6059f2a1..fd8e188a76b 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -262,9 +262,12 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, For "win_func() OVER (ORDER BY order_list RANGE BETWEEN ...)", - ORDER BY order_list must not be ommitted - the list must have a single element. + But it really only matters if the frame is bounded. */ if (win_spec->window_frame && - win_spec->window_frame->units == Window_frame::UNITS_RANGE) + win_spec->window_frame->units == Window_frame::UNITS_RANGE && + !(win_spec->window_frame->top_bound->is_unbounded() && + win_spec->window_frame->bottom_bound->is_unbounded())) { if (win_spec->order_list->elements != 1) { From 0939bfc093ef8c1ae553f5d2bdbdf56ced97d149 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Sat, 27 Jul 2024 12:52:51 +1000 Subject: [PATCH 04/12] MDEV-19052 main.win postfix --view-protocol compat Correct compatibility with view-protocol. Thanks Lena Startseva --- mysql-test/main/win.result | 27 +++++++++---------- mysql-test/main/win.test | 12 ++++----- .../encryption/r/tempfiles_encrypted.result | 27 +++++++++---------- 3 files changed, 30 insertions(+), 36 deletions(-) diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index cf51315f612..f3b719d0a18 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -1276,47 +1276,44 @@ ERROR HY000: Integer is required for ROWS-type frame # select count(*) over (order by c -range between unbounded preceding and current row) +range between unbounded preceding and current row) as r from t1; -count(*) over (order by c -range between unbounded preceding and current row) +r 1 2 select count(*) over (order by c -range between current row and unbounded following) +range between current row and unbounded following) as r from t1; -count(*) over (order by c -range between current row and unbounded following) +r 2 1 select count(*) over (order by c -range between unbounded preceding and unbounded following) +range between unbounded preceding and unbounded following) as r from t1; -count(*) over (order by c -range between unbounded preceding and unbounded following) +r 2 2 create table t2 (a int, b varchar(5)); insert into t2 values (1,'a'), (2, 'b'), (3, 'c'); -select sum(a) over (order by b range between unbounded preceding and current row) from t2; -sum(a) over (order by b range between unbounded preceding and current row) +select sum(a) over (order by b range between unbounded preceding and current row) as r from t2; +r 1 3 6 insert into t1 values (3,3,'goo'); insert into t1 values (3,1,'har'); insert into t1 values (1,4,'har'); -select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) from t1; -a b sum(b) over (order by a, b desc range between unbounded preceding and current row) +select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) as r from t1; +a b r 1 4 4 1 1 5 2 2 7 3 3 10 3 1 11 -select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) from t1; -a b sum(b) over (order by a desc, b range between unbounded preceding and current row) +select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) as r from t1; +a b r 3 1 1 3 3 4 2 2 6 diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test index d8771f158fe..5722cedab81 100644 --- a/mysql-test/main/win.test +++ b/mysql-test/main/win.test @@ -818,31 +818,31 @@ from t1; select count(*) over (order by c - range between unbounded preceding and current row) + range between unbounded preceding and current row) as r from t1; select count(*) over (order by c - range between current row and unbounded following) + range between current row and unbounded following) as r from t1; select count(*) over (order by c - range between unbounded preceding and unbounded following) + range between unbounded preceding and unbounded following) as r from t1; create table t2 (a int, b varchar(5)); insert into t2 values (1,'a'), (2, 'b'), (3, 'c'); -select sum(a) over (order by b range between unbounded preceding and current row) from t2; +select sum(a) over (order by b range between unbounded preceding and current row) as r from t2; insert into t1 values (3,3,'goo'); insert into t1 values (3,1,'har'); insert into t1 values (1,4,'har'); -select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) from t1; +select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) as r from t1; -select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) from t1; +select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) as r from t1; drop table t2; delete from t1 where a >= 3 or b = 4; diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index edf7acba24f..e233c8fa3ef 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -1282,47 +1282,44 @@ ERROR HY000: Integer is required for ROWS-type frame # select count(*) over (order by c -range between unbounded preceding and current row) +range between unbounded preceding and current row) as r from t1; -count(*) over (order by c -range between unbounded preceding and current row) +r 1 2 select count(*) over (order by c -range between current row and unbounded following) +range between current row and unbounded following) as r from t1; -count(*) over (order by c -range between current row and unbounded following) +r 2 1 select count(*) over (order by c -range between unbounded preceding and unbounded following) +range between unbounded preceding and unbounded following) as r from t1; -count(*) over (order by c -range between unbounded preceding and unbounded following) +r 2 2 create table t2 (a int, b varchar(5)); insert into t2 values (1,'a'), (2, 'b'), (3, 'c'); -select sum(a) over (order by b range between unbounded preceding and current row) from t2; -sum(a) over (order by b range between unbounded preceding and current row) +select sum(a) over (order by b range between unbounded preceding and current row) as r from t2; +r 1 3 6 insert into t1 values (3,3,'goo'); insert into t1 values (3,1,'har'); insert into t1 values (1,4,'har'); -select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) from t1; -a b sum(b) over (order by a, b desc range between unbounded preceding and current row) +select a, b, sum(b) over (order by a, b desc range between unbounded preceding and current row) as r from t1; +a b r 1 4 4 1 1 5 2 2 7 3 3 10 3 1 11 -select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) from t1; -a b sum(b) over (order by a desc, b range between unbounded preceding and current row) +select a, b, sum(b) over (order by a desc, b range between unbounded preceding and current row) as r from t1; +a b r 3 1 1 3 3 4 2 2 6 From 232d7a5e2dc50181294b927e2bc4b02e282725a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 29 Jul 2024 10:58:09 +0300 Subject: [PATCH 05/12] MDEV-34565: SIGILL due to OS not supporting AVX512 It is not sufficient to check that the CPU supports the necessary instructions. Also the operating system (or virtual machine hypervisor) must enable all the AVX registers to be saved and restored on a context switch. Because clang 8 does not support the compiler intrinsic _xgetbv() we will require clang 9 or later for enabling the use of VPCLMULQDQ and the related AVX512 features. --- mysys/crc32/crc32c_x86.cc | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/mysys/crc32/crc32c_x86.cc b/mysys/crc32/crc32c_x86.cc index 0a4fd9db812..3ddddf1303c 100644 --- a/mysys/crc32/crc32c_x86.cc +++ b/mysys/crc32/crc32c_x86.cc @@ -28,7 +28,8 @@ # elif __GNUC__ >= 14 || (defined __clang_major__ && __clang_major__ >= 18) # define TARGET "pclmul,evex512,avx512f,avx512dq,avx512bw,avx512vl,vpclmulqdq" # define USE_VPCLMULQDQ __attribute__((target(TARGET))) -# elif __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 8) +# elif __GNUC__ >= 11 || (defined __clang_major__ && __clang_major__ >= 9) +/* clang 8 does not support _xgetbv(), which we also need */ # define TARGET "pclmul,avx512f,avx512dq,avx512bw,avx512vl,vpclmulqdq" # define USE_VPCLMULQDQ __attribute__((target(TARGET))) # endif @@ -38,6 +39,7 @@ extern "C" unsigned crc32c_sse42(unsigned crc, const void* buf, size_t size); constexpr uint32_t cpuid_ecx_SSE42= 1U << 20; constexpr uint32_t cpuid_ecx_SSE42_AND_PCLMUL= cpuid_ecx_SSE42 | 1U << 1; +constexpr uint32_t cpuid_ecx_XSAVE= 1U << 26; static uint32_t cpuid_ecx() { @@ -382,8 +384,19 @@ static unsigned crc32_avx512(unsigned crc, const char *buf, size_t size, } } -static ATTRIBUTE_NOINLINE int have_vpclmulqdq() +#ifdef __GNUC__ +__attribute__((target("xsave"))) +#endif +static bool os_have_avx512() { + // The following flags must be set: SSE, AVX, OPMASK, ZMM_HI256, HI16_ZMM + return !(~_xgetbv(0 /*_XCR_XFEATURE_ENABLED_MASK*/) & 0xe6); +} + +static ATTRIBUTE_NOINLINE bool have_vpclmulqdq(uint32_t cpuid_ecx) +{ + if (!(cpuid_ecx & cpuid_ecx_XSAVE) || !os_have_avx512()) + return false; # ifdef _MSC_VER int regs[4]; __cpuidex(regs, 7, 0); @@ -410,10 +423,11 @@ static unsigned crc32c_vpclmulqdq(unsigned crc, const void *buf, size_t size) extern "C" my_crc32_t crc32_pclmul_enabled(void) { - if (~cpuid_ecx() & cpuid_ecx_SSE42_AND_PCLMUL) + const uint32_t ecx= cpuid_ecx(); + if (~ecx & cpuid_ecx_SSE42_AND_PCLMUL) return nullptr; #ifdef USE_VPCLMULQDQ - if (have_vpclmulqdq()) + if (have_vpclmulqdq(ecx)) return crc32_vpclmulqdq; #endif return crc32_pclmul; @@ -421,19 +435,20 @@ extern "C" my_crc32_t crc32_pclmul_enabled(void) extern "C" my_crc32_t crc32c_x86_available(void) { + const uint32_t ecx= cpuid_ecx(); #ifdef USE_VPCLMULQDQ - if (have_vpclmulqdq()) + if (have_vpclmulqdq(ecx)) return crc32c_vpclmulqdq; #endif #if SIZEOF_SIZE_T == 8 - switch (cpuid_ecx() & cpuid_ecx_SSE42_AND_PCLMUL) { + switch (ecx & cpuid_ecx_SSE42_AND_PCLMUL) { case cpuid_ecx_SSE42_AND_PCLMUL: return crc32c_3way; case cpuid_ecx_SSE42: return crc32c_sse42; } #else - if (cpuid_ecx() & cpuid_ecx_SSE42) + if (ecx & cpuid_ecx_SSE42) return crc32c_sse42; #endif return nullptr; From 7e5c9ccda55b846328edc44a1e7342c605dcd73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 29 Jul 2024 15:04:16 +0300 Subject: [PATCH 06/12] MDEV-34502 fixup: Do not cripple MSAN We need to work around deficiencies of Valgrind, and apparently the previous work-around attempts (such as d247d64988fb3b5d348e412813593a13f3be91fa) do not work anymore, definitely not on recent clang-based compilers. MemorySanitizer should be fine; unfortunately we set HAVE_valgrind for it as well. --- storage/innobase/include/mach0data.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/innobase/include/mach0data.inl b/storage/innobase/include/mach0data.inl index 94bf4326069..8e95d05c79c 100644 --- a/storage/innobase/include/mach0data.inl +++ b/storage/innobase/include/mach0data.inl @@ -38,7 +38,7 @@ mach_write_to_1( byte* b, /*!< in: pointer to byte where to store */ ulint n) /*!< in: ulint integer to be stored, >= 0, < 256 */ { -#ifndef HAVE_valgrind +#if !defined HAVE_valgrind || __has_feature(memory_sanitizer) ut_ad((n & ~0xFFUL) == 0); #endif @@ -57,7 +57,7 @@ mach_write_to_2( byte* b, /*!< in: pointer to two bytes where to store */ ulint n) /*!< in: ulint integer to be stored */ { -#ifndef HAVE_valgrind +#if !defined HAVE_valgrind || __has_feature(memory_sanitizer) ut_ad((n & ~0xFFFFUL) == 0); #endif From 48b256a7e283a84802d94060b77bce1e0eab81a0 Mon Sep 17 00:00:00 2001 From: Rex Date: Tue, 2 Jul 2024 12:27:41 +1100 Subject: [PATCH 07/12] MDEV-34506 2nd execution name resolution problem with pushdown into unions Statements affected by this bug need all the following to be true 1) a derived table table or view whose specification contains a set operation at the top level. 2) a grouping operator (group by/having) operating on a column alias other than in the first select of the union/intersect 3) an outer condition that will be pushed into all selects in this union/intersect, either into the where or having clause When pushing a condition into all selects of a unit with more than one select, pushdown_cond_for_derived() renames items so we can re-use the condition being pushed. These names need to be saved and reset for correct name resolution on second execution of prepared statements. Reviewed by Igor Babaev (igor@mariadb.com) --- mysql-test/main/derived_cond_pushdown.result | 495 +++++++++++++++++++ mysql-test/main/derived_cond_pushdown.test | 87 ++++ sql/sql_derived.cc | 1 + 3 files changed, 583 insertions(+) diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index f13f04a26dc..4fa8867e2f4 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -18557,3 +18557,498 @@ valdouble valint1 5 3289988 DROP TABLE t1,t2; # End of 10.4 tests +# MDEV-34506 2nd execution name resolution problem with pushdown into +# unions +# +# Statements affected by this bug need all the following to be true +# 1) a derived table table or view whose specification contains a set +# operation at the top level. +# 2) a grouping operator (group by/having) operating on a column alias +# other than in the first select of the union/intersect +# 3) an outer condition that will be pushed into all selects in this +# union/intersect, either into the where or having clause +# +# When pushing a condition into all selects of a unit with more than one +# select, pushdown_cond_for_derived() renames items so we can re-use the +# condition being pushed. +# These names need to be saved and reset for correct name resolution on +# second execution of prepared statements. +create table t1 (c1 int, c2 int, c3 int); +insert into t1 values (1,2,3),(1,2,2),(4,5,6); +insert into t1 values (17,8,9),(11,11,12); +create table t2 (c4 int, c5 int, c6 int); +insert into t2 values (7,8,9),(10,11,12); +prepare stmt from 'select * from +( +select c1, sum(c3) as s from t1 group by c1 +union +select c4 as c, sum(c6) as u from t2 group by c +) dt +where c1 > 6'; +execute stmt; +c1 s +11 12 +17 9 +7 9 +10 12 +execute stmt; +c1 s +11 12 +17 9 +7 9 +10 12 +prepare stmt from 'explain format=json select * from +( +select c1, sum(c3) as s from t1 group by c1 +union +select c4 as c, sum(c6) as u from t2 group by c +) dt +where c1 > 6'; +execute stmt; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 7, + "filtered": 100, + "attached_condition": "dt.c1 > 6", + "materialized": { + "query_block": { + "union_result": { + "table_name": "", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "t1.c1", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 5, + "filtered": 100, + "attached_condition": "t1.c1 > 6" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "filesort": { + "sort_key": "t2.c4", + "temporary_table": { + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "t2.c4 > 6" + } + } + } + } + } + ] + } + } + } + } + } +} +execute stmt; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 7, + "filtered": 100, + "attached_condition": "dt.c1 > 6", + "materialized": { + "query_block": { + "union_result": { + "table_name": "", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "filesort": { + "sort_key": "t1.c1", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 5, + "filtered": 100, + "attached_condition": "t1.c1 > 6" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "filesort": { + "sort_key": "t2.c4", + "temporary_table": { + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "t2.c4 > 6" + } + } + } + } + } + ] + } + } + } + } + } +} +prepare stmt from 'select * from +( +select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2 +union +select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3 +) dt +where c2 > 5'; +execute stmt; +c1 c2 s +11 11 12 +17 8 9 +7 8 9 +10 11 12 +execute stmt; +c1 c2 s +11 11 12 +17 8 9 +7 8 9 +10 11 12 +prepare stmt from 'explain format=json select * from +( +select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2 +union +select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3 +) dt +where c2 > 5'; +execute stmt; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 7, + "filtered": 100, + "attached_condition": "dt.c2 > 5", + "materialized": { + "query_block": { + "union_result": { + "table_name": "", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "s > 2", + "filesort": { + "sort_key": "t1.c1, t1.c2", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 5, + "filtered": 100, + "attached_condition": "t1.c2 > 5" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "having_condition": "s > 3", + "filesort": { + "sort_key": "t2.c4, t2.c5", + "temporary_table": { + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "t2.c5 > 5" + } + } + } + } + } + ] + } + } + } + } + } +} +execute stmt; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 7, + "filtered": 100, + "attached_condition": "dt.c2 > 5", + "materialized": { + "query_block": { + "union_result": { + "table_name": "", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "s > 2", + "filesort": { + "sort_key": "t1.c1, t1.c2", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 5, + "filtered": 100, + "attached_condition": "t1.c2 > 5" + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "having_condition": "s > 3", + "filesort": { + "sort_key": "t2.c4, t2.c5", + "temporary_table": { + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100, + "attached_condition": "t2.c5 > 5" + } + } + } + } + } + ] + } + } + } + } + } +} +prepare stmt from 'select * +from +( +select c1, c2, max(c3) as max_c, avg(c3) as avg_c +from t1 +group by c1,c2 +having max_c < 7 +union +select c4, c5, max(c6) as u, avg(c6) as w +from t2 +group by c4, c5 +having u < 10 +) dt, +t2 +where dt.max_c > 6 and t2.c6 > dt.c1'; +execute stmt; +c1 c2 max_c avg_c c4 c5 c6 +7 8 9 9.0000 7 8 9 +7 8 9 9.0000 10 11 12 +execute stmt; +c1 c2 max_c avg_c c4 c5 c6 +7 8 9 9.0000 7 8 9 +7 8 9 9.0000 10 11 12 +prepare stmt from 'explain format=json select * +from +( +select c1, c2, max(c3) as max_c, avg(c3) as avg_c +from t1 +group by c1,c2 +having max_c < 7 +union +select c4, c5, max(c6) as u, avg(c6) as w +from t2 +group by c4, c5 +having u < 10 +) dt, +t2 +where dt.max_c > 6 and t2.c6 > dt.c1'; +execute stmt; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 7, + "filtered": 100, + "attached_condition": "dt.max_c > 6" + }, + "buffer_type": "flat", + "buffer_size": "173", + "join_type": "BNL", + "attached_condition": "t2.c6 > dt.c1", + "materialized": { + "query_block": { + "union_result": { + "table_name": "", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "max_c < 7 and max_c > 6", + "filesort": { + "sort_key": "t1.c1, t1.c2", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 5, + "filtered": 100 + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "having_condition": "max_c < 10 and max_c > 6", + "filesort": { + "sort_key": "t2.c4, t2.c5", + "temporary_table": { + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100 + } + } + } + } + } + ] + } + } + } + } + } +} +execute stmt; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100 + }, + "block-nl-join": { + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 7, + "filtered": 100, + "attached_condition": "dt.max_c > 6" + }, + "buffer_type": "flat", + "buffer_size": "173", + "join_type": "BNL", + "attached_condition": "t2.c6 > dt.c1", + "materialized": { + "query_block": { + "union_result": { + "table_name": "", + "access_type": "ALL", + "query_specifications": [ + { + "query_block": { + "select_id": 2, + "having_condition": "max_c < 7 and max_c > 6", + "filesort": { + "sort_key": "t1.c1, t1.c2", + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 5, + "filtered": 100 + } + } + } + } + }, + { + "query_block": { + "select_id": 3, + "operation": "UNION", + "having_condition": "max_c < 10 and max_c > 6", + "filesort": { + "sort_key": "t2.c4, t2.c5", + "temporary_table": { + "table": { + "table_name": "t2", + "access_type": "ALL", + "rows": 2, + "filtered": 100 + } + } + } + } + } + ] + } + } + } + } + } +} +drop table t1, t2; +# End of 10.5 tests diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index ce303779a41..179e033889f 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -4102,3 +4102,90 @@ eval $q; DROP TABLE t1,t2; --echo # End of 10.4 tests + +--echo # MDEV-34506 2nd execution name resolution problem with pushdown into +--echo # unions +--echo # +--echo # Statements affected by this bug need all the following to be true +--echo # 1) a derived table table or view whose specification contains a set +--echo # operation at the top level. +--echo # 2) a grouping operator (group by/having) operating on a column alias +--echo # other than in the first select of the union/intersect +--echo # 3) an outer condition that will be pushed into all selects in this +--echo # union/intersect, either into the where or having clause +--echo # +--echo # When pushing a condition into all selects of a unit with more than one +--echo # select, pushdown_cond_for_derived() renames items so we can re-use the +--echo # condition being pushed. +--echo # These names need to be saved and reset for correct name resolution on +--echo # second execution of prepared statements. + +create table t1 (c1 int, c2 int, c3 int); +insert into t1 values (1,2,3),(1,2,2),(4,5,6); +insert into t1 values (17,8,9),(11,11,12); +create table t2 (c4 int, c5 int, c6 int); +insert into t2 values (7,8,9),(10,11,12); +let $q=select * from + ( + select c1, sum(c3) as s from t1 group by c1 + union + select c4 as c, sum(c6) as u from t2 group by c + ) dt + where c1 > 6; +eval prepare stmt from '$q'; +execute stmt; +execute stmt; + +eval prepare stmt from 'explain format=json $q'; +--source include/analyze-format.inc +execute stmt; +--source include/analyze-format.inc +execute stmt; + +let $q=select * from + ( + select c1, c2, sum(c3) as s from t1 group by c1, c2 having s > 2 + union + select c4, c5, sum(c6) as u from t2 group by c4, c5 having u > 3 + ) dt + where c2 > 5; + +eval prepare stmt from '$q'; +execute stmt; +execute stmt; + +eval prepare stmt from 'explain format=json $q'; +--source include/analyze-format.inc +execute stmt; +--source include/analyze-format.inc +execute stmt; + +let $q=select * + from + ( + select c1, c2, max(c3) as max_c, avg(c3) as avg_c + from t1 + group by c1,c2 + having max_c < 7 + union + select c4, c5, max(c6) as u, avg(c6) as w + from t2 + group by c4, c5 + having u < 10 + ) dt, + t2 + where dt.max_c > 6 and t2.c6 > dt.c1; + +eval prepare stmt from '$q'; +execute stmt; +execute stmt; + +eval prepare stmt from 'explain format=json $q'; +--source include/analyze-format.inc +execute stmt; +--source include/analyze-format.inc +execute stmt; + +drop table t1, t2; + +--echo # End of 10.5 tests diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index a721875051b..bd55c533108 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1557,6 +1557,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived) if (sl != first_sl) { DBUG_ASSERT(sl->item_list.elements == first_sl->item_list.elements); + sl->save_item_list_names(thd); List_iterator_fast it(sl->item_list); List_iterator_fast nm_it(unit->types); while (Item *item= it++) From c038b3c05ed90041333dc869e3435c301210a3c4 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 30 Jul 2024 12:05:38 +0530 Subject: [PATCH 08/12] MDEV-34181 Instant table aborts after discard tablespace - commit 85db5347311340e39753b0200fb9d459a5024535 (MDEV-33400) retains the instantness in the table definition after discard tablespace. So there is no need to assign n_core_null_bytes during instant table preparation unless they are not initialized. --- mysql-test/suite/innodb/r/import_bugs.result | 26 ++++++++++++++++++++ mysql-test/suite/innodb/t/import_bugs.test | 20 +++++++++++++++ storage/innobase/handler/handler0alter.cc | 10 +++++--- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/innodb/r/import_bugs.result b/mysql-test/suite/innodb/r/import_bugs.result index 82942e85301..f62c3ee4279 100644 --- a/mysql-test/suite/innodb/r/import_bugs.result +++ b/mysql-test/suite/innodb/r/import_bugs.result @@ -61,4 +61,30 @@ id 4 5 DROP TABLE t2; +# +# MDEV-34181 Instant table aborts after discard tablespace +# +CREATE TABLE t1(c3 INT, c2 INT, c1 INT KEY)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1, 1), (2, 2, 2); +CREATE TABLE t2 (c1 INT KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES(1); +ALTER TABLE t2 ADD c2 INT; +FLUSH TABLES t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 DISCARD TABLESPACE; +ALTER TABLE t2 ADD c3 INT FIRST; +Warnings: +Warning 1814 Tablespace has been discarded for table `t2` +ALTER TABLE t2 IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c3` int(11) DEFAULT NULL, + `c1` int(11) NOT NULL, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +DROP TABLE t2, t1; # End of 10.5 tests diff --git a/mysql-test/suite/innodb/t/import_bugs.test b/mysql-test/suite/innodb/t/import_bugs.test index d9c5b6b1d89..5c9fdc602fd 100644 --- a/mysql-test/suite/innodb/t/import_bugs.test +++ b/mysql-test/suite/innodb/t/import_bugs.test @@ -78,4 +78,24 @@ INSERT INTO t2() VALUES(); SELECT * FROM t2 ORDER BY id; DROP TABLE t2; +--echo # +--echo # MDEV-34181 Instant table aborts after discard tablespace +--echo # +CREATE TABLE t1(c3 INT, c2 INT, c1 INT KEY)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1, 1), (2, 2, 2); +CREATE TABLE t2 (c1 INT KEY) ENGINE=InnoDB; +INSERT INTO t2 VALUES(1); +ALTER TABLE t2 ADD c2 INT; +FLUSH TABLES t1 FOR EXPORT; +let $datadir=`select @@datadir`; +--copy_file $datadir/test/t1.ibd $datadir/test/imp_t1.ibd +UNLOCK TABLES; +ALTER TABLE t2 DISCARD TABLESPACE; +ALTER TABLE t2 ADD c3 INT FIRST; +--copy_file $datadir/test/imp_t1.ibd $datadir/test/t2.ibd + +--replace_regex /opening '.*\/test\//opening '.\/test\// +ALTER TABLE t2 IMPORT TABLESPACE; +SHOW CREATE TABLE t2; +DROP TABLE t2, t1; --echo # End of 10.5 tests diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 79024177125..b5a76bfcdc2 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -374,10 +374,12 @@ found_j: } } - /* In case of discarded tablespace, InnoDB can't - read the root page. So assign the null bytes based - on nullabled fields */ - if (!oindex.table->space) { + /* Discard tablespace doesn't remove the instantness + from the table definition. if n_core_null_bytes wasn't + initialized then assign it based on nullable fields */ + if (!oindex.table->space + && oindex.n_core_null_bytes + == dict_index_t::NO_CORE_NULL_BYTES) { oindex.n_core_null_bytes = static_cast( UT_BITS_IN_BYTES(unsigned(oindex.n_nullable))); } From fdda8171b2391f94905a07e8072d0b5f2e44ae74 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Tue, 30 Jul 2024 17:49:09 +0300 Subject: [PATCH 09/12] MDEV-34580: Assertion `(key_part->key_part_flag & 4) == 0' failed key_hashnr Remove an assert added by fix for MDEV-34417. BNL-H join can be used with prefix keys. This happens when there are real prefix indexes on the equi-join columns (although it probably doesn't make a lot of sense). Anyway, remove the assert. The code receives properly truncated key values for hashing/comparison so it can handle them just fine. --- mysql-test/main/join_cache.result | 20 ++++++++++++++++++++ mysql-test/main/join_cache.test | 22 ++++++++++++++++++++++ sql/key.cc | 14 ++++++++------ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/join_cache.result b/mysql-test/main/join_cache.result index 1e42f798d2c..3546d74aaeb 100644 --- a/mysql-test/main/join_cache.result +++ b/mysql-test/main/join_cache.result @@ -6420,3 +6420,23 @@ DROP TABLE t1,t2,t3; # # End of 10.4 tests # +# +# MDEV-34580: Assertion `(key_part->key_part_flag & 4) == 0' failed key_hashnr +# +SET join_cache_level=3; +CREATE TABLE t1 ( a TIMESTAMP , b varchar(100), c varchar(10) ) ; +INSERT INTO t1 (b,c) VALUES ('GHOBS','EMLCG'),('t','p'); +CREATE TABLE t2 (a varchar(100), b varchar(100), c varchar(10) , KEY b (b(66))) ; +insert into t2 select seq, seq, seq from seq_1_to_20; +explain +SELECT t1.a FROM t1 JOIN t2 ON t1.b = t2.b ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t2 hash_ALL b #hash#b 69 test.t1.b 20 Using where; Using join buffer (flat, BNLH join) +SELECT t1.a FROM t1 JOIN t2 ON t1.b = t2.b ; +a +set join_cache_level=default; +DROP TABLE t1, t2; +# +# End of 10.5 tests +# diff --git a/mysql-test/main/join_cache.test b/mysql-test/main/join_cache.test index e9c81a08562..0614e2a1ba3 100644 --- a/mysql-test/main/join_cache.test +++ b/mysql-test/main/join_cache.test @@ -4300,3 +4300,25 @@ DROP TABLE t1,t2,t3; --echo # --echo # End of 10.4 tests --echo # + +--echo # +--echo # MDEV-34580: Assertion `(key_part->key_part_flag & 4) == 0' failed key_hashnr +--echo # +--source include/have_sequence.inc +SET join_cache_level=3; + +CREATE TABLE t1 ( a TIMESTAMP , b varchar(100), c varchar(10) ) ; +INSERT INTO t1 (b,c) VALUES ('GHOBS','EMLCG'),('t','p'); + +CREATE TABLE t2 (a varchar(100), b varchar(100), c varchar(10) , KEY b (b(66))) ; +insert into t2 select seq, seq, seq from seq_1_to_20; + +explain +SELECT t1.a FROM t1 JOIN t2 ON t1.b = t2.b ; +SELECT t1.a FROM t1 JOIN t2 ON t1.b = t2.b ; + +set join_cache_level=default; +DROP TABLE t1, t2; +--echo # +--echo # End of 10.5 tests +--echo # diff --git a/sql/key.cc b/sql/key.cc index 58b2cfbb47a..fa0239b49fc 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -755,10 +755,12 @@ ulong key_hashnr(KEY *key_info, uint used_key_parts, const uchar *key) if (is_string) { /* - Prefix keys are not possible in BNLH joins. - Use the whole string to calculate the hash. + Surprisingly, BNL-H joins may use prefix keys. This may happen + when there is a real index on the column used in equi-join. + + In this case, the passed key tuple is already a prefix, no + special handling is required. */ - DBUG_ASSERT((key_part->key_part_flag & HA_PART_KEY_SEG) == 0); cs->hash_sort(pos+pack_length, length, &nr, &nr2); key+= pack_length; } @@ -862,10 +864,10 @@ bool key_buf_cmp(KEY *key_info, uint used_key_parts, if (is_string) { /* - Prefix keys are not possible in BNLH joins. - Compare whole strings. + Surprisingly, BNL-H joins may use prefix keys. This may happen + when there is a real index on the column used in equi-join. + In this case, we get properly truncated prefixes here. */ - DBUG_ASSERT((key_part->key_part_flag & HA_PART_KEY_SEG) == 0); if (cs->strnncollsp(pos1 + pack_length, length1, pos2 + pack_length, length2)) return true; From 533e6d5d13921948bf451b6a9c3628d4c1699383 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 30 Jul 2024 23:59:00 +0530 Subject: [PATCH 10/12] MDEV-34670 IMPORT TABLESPACE unnecessary traverses tablespace list Problem: ======== - After the commit ada1074bb10359342ee00e220fe9c172574265fb (MDEV-14398) fil_crypt_set_encrypt_tables() iterates through all tablespaces to fill the default_encrypt tables list. This was a trigger to encrypt or decrypt when key rotation age is set to 0. But import tablespace does call fil_crypt_set_encrypt_tables() unnecessarily. The motivation for the call is to signal the encryption threads. Fix: ==== ha_innobase::discard_or_import_tablespace: Remove the fil_crypt_set_encrypt_tables() and add the import tablespace to the default encrypt list if necessary --- .../r/innodb_encryption_discard_import.result | 41 ++++++++++++++ .../t/innodb_encryption_discard_import.test | 56 ++++++++++++++++++- storage/innobase/fil/fil0crypt.cc | 20 +++++++ storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/include/fil0crypt.h | 5 ++ 5 files changed, 122 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result b/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result index 18082027660..95797da2e15 100644 --- a/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result +++ b/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result @@ -1,3 +1,5 @@ +SET @start_encr_threads = @@global.innodb_encryption_threads; +SET @start_encrypt_tables = @@global.innodb_encrypt_tables; CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB encrypted=yes; CREATE TABLE t2 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB; CREATE TABLE t3 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB row_format=compressed encrypted=yes; @@ -116,3 +118,42 @@ NOT FOUND /temp/ in t2.ibd # t3 ... on expecting NOT FOUND UNLOCK TABLES; DROP TABLE t1, t2, t3; +# +# MDEV-34670 IMPORT TABLESPACE unnecessary traverses +# tablespace list +# +SET GLOBAL innodb_encrypt_tables= OFF; +SET GLOBAL innodb_encryption_threads= 0; +CREATE TABLE t1(f1 int,f2 text)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, "InnoDB"); +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLES t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +SET GLOBAL innodb_encryption_threads=2; +SET GLOBAL innodb_encrypt_tables = ON; +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +innodb_system +test/t1 +test/t2 +SET GLOBAL innodb_encrypt_tables = OFF; +# Wait max 10 min for key encryption threads to decrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +innodb_system +test/t1 +test/t2 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +DROP TABLE t1, t2; +SET GLOBAL innodb_encryption_threads=@start_encr_threads; +SET GLOBAL innodb_encrypt_tables=@start_encrypt_tables; diff --git a/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test index 5f02d966e7e..e33aaec3e21 100644 --- a/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test +++ b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test @@ -2,7 +2,8 @@ -- source include/have_example_key_management_plugin.inc -- source include/not_valgrind.inc -- source include/not_embedded.inc - +SET @start_encr_threads = @@global.innodb_encryption_threads; +SET @start_encrypt_tables = @@global.innodb_encrypt_tables; let MYSQLD_DATADIR = `SELECT @@datadir`; --let SEARCH_RANGE = 10000000 @@ -124,3 +125,56 @@ FLUSH TABLES t1, t2, t3 FOR EXPORT; UNLOCK TABLES; DROP TABLE t1, t2, t3; + +--echo # +--echo # MDEV-34670 IMPORT TABLESPACE unnecessary traverses +--echo # tablespace list +--echo # +SET GLOBAL innodb_encrypt_tables= OFF; +SET GLOBAL innodb_encryption_threads= 0; + +CREATE TABLE t1(f1 int,f2 text)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, "InnoDB"); +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLES t1 FOR EXPORT; +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +SET GLOBAL innodb_encryption_threads=2; +SET GLOBAL innodb_encrypt_tables = ON; + +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces + 1 from information_schema.tables where engine = 'InnoDB'` + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; + +SET GLOBAL innodb_encrypt_tables = OFF; + +--echo # Wait max 10 min for key encryption threads to decrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; + +DROP TABLE t1, t2; +SET GLOBAL innodb_encryption_threads=@start_encr_threads; +SET GLOBAL innodb_encrypt_tables=@start_encrypt_tables; diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 3cccf5ec864..fce308bcc81 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1461,6 +1461,8 @@ inline bool fil_space_t::acquire_if_not_stopped() bool fil_crypt_must_default_encrypt() { + /* prevents a race condition with fil_crypt_set_rotate_key_age() */ + ut_ad(mutex_own(&fil_system.mutex)); return !srv_fil_crypt_rotate_key_age || !srv_encrypt_rotate; } @@ -2364,6 +2366,24 @@ fil_crypt_set_rotation_iops( os_event_set(fil_crypt_threads_event); } +/** Add the import tablespace to default_encrypt list +if necessary and signal fil_crypt_threads +@param space imported tablespace */ +void fil_crypt_add_imported_space(fil_space_t *space) +{ + mutex_enter(&fil_system.mutex); + + if (fil_crypt_must_default_encrypt()) + { + fil_system.default_encrypt_tables.push_back(*space); + space->is_in_default_encrypt= true; + } + + mutex_exit(&fil_system.mutex); + + os_event_set(fil_crypt_threads_event); +} + /********************************************************************* Adjust encrypt tables @param[in] val New setting for innodb-encrypt-tables */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 69ad47b8ac3..08229b21839 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13286,7 +13286,7 @@ ha_innobase::discard_or_import_tablespace( | HA_STATUS_VARIABLE | HA_STATUS_AUTO); - fil_crypt_set_encrypt_tables(srv_encrypt_tables); + fil_crypt_add_imported_space(m_prebuilt->table->space); } } diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h index 62043003a6c..d8db6ad9851 100644 --- a/storage/innobase/include/fil0crypt.h +++ b/storage/innobase/include/fil0crypt.h @@ -383,6 +383,11 @@ void fil_crypt_set_rotation_iops( uint val); +/** Add the import tablespace to default_encrypt list +if necessary and signal fil_crypt_threads +@param space imported tablespace */ +void fil_crypt_add_imported_space(fil_space_t *space); + /********************************************************************* Adjust encrypt tables @param[in] val New setting for innodb-encrypt-tables */ From 001608de7e2273601b6b862a65225a8e15eab93f Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Wed, 31 Jul 2024 14:14:18 -0600 Subject: [PATCH 11/12] MDEV-15393: Fix rpl_mysqldump_gtid_slave_pos The slave would try to sync_with_master_gtid.inc, but the master never actually saved its gtid position so the test would move on too quickly. --- mysql-test/suite/rpl/r/rpl_mysqldump_gtid_slave_pos.result | 1 + mysql-test/suite/rpl/t/rpl_mysqldump_gtid_slave_pos.test | 1 + 2 files changed, 2 insertions(+) diff --git a/mysql-test/suite/rpl/r/rpl_mysqldump_gtid_slave_pos.result b/mysql-test/suite/rpl/r/rpl_mysqldump_gtid_slave_pos.result index 301605d5d8d..1849f896758 100644 --- a/mysql-test/suite/rpl/r/rpl_mysqldump_gtid_slave_pos.result +++ b/mysql-test/suite/rpl/r/rpl_mysqldump_gtid_slave_pos.result @@ -30,6 +30,7 @@ insert into t1 set a = 4; insert into t1 set a = 3; insert into t1 set a = 2; insert into t1 set a = 1; +include/save_master_gtid.inc connection slave; include/start_slave.inc include/sync_with_master_gtid.inc diff --git a/mysql-test/suite/rpl/t/rpl_mysqldump_gtid_slave_pos.test b/mysql-test/suite/rpl/t/rpl_mysqldump_gtid_slave_pos.test index 74d231731c7..e66a92a6153 100644 --- a/mysql-test/suite/rpl/t/rpl_mysqldump_gtid_slave_pos.test +++ b/mysql-test/suite/rpl/t/rpl_mysqldump_gtid_slave_pos.test @@ -44,6 +44,7 @@ while ($i) eval insert into t1 set a = $i; --dec $i } +--source include/save_master_gtid.inc --connection slave --source include/start_slave.inc From 7a5b8bf0f5470a13094101f0a4bdfa9e1b9ded02 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Sat, 3 Aug 2024 08:47:17 +0200 Subject: [PATCH 12/12] lost in editinig line added --- mysql-test/main/json_debug_nonembedded_noasan.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/main/json_debug_nonembedded_noasan.test b/mysql-test/main/json_debug_nonembedded_noasan.test index 021abd8c602..11788fd3830 100644 --- a/mysql-test/main/json_debug_nonembedded_noasan.test +++ b/mysql-test/main/json_debug_nonembedded_noasan.test @@ -1,5 +1,6 @@ -- source include/not_embedded.inc --source include/have_debug.inc +--source include/not_asan.inc --echo # --echo # Beginning of 10.3 test