From 432856c473feb92ddd69442a4c164ee88a0d28d7 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Mon, 9 Dec 2024 19:27:53 +1100 Subject: [PATCH 01/11] MDEV-35571 Check for LIMIT ROWS EXAMINED exceeded in UNION ALL When UNION ALL is used with LIMIT ROWS EXAMINED, and when the limit is exceeded for a SELECT that is not the last in the UNION, interrupt the execution and call end_eof on the result. This makes sure that the results are sent, and the query result status is conclusive rather than empty, which would cause an assertion failure. --- mysql-test/main/limit_rows_examined.result | 43 ++++++++++++++++++++++ mysql-test/main/limit_rows_examined.test | 41 +++++++++++++++++++++ sql/sql_union.cc | 3 +- 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/limit_rows_examined.result b/mysql-test/main/limit_rows_examined.result index 50b542fa5fe..7bea8862c18 100644 --- a/mysql-test/main/limit_rows_examined.result +++ b/mysql-test/main/limit_rows_examined.result @@ -895,3 +895,46 @@ Warnings: Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`c2` = `test`.`t1`.`c1` drop table t1,t2; # End of 10.4 tests +# +# MDEV-35571: Connection hangs after query on a partitioned table with UNION and LIMIT ROWS EXAMINED +# +create table t1 (a int); +insert into t1 values (1), (2); +select * from t1 UNION ALL select * from t1 LIMIT ROWS EXAMINED 1; +a +1 +Warnings: +Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 1. The query result may be incomplete +select * from t1 UNION DISTINCT select * from t1 LIMIT ROWS EXAMINED 1; +a +1 +Warnings: +Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 1. The query result may be incomplete +DROP TABLE t1; +create table t1 (a int); +insert into t1 values (1), (2); +(select a from t1 UNION ALL select a from t1) order by a desc LIMIT ROWS EXAMINED 2; +a +1 +Warnings: +Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 2. The query result may be incomplete +(select a from t1 UNION DISTINCT select a from t1) order by a desc LIMIT ROWS EXAMINED 2; +a +1 +Warnings: +Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 2. The query result may be incomplete +DROP TABLE t1; +CREATE TABLE t1 (a INT); +INSERT INTO t1 SELECT seq%25 FROM seq_1_to_100; +CREATE TABLE t2 (b INT, c INT, KEY(b)) PARTITION BY HASH(c) PARTITIONS 12; +INSERT INTO t2 SELECT seq, seq FROM seq_1_to_10; +SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) UNION ALL SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) LIMIT ROWS EXAMINED 100; +COUNT(*) +Warnings: +Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 100. The query result may be incomplete +SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) UNION DISTINCT SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) LIMIT ROWS EXAMINED 100; +COUNT(*) +Warnings: +Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 100. The query result may be incomplete +DROP TABLE t1, t2; +# End of 10.5 tests diff --git a/mysql-test/main/limit_rows_examined.test b/mysql-test/main/limit_rows_examined.test index 94bbf8e819a..12c75121dfb 100644 --- a/mysql-test/main/limit_rows_examined.test +++ b/mysql-test/main/limit_rows_examined.test @@ -617,3 +617,44 @@ select * from t1, t2 where c1 = c2 LIMIT ROWS EXAMINED 2; drop table t1,t2; --echo # End of 10.4 tests + +--echo # +--echo # MDEV-35571: Connection hangs after query on a partitioned table with UNION and LIMIT ROWS EXAMINED +--echo # + +--source include/have_partition.inc +--source include/have_sequence.inc + +# Simplified test +create table t1 (a int); +insert into t1 values (1), (2); +select * from t1 UNION ALL select * from t1 LIMIT ROWS EXAMINED 1; +# UNION DISTINCT produces the same result here. Note that this is not +# affected by the MDEV-35571 patch +select * from t1 UNION DISTINCT select * from t1 LIMIT ROWS EXAMINED 1; +DROP TABLE t1; + +# Simplified test with order by +create table t1 (a int); +insert into t1 values (1), (2); +(select a from t1 UNION ALL select a from t1) order by a desc LIMIT ROWS EXAMINED 2; +# UNION DISTINCT produces the same result with order by desc. Note +# that this is not affected by the MDEV-35571 patch +(select a from t1 UNION DISTINCT select a from t1) order by a desc LIMIT ROWS EXAMINED 2; +DROP TABLE t1; + +# Original test +CREATE TABLE t1 (a INT); +INSERT INTO t1 SELECT seq%25 FROM seq_1_to_100; + +CREATE TABLE t2 (b INT, c INT, KEY(b)) PARTITION BY HASH(c) PARTITIONS 12; +INSERT INTO t2 SELECT seq, seq FROM seq_1_to_10; + +SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) UNION ALL SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) LIMIT ROWS EXAMINED 100; +# UNION DISTINCT produces the same result here. Note that this is not +# affected by the MDEV-35571 patch +SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) UNION DISTINCT SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) LIMIT ROWS EXAMINED 100; + +DROP TABLE t1, t2; + +--echo # End of 10.5 tests diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 8cbb35fc9a4..53e604bfa92 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -1026,7 +1026,8 @@ bool select_union_direct::send_eof() // Reset for each SELECT_LEX, so accumulate here limit_found_rows+= thd->limit_found_rows; - if (unit->thd->lex->current_select == last_select_lex) + if (unit->thd->lex->current_select == last_select_lex || + thd->killed == ABORT_QUERY) { thd->limit_found_rows= limit_found_rows; From 0b7fa4c267cb7eee4a84a696170266f10397f266 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 29 Nov 2024 21:03:16 +0400 Subject: [PATCH 02/11] MDEV-31219 Assertion `fixed' failed in Item_func_hybrid_field_type / Frame_positional_cursor add_special_frame_cursors() did not check the return value offset_func->fix_fields(). It can return an error if the data type does not support the operator "minus". --- mysql-test/main/gis.result | 8 ++++++++ mysql-test/main/gis.test | 10 ++++++++++ sql/sql_window.cc | 18 ++++++++++++------ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result index c4918809e4d..196758b1e94 100644 --- a/mysql-test/main/gis.result +++ b/mysql-test/main/gis.result @@ -5466,4 +5466,12 @@ CREATE TABLE t (f POINT, KEY(f)); DELETE FROM t WHERE f NOT IN (NULL,'x'); ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field DROP TABLE t; +# +# MDEV-31219 Assertion `fixed' failed in Item_func_hybrid_field_type / Frame_positional_cursor +# +CREATE TABLE t (a INT, b POINT); +INSERT INTO t VALUES (1,POINT(0,0)),(2,POINT(0,0)); +SELECT NTH_VALUE(a,b) OVER () FROM t; +ERROR HY000: Illegal parameter data types point and bigint for operation '-' +DROP TABLE t; # End of 10.5 tests diff --git a/mysql-test/main/gis.test b/mysql-test/main/gis.test index 8e392e6b2f4..6dc932b4f8d 100644 --- a/mysql-test/main/gis.test +++ b/mysql-test/main/gis.test @@ -3472,4 +3472,14 @@ CREATE TABLE t (f POINT, KEY(f)); DELETE FROM t WHERE f NOT IN (NULL,'x'); DROP TABLE t; +--echo # +--echo # MDEV-31219 Assertion `fixed' failed in Item_func_hybrid_field_type / Frame_positional_cursor +--echo # + +CREATE TABLE t (a INT, b POINT); +INSERT INTO t VALUES (1,POINT(0,0)),(2,POINT(0,0)); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT NTH_VALUE(a,b) OVER () FROM t; +DROP TABLE t; + --echo # End of 10.5 tests diff --git a/sql/sql_window.cc b/sql/sql_window.cc index fd8e188a76b..565a1b964b5 100644 --- a/sql/sql_window.cc +++ b/sql/sql_window.cc @@ -2528,7 +2528,7 @@ Frame_cursor *get_frame_cursor(THD *thd, Window_spec *spec, bool is_top_bound) } static -void add_special_frame_cursors(THD *thd, Cursor_manager *cursor_manager, +bool add_special_frame_cursors(THD *thd, Cursor_manager *cursor_manager, Item_window_func *window_func) { Window_spec *spec= window_func->window_spec; @@ -2615,7 +2615,9 @@ void add_special_frame_cursors(THD *thd, Cursor_manager *cursor_manager, Item *offset_func= new (thd->mem_root) Item_func_minus(thd, item_sum->get_arg(1), int_item); - offset_func->fix_fields(thd, &offset_func); + if (offset_func->fix_fields(thd, &offset_func)) + return true; + fc= new Frame_positional_cursor(*top_bound, *top_bound, *bottom_bound, *offset_func, false); @@ -2648,6 +2650,7 @@ void add_special_frame_cursors(THD *thd, Cursor_manager *cursor_manager, fc->add_sum_func(item_sum); cursor_manager->add_cursor(fc); } + return false; } @@ -2675,7 +2678,7 @@ static bool is_computed_with_remove(Item_sum::Sumfunctype sum_func) If the window functions share the same frame specification, those window functions will be registered to the same cursor. */ -void get_window_functions_required_cursors( +bool get_window_functions_required_cursors( THD *thd, List& window_functions, List *cursor_managers) @@ -2726,7 +2729,8 @@ void get_window_functions_required_cursors( if (item_win_func->is_frame_prohibited() || item_win_func->requires_special_cursors()) { - add_special_frame_cursors(thd, cursor_manager, item_win_func); + if (add_special_frame_cursors(thd, cursor_manager, item_win_func)) + return true; cursor_managers->push_back(cursor_manager); continue; } @@ -2760,6 +2764,7 @@ void get_window_functions_required_cursors( } cursor_managers->push_back(cursor_manager); } + return false; } /** @@ -3034,8 +3039,9 @@ bool Window_func_runner::exec(THD *thd, TABLE *tbl, SORT_INFO *filesort_result) it.rewind(); List cursor_managers; - get_window_functions_required_cursors(thd, window_functions, - &cursor_managers); + if (get_window_functions_required_cursors(thd, window_functions, + &cursor_managers)) + return true; /* Go through the sorted array and compute the window function */ bool is_error= compute_window_func(thd, From 54c1031b74e88300103aeeef2e8990204a8584f5 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Fri, 13 Dec 2024 09:29:23 +0700 Subject: [PATCH 03/11] MDEV-34958: after Trigger doesn't work correctly with bulk insert This bug has the same nature as the issues MDEV-34718: Trigger doesn't work correctly with bulk update MDEV-24411: Trigger doesn't work correctly with bulk insert To fix the issue covering all use cases, resetting the thd->bulk_param temporary to the value nullptr before invoking triggers and restoring its original value on finishing execution of a trigger is moved to the method Table_triggers_list::process_triggers that be invoked ultimately for any kind of triggers. --- sql/sql_base.cc | 9 --- sql/sql_delete.cc | 7 --- sql/sql_insert.cc | 10 --- sql/sql_trigger.cc | 9 +++ sql/sql_update.cc | 5 -- tests/mysql_client_test.c | 124 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 31 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0bfae16b23e..de744edfbae 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8784,22 +8784,13 @@ fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, if (!result && triggers) { - void *save_bulk_param= thd->bulk_param; - /* - Reset the sentinel thd->bulk_param in order not to consume the next - values of a bound array in case one of statement executed by - the trigger's body is INSERT statement. - */ - thd->bulk_param= nullptr; if (triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, TRUE) || not_null_fields_have_null_values(table)) { - thd->bulk_param= save_bulk_param; return TRUE; } - thd->bulk_param= save_bulk_param; /* Re-calculate virtual fields to cater for cases when base columns are diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 7823350d7a3..25b3aef3ebe 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -812,17 +812,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, delete_history); if (delete_record) { - void *save_bulk_param= thd->bulk_param; - thd->bulk_param= nullptr; if (!delete_history && table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE)) { error= 1; - thd->bulk_param= save_bulk_param; break; } - thd->bulk_param= save_bulk_param; // no LIMIT / OFFSET if (returning && result->send_data(returning->item_list) < 0) @@ -853,16 +849,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (likely(!error)) { deleted++; - thd->bulk_param= nullptr; if (!delete_history && table->triggers && table->triggers->process_triggers(thd, TRG_EVENT_DELETE, TRG_ACTION_AFTER, FALSE)) { error= 1; - thd->bulk_param= save_bulk_param; break; } - thd->bulk_param= save_bulk_param; if (!--limit && using_limit) { error= -1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 2dccf7af587..18c364c7fea 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1069,21 +1069,12 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, } table->reset_default_fields(); - /* - Reset the sentinel thd->bulk_param in order not to consume the next - values of a bound array in case one of statement executed by - the trigger's body is INSERT statement. - */ - void *save_bulk_param= thd->bulk_param; - thd->bulk_param= nullptr; - if (unlikely(fill_record_n_invoke_before_triggers(thd, table, table-> field_to_fill(), *values, 0, TRG_EVENT_INSERT))) { - thd->bulk_param= save_bulk_param; if (values_list.elements != 1 && ! thd->is_error()) { info.records++; @@ -1092,7 +1083,6 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list, error=1; break; } - thd->bulk_param= save_bulk_param; } /* diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index c788d66744a..f35a07347fe 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -2288,6 +2288,14 @@ bool Table_triggers_list::process_triggers(THD *thd, */ save_current_select= thd->lex->current_select; + /* + Reset the sentinel thd->bulk_param in order not to consume the next + values of a bound array in case one of statement executed by + the trigger's body is a DML statement. + */ + void *save_bulk_param= thd->bulk_param; + thd->bulk_param= nullptr; + do { thd->lex->current_select= NULL; err_status= @@ -2297,6 +2305,7 @@ bool Table_triggers_list::process_triggers(THD *thd, &trigger->subject_table_grants); status_var_increment(thd->status_var.executed_triggers); } while (!err_status && (trigger= trigger->next)); + thd->bulk_param= save_bulk_param; thd->lex->current_select= save_current_select; thd->restore_sub_statement_state(&statement_state); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 7bc7041e161..4a13d83d52f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1161,19 +1161,14 @@ error: rows_inserted++; } - void *save_bulk_param= thd->bulk_param; - thd->bulk_param= nullptr; - if (table->triggers && unlikely(table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE))) { error= 1; - thd->bulk_param= save_bulk_param; break; } - thd->bulk_param= save_bulk_param; if (!--limit && using_limit) { diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 138eae10ab1..f06566cf208 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -22503,6 +22503,129 @@ static void test_mdev_34718_ad() rc= mysql_query(mysql, "DROP TABLE t1, t2"); myquery(rc); } + +/* Test case for bulk INSERT in presence of AFTER INSERT trigger */ +static void test_mdev_34958() +{ + int rc; + MYSQL_STMT *stmt_insert; + MYSQL_BIND bind[2]; + MYSQL_RES *result; + MYSQL_ROW row; + my_ulonglong row_count; + unsigned int vals[] = { 1, 2, 3}; + unsigned int vals_array_len = 3; + const char *insert_stmt= "INSERT INTO t1 VALUES (?)"; + + /* Set up test's environment */ + rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TABLE t2 (a INT)"); + myquery(rc); + + rc= mysql_query(mysql, "CREATE TRIGGER t1_ai AFTER INSERT ON t1 " + "FOR EACH ROW INSERT INTO t2 VALUES (NEW.a);"); + + stmt_insert = mysql_stmt_init(mysql); + if (!stmt_insert) + { + fprintf(stderr, "mysql_stmt_init failed: Error: %s\n", + mysql_error(mysql)); + exit(1); + } + + rc= mysql_stmt_prepare(stmt_insert, insert_stmt, strlen(insert_stmt)); + if (rc) + { + fprintf(stderr, "mysql_stmt_prepare failed: %s\n", + mysql_stmt_error(stmt_insert)); + exit(1); + } + + memset(&bind[0], 0, sizeof(MYSQL_BIND)); + + bind[0].buffer_type= MYSQL_TYPE_LONG; + bind[0].buffer= vals; + + rc= mysql_stmt_attr_set(stmt_insert, STMT_ATTR_ARRAY_SIZE, &vals_array_len); + if (rc) + { + fprintf(stderr, "mysql_stmt_prepare failed: %s\n", + mysql_stmt_error(stmt_insert)); + exit(1); + } + + rc= mysql_stmt_bind_param(stmt_insert, bind); + if (rc) + { + fprintf(stderr, "mysql_stmt_bind_param failed: %s\n", + mysql_stmt_error(stmt_insert)); + exit(1); + } + + rc= mysql_stmt_execute(stmt_insert); + if (rc) + { + fprintf(stderr, "mysql_stmt_execute failed: %s\n", + mysql_stmt_error(stmt_insert)); + exit(1); + } + + /* + It's expected that the INSERT statement adds three rows into + the table t1 + */ + row_count = mysql_stmt_affected_rows(stmt_insert); + if (row_count != 3) + { + fprintf(stderr, "Wrong number of affected rows (%llu), expected 3\n", + row_count); + exit(1); + } + + /* + * Check that the AFTER INSERT trigger of the table t1 does work correct + * and inserted the rows (1), (2), (3) into the table t2. + */ + rc= mysql_query(mysql, "SELECT 't1' tname, a FROM t1 " + "UNION SELECT 't2' tname, a FROM t2 ORDER BY tname, a"); + if (rc) + { + fprintf(stderr, "Query failed: %s\n", mysql_error(mysql)); + } + + result= mysql_store_result(mysql); + + row= mysql_fetch_row(result); + DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 1); + + row= mysql_fetch_row(result); + DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 2); + + row= mysql_fetch_row(result); + DIE_UNLESS(strcmp(row[0], "t1") == 0 && atoi(row[1]) == 3); + + row= mysql_fetch_row(result); + DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 1); + + row= mysql_fetch_row(result); + DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 2); + + row= mysql_fetch_row(result); + DIE_UNLESS(strcmp(row[0], "t2") == 0 && atoi(row[1]) == 3); + + row= mysql_fetch_row(result); + DIE_UNLESS(row == NULL); + + mysql_free_result(result); + + mysql_stmt_close(stmt_insert); + + /* Clean up */ + rc= mysql_query(mysql, "DROP TABLE t1, t2"); + myquery(rc); +} #endif // EMBEDDED_LIBRARY /* @@ -22856,6 +22979,7 @@ static struct my_tests_st my_tests[]= { { "test_mdev_34718_au", test_mdev_34718_au }, { "test_mdev_34718_bd", test_mdev_34718_bd }, { "test_mdev_34718_ad", test_mdev_34718_ad }, + { "test_mdev_34958", test_mdev_34958 }, #endif { 0, 0 } }; From d1f42fc80ff81e39fc2443c40776f57253c02dd4 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 3 Dec 2024 14:03:17 +0400 Subject: [PATCH 04/11] MDEV-21589 AddressSanitizer: memcpy-param-overlap in Static_binary_string::q_append or String::append Item_func_concat_ws::val_str(): - collects the result into the string "str" passed as a parameter. - calls val_str(&tmp_buffer) to get arguments. At some point due to heuristic it decides to swap the buffers: - collect the result into &tmp_buffer - call val_str(str) to get arguments Item_func_password::val_str_ascii() returns a String pointing to its member tmp_value[SCRAMBLED_PASSWORD_CHAR_LENGTH+1]. As a result, it's possible that both str and tmp_buffer in Item_func_concat_ws::val_str() point to Item_func_password::tmp_value. Then, memcmp() called on overlapping memory fragrments. Fixing Item_func_password::val_str_ascii() to use Item::copy() instead of Item::set(). --- mysql-test/main/func_concat.result | 17 +++++++++++++++++ mysql-test/main/func_concat.test | 16 ++++++++++++++++ sql/item_strfunc.cc | 4 ++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/func_concat.result b/mysql-test/main/func_concat.result index 4303c97d35c..4b91fb97c6c 100644 --- a/mysql-test/main/func_concat.result +++ b/mysql-test/main/func_concat.result @@ -287,3 +287,20 @@ SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT MAKE_SET(3,t,t) t2 FROM t1) sub; c2 abcdefghi,abcdefghi-abcdefghi,abcdefghi DROP TABLE t1; +# Start of 10.5 tests +# +# MDEV-13120 Wrong results with MAKE_SET() and subquery +# +CREATE TABLE t1 (a DATE, b DATETIME, c VARCHAR(8)); +INSERT INTO t1 VALUES +('1996-03-06','1985-11-16 08:00:46','foo'), +('2028-08-26','1900-01-01 00:00:00','bar'), +('1973-05-04','1900-01-01 00:00:00','qux'); +SELECT CONCAT_WS(' ', a, b, PASSWORD(c)) AS f FROM t1 GROUP BY f WITH ROLLUP; +f +1973-05-04 1900-01-01 00:00:00 *6D720C5AAB5096E70AA751206B45B484E5E0121F +1996-03-06 1985-11-16 08:00:46 *F3A2A51A9B0F2BE2468926B4132313728C250DBF +2028-08-26 1900-01-01 00:00:00 *E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB +NULL +DROP TABLE t1; +# End of 10.5 tests diff --git a/mysql-test/main/func_concat.test b/mysql-test/main/func_concat.test index 44dea7e35b1..f93b150f88f 100644 --- a/mysql-test/main/func_concat.test +++ b/mysql-test/main/func_concat.test @@ -265,3 +265,19 @@ CREATE TABLE t1 (t VARCHAR(10) CHARSET latin1); INSERT INTO t1 VALUES('abcdefghi'); SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT MAKE_SET(3,t,t) t2 FROM t1) sub; DROP TABLE t1; + +--echo # Start of 10.5 tests + +--echo # +--echo # MDEV-13120 Wrong results with MAKE_SET() and subquery +--echo # + +CREATE TABLE t1 (a DATE, b DATETIME, c VARCHAR(8)); +INSERT INTO t1 VALUES +('1996-03-06','1985-11-16 08:00:46','foo'), +('2028-08-26','1900-01-01 00:00:00','bar'), +('1973-05-04','1900-01-01 00:00:00','qux'); +SELECT CONCAT_WS(' ', a, b, PASSWORD(c)) AS f FROM t1 GROUP BY f WITH ROLLUP; +DROP TABLE t1; + +--echo # End of 10.5 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 7e4ba259261..0e9c01c7a7e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2241,7 +2241,7 @@ String *Item_func_password::val_str_ascii(String *str) if (args[0]->null_value || res->length() == 0) return make_empty_result(str); my_make_scrambled_password(tmp_value, res->ptr(), res->length()); - str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1); + str->copy(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, &my_charset_latin1); break; case OLD: if ((null_value=args[0]->null_value)) @@ -2249,7 +2249,7 @@ String *Item_func_password::val_str_ascii(String *str) if (res->length() == 0) return make_empty_result(str); my_make_scrambled_password_323(tmp_value, res->ptr(), res->length()); - str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, &my_charset_latin1); + str->copy(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, &my_charset_latin1); break; default: DBUG_ASSERT(0); From 271b73770cd5bd13bb52bfa4dd91c8d275920467 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 13 Dec 2024 16:27:14 +0100 Subject: [PATCH 05/11] MDEV-30263 Assertion failure in Protocol::end_statement upon HANDLER READ with invalid timestamp Process save_in_field() return codes as in other places (<0 is real error) --- mysql-test/suite/handler/handler_warnings.result | 14 ++++++++++++++ mysql-test/suite/handler/handler_warnings.test | 15 +++++++++++++++ sql/sql_handler.cc | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/handler/handler_warnings.result create mode 100644 mysql-test/suite/handler/handler_warnings.test diff --git a/mysql-test/suite/handler/handler_warnings.result b/mysql-test/suite/handler/handler_warnings.result new file mode 100644 index 00000000000..f64f7cad76f --- /dev/null +++ b/mysql-test/suite/handler/handler_warnings.result @@ -0,0 +1,14 @@ +# +# MDEV-30263: --echo # Assertion failure in Protocol::end_statement +# upon HANDLER READ with invalid timestamp +# +CREATE TABLE t (a TIMESTAMP, KEY(a)); +HANDLER t OPEN; +HANDLER t READ a > ('2022-12'); +a +# above should issue the same warnings/errors as following +SELECT * from t WHERE t.a > ('2022-12'); +a +HANDLER t CLOSE; +DROP TABLE t; +End of 10.5 tests diff --git a/mysql-test/suite/handler/handler_warnings.test b/mysql-test/suite/handler/handler_warnings.test new file mode 100644 index 00000000000..b632381c1c0 --- /dev/null +++ b/mysql-test/suite/handler/handler_warnings.test @@ -0,0 +1,15 @@ +--echo # +--echo # MDEV-30263: --echo # Assertion failure in Protocol::end_statement +--echo # upon HANDLER READ with invalid timestamp +--echo # + +CREATE TABLE t (a TIMESTAMP, KEY(a)); +HANDLER t OPEN; +HANDLER t READ a > ('2022-12'); +--echo # above should issue the same warnings/errors as following +SELECT * from t WHERE t.a > ('2022-12'); +# Cleanup +HANDLER t CLOSE; +DROP TABLE t; + +--echo End of 10.5 tests diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index b1899e9969e..5938537b460 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -700,7 +700,7 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set); int res= item->save_in_field(key_part->field, 1); dbug_tmp_restore_column_map(&table->write_set, old_map); - if (res) + if (res < 0 || thd->is_error()) return 1; } key_len+= key_part->store_length; From e6403733897483bed249875f0f3e5e9937ca2b38 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Fri, 25 Oct 2024 14:35:22 +0700 Subject: [PATCH 06/11] Revert "MDEV-26427 MariaDB Server SEGV on INSERT .. SELECT" This reverts commit 49e14000eeb245ea27e9207d2f63cb0a28be1ca9 as it introduces regression MDEV-29935 and has to be reconsidered in general --- mysql-test/main/insert_select.result | 70 ----------- mysql-test/main/insert_select.test | 54 -------- mysql-test/main/view.result | 10 -- mysql-test/main/view.test | 2 - sql/sql_base.cc | 178 ++++++++------------------- sql/sql_insert.cc | 4 +- sql/sql_select.cc | 4 + sql/sql_select.h | 1 + 8 files changed, 59 insertions(+), 264 deletions(-) diff --git a/mysql-test/main/insert_select.result b/mysql-test/main/insert_select.result index 463f571b096..1f8c1f69b4b 100644 --- a/mysql-test/main/insert_select.result +++ b/mysql-test/main/insert_select.result @@ -883,76 +883,6 @@ INSERT INTO t1 SELECT a*2 FROM t1 ORDER BY a; Warnings: Warning 1264 Out of range value for column 'a' at row 4 DROP TABLE t1; -CREATE TABLE t1 (a INT, b INT); -INSERT INTO t1 (a) SELECT SUM(1); -INSERT INTO t1 (a, b) SELECT AVG(2), MIN(3); -INSERT INTO t1 (b) SELECT AVG('x') OVER (); -ERROR 22007: Truncated incorrect DOUBLE value: 'x' -INSERT INTO t1 SELECT MIN(7) OVER (), MAX(8) OVER(); -SELECT * FROM t1; -a b -1 NULL -2 3 -7 8 -PREPARE stmt FROM 'INSERT INTO t1 (a) SELECT AVG(?)'; -EXECUTE stmt USING 9; -EXECUTE stmt USING 10; -PREPARE stmt FROM 'INSERT INTO t1 SELECT MIN(?), MAX(?)'; -EXECUTE stmt USING 11, 12; -EXECUTE stmt USING 13, 14; -DEALLOCATE PREPARE stmt; -SELECT * FROM t1; -a b -1 NULL -2 3 -7 8 -9 NULL -10 NULL -11 12 -13 14 -CREATE PROCEDURE p1(param_a INT, param_b INT) -BEGIN -INSERT INTO t1 SELECT MIN(param_a) OVER (), MAX(param_b); -END// -CALL p1(21, 22); -CALL p1(23, 24); -SELECT * FROM t1; -a b -1 NULL -2 3 -7 8 -9 NULL -10 NULL -11 12 -13 14 -21 22 -23 24 -CREATE TABLE t2 ( -a DECIMAL UNIQUE CHECK (CASE 0 * 27302337.000000 WHEN 34 THEN -+ 'x' LIKE 'x' OR a NOT IN (-1 / TRUE ^ 2) ELSE 7105743.000000 END)); -INSERT INTO t2 VALUES (90),( -1),(31152443.000000),(-32768),(NULL),(NULL); -INSERT INTO t2 SELECT AVG('x') OVER ( -PARTITION BY ((NOT AVG(76698761.000000))) IS NOT NULL); -ERROR 22007: Truncated incorrect DOUBLE value: 'x' -INSERT IGNORE INTO t2 () VALUES (0),('x'),(3751286.000000), -('x'),((a = 'x' AND 0 AND 0)); -Warnings: -Warning 1366 Incorrect decimal value: 'x' for column `test`.`t2`.`a` at row 2 -Warning 1062 Duplicate entry '0' for key 'a' -Warning 1366 Incorrect decimal value: 'x' for column `test`.`t2`.`a` at row 4 -Warning 1062 Duplicate entry '0' for key 'a' -Warning 1062 Duplicate entry '0' for key 'a' -INSERT INTO t2 VALUES (127); -INSERT INTO t2 SELECT -2147483648 END FROM t2 AS TEXT JOIN t2 JOIN t2 TABLES; -ERROR 23000: Duplicate entry '-2147483648' for key 'a' -ALTER TABLE t2 ADD ( -b INT UNIQUE CHECK ((a = 'x' AND ((-(+(BINARY 49730460.000000)))) = 'x' -BETWEEN 'x' AND 'x'))); -ERROR 22007: Truncated incorrect DECIMAL value: 'x' -UPDATE t2 SET a = -128 WHERE a IS NULL ORDER BY 78 IN ('x','x'),a; -ERROR 23000: Duplicate entry '-128' for key 'a' -DROP TABLE t1, t2; -DROP PROCEDURE p1; # End of 10.2 test # # MDEV-28617: INSERT ... SELECT with redundant IN subquery in GROUP BY diff --git a/mysql-test/main/insert_select.test b/mysql-test/main/insert_select.test index a3604e38f34..7417bab9a61 100644 --- a/mysql-test/main/insert_select.test +++ b/mysql-test/main/insert_select.test @@ -459,60 +459,6 @@ INSERT INTO t1 SELECT a*2 FROM t1 ORDER BY a; DROP TABLE t1; -# -# MDEV-26427 MariaDB Server SEGV on INSERT .. SELECT -# -CREATE TABLE t1 (a INT, b INT); -INSERT INTO t1 (a) SELECT SUM(1); -INSERT INTO t1 (a, b) SELECT AVG(2), MIN(3); - ---error ER_TRUNCATED_WRONG_VALUE -INSERT INTO t1 (b) SELECT AVG('x') OVER (); -INSERT INTO t1 SELECT MIN(7) OVER (), MAX(8) OVER(); -SELECT * FROM t1; - -PREPARE stmt FROM 'INSERT INTO t1 (a) SELECT AVG(?)'; -EXECUTE stmt USING 9; -EXECUTE stmt USING 10; - -PREPARE stmt FROM 'INSERT INTO t1 SELECT MIN(?), MAX(?)'; -EXECUTE stmt USING 11, 12; -EXECUTE stmt USING 13, 14; -DEALLOCATE PREPARE stmt; -SELECT * FROM t1; - -DELIMITER //; -CREATE PROCEDURE p1(param_a INT, param_b INT) -BEGIN -INSERT INTO t1 SELECT MIN(param_a) OVER (), MAX(param_b); -END// -DELIMITER ;// -CALL p1(21, 22); -CALL p1(23, 24); -SELECT * FROM t1; - -CREATE TABLE t2 ( - a DECIMAL UNIQUE CHECK (CASE 0 * 27302337.000000 WHEN 34 THEN - + 'x' LIKE 'x' OR a NOT IN (-1 / TRUE ^ 2) ELSE 7105743.000000 END)); -INSERT INTO t2 VALUES (90),( -1),(31152443.000000),(-32768),(NULL),(NULL); ---error ER_TRUNCATED_WRONG_VALUE -INSERT INTO t2 SELECT AVG('x') OVER ( - PARTITION BY ((NOT AVG(76698761.000000))) IS NOT NULL); -INSERT IGNORE INTO t2 () VALUES (0),('x'),(3751286.000000), - ('x'),((a = 'x' AND 0 AND 0)); -INSERT INTO t2 VALUES (127); ---error ER_DUP_ENTRY -INSERT INTO t2 SELECT -2147483648 END FROM t2 AS TEXT JOIN t2 JOIN t2 TABLES; ---error ER_TRUNCATED_WRONG_VALUE -ALTER TABLE t2 ADD ( - b INT UNIQUE CHECK ((a = 'x' AND ((-(+(BINARY 49730460.000000)))) = 'x' - BETWEEN 'x' AND 'x'))); ---error ER_DUP_ENTRY -UPDATE t2 SET a = -128 WHERE a IS NULL ORDER BY 78 IN ('x','x'),a; - -DROP TABLE t1, t2; -DROP PROCEDURE p1; - --echo # End of 10.2 test --echo # diff --git a/mysql-test/main/view.result b/mysql-test/main/view.result index 74f64388b4a..3d3efd041c3 100644 --- a/mysql-test/main/view.result +++ b/mysql-test/main/view.result @@ -1503,8 +1503,6 @@ execute stmt1 using @a; set @a= 301; execute stmt1 using @a; deallocate prepare stmt1; -insert into v3(a) select sum(302); -insert into v3(a) select sum(303) over (); select * from v3; a b 100 0 @@ -1523,14 +1521,6 @@ a b 301 10 301 1000 301 2000 -302 0 -302 10 -302 1000 -302 2000 -303 0 -303 10 -303 1000 -303 2000 drop view v3; drop tables t1,t2; create table t1(f1 int); diff --git a/mysql-test/main/view.test b/mysql-test/main/view.test index 229fedddb5c..20aaba8e52a 100644 --- a/mysql-test/main/view.test +++ b/mysql-test/main/view.test @@ -1334,8 +1334,6 @@ execute stmt1 using @a; set @a= 301; execute stmt1 using @a; deallocate prepare stmt1; -insert into v3(a) select sum(302); -insert into v3(a) select sum(303) over (); --sorted_result select * from v3; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index de744edfbae..4f151d397d4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7708,39 +7708,6 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array, DBUG_RETURN(MY_TEST(thd->is_error())); } -/* - make list of leaves for a single TABLE_LIST - - SYNOPSIS - make_leaves_for_single_table() - thd Thread handler - leaves List of leaf tables to be filled - table TABLE_LIST object to process - full_table_list Whether to include tables from mergeable derived table/view -*/ -void make_leaves_for_single_table(THD *thd, List &leaves, - TABLE_LIST *table, bool& full_table_list, - TABLE_LIST *boundary) -{ - if (table == boundary) - full_table_list= !full_table_list; - if (full_table_list && table->is_merged_derived()) - { - SELECT_LEX *select_lex= table->get_single_select(); - /* - It's safe to use select_lex->leaf_tables because all derived - tables/views were already prepared and has their leaf_tables - set properly. - */ - make_leaves_list(thd, leaves, select_lex->get_table_list(), - full_table_list, boundary); - } - else - { - leaves.push_back(table, thd->mem_root); - } -} - /* Perform checks like all given fields exists, if exists fill struct with @@ -7767,79 +7734,40 @@ int setup_returning_fields(THD* thd, TABLE_LIST* table_list) SYNOPSIS make_leaves_list() - leaves List of leaf tables to be filled - tables Table list - full_table_list Whether to include tables from mergeable derived table/view. - We need them for checks for INSERT/UPDATE statements only. + list pointer to pointer on list first element + tables table list + full_table_list whether to include tables from mergeable derived table/view. + we need them for checks for INSERT/UPDATE statements only. + + RETURN pointer on pointer to next_leaf of last element */ -void make_leaves_list(THD *thd, List &leaves, TABLE_LIST *tables, +void make_leaves_list(THD *thd, List &list, TABLE_LIST *tables, bool full_table_list, TABLE_LIST *boundary) { for (TABLE_LIST *table= tables; table; table= table->next_local) { - make_leaves_for_single_table(thd, leaves, table, full_table_list, - boundary); + if (table == boundary) + full_table_list= !full_table_list; + if (full_table_list && table->is_merged_derived()) + { + SELECT_LEX *select_lex= table->get_single_select(); + /* + It's safe to use select_lex->leaf_tables because all derived + tables/views were already prepared and has their leaf_tables + set properly. + */ + make_leaves_list(thd, list, select_lex->get_table_list(), + full_table_list, boundary); + } + else + { + list.push_back(table, thd->mem_root); + } } } - -/* - Setup the map and other attributes for a single TABLE_LIST object - - SYNOPSIS - setup_table_attributes() - thd Thread handler - table_list TABLE_LIST object to process - first_select_table First table participating in SELECT for INSERT..SELECT - statements, NULL for other cases - tablenr Serial number of the table in the SQL statement - - RETURN - false Success - true Failure -*/ -bool setup_table_attributes(THD *thd, TABLE_LIST *table_list, - TABLE_LIST *first_select_table, - uint &tablenr) -{ - TABLE *table= table_list->table; - if (table) - table->pos_in_table_list= table_list; - if (first_select_table && table_list->top_table() == first_select_table) - { - /* new counting for SELECT of INSERT ... SELECT command */ - first_select_table= 0; - thd->lex->first_select_lex()->insert_tables= tablenr; - tablenr= 0; - } - if (table_list->jtbm_subselect) - { - table_list->jtbm_table_no= tablenr; - } - else if (table) - { - table->pos_in_table_list= table_list; - setup_table_map(table, table_list, tablenr); - - if (table_list->process_index_hints(table)) - return true; - } - tablenr++; - /* - We test the max tables here as we setup_table_map() should not be called - with tablenr >= 64 - */ - if (tablenr > MAX_TABLES) - { - my_error(ER_TOO_MANY_TABLES, MYF(0), static_cast(MAX_TABLES)); - return true; - } - return false; -} - - /* prepare tables @@ -7896,14 +7824,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, leaves.empty(); if (select_lex->prep_leaf_list_state != SELECT_LEX::SAVED) { - /* - For INSERT ... SELECT statements we must not include the first table - (where the data is being inserted into) in the list of leaves - */ - TABLE_LIST *tables_for_leaves= - select_insert ? first_select_table : tables; - make_leaves_list(thd, leaves, tables_for_leaves, full_table_list, - first_select_table); + make_leaves_list(thd, leaves, tables, full_table_list, first_select_table); select_lex->prep_leaf_list_state= SELECT_LEX::READY; select_lex->leaf_tables_exec.empty(); } @@ -7914,34 +7835,37 @@ bool setup_tables(THD *thd, Name_resolution_context *context, leaves.push_back(table_list, thd->mem_root); } - List_iterator ti(leaves); while ((table_list= ti++)) { - if (setup_table_attributes(thd, table_list, first_select_table, tablenr)) - DBUG_RETURN(1); - } - - if (select_insert) - { - /* - The table/view in which the data is inserted must not be included into - the leaf_tables list. But we need this table/view to setup attributes - for it. So build a temporary list of leaves and setup attributes for - the tables included - */ - List leaves; - TABLE_LIST *table= tables; - - make_leaves_for_single_table(thd, leaves, table, full_table_list, - first_select_table); - - List_iterator ti(leaves); - while ((table_list= ti++)) + TABLE *table= table_list->table; + if (table) + table->pos_in_table_list= table_list; + if (first_select_table && + table_list->top_table() == first_select_table) { - if (setup_table_attributes(thd, table_list, first_select_table, - tablenr)) + /* new counting for SELECT of INSERT ... SELECT command */ + first_select_table= 0; + thd->lex->select_lex.insert_tables= tablenr; + tablenr= 0; + } + if(table_list->jtbm_subselect) + { + table_list->jtbm_table_no= tablenr; + } + else if (table) + { + table->pos_in_table_list= table_list; + setup_table_map(table, table_list, tablenr); + + if (table_list->process_index_hints(table)) DBUG_RETURN(1); } + tablenr++; + } + if (tablenr > MAX_TABLES) + { + my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast(MAX_TABLES)); + DBUG_RETURN(1); } } else diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 18c364c7fea..0a08866c5fa 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1570,7 +1570,8 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, if (insert_into_view && !fields.elements) { thd->lex->empty_field_list_on_rset= 1; - if (!table_list->table || table_list->is_multitable()) + if (!thd->lex->select_lex.leaf_tables.head()->table || + table_list->is_multitable()) { my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0), table_list->view_db.str, table_list->view_name.str); @@ -3855,6 +3856,7 @@ int mysql_insert_select_prepare(THD *thd, select_result *sel_res) if (sel_res) sel_res->prepare(lex->returning()->item_list, NULL); + DBUG_ASSERT(select_lex->leaf_tables.elements != 0); List_iterator ti(select_lex->leaf_tables); TABLE_LIST *table; uint insert_tables; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d75a3bbcd4c..f0da265f86b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1957,6 +1957,7 @@ JOIN::optimize_inner() /* Merge all mergeable derived tables/views in this SELECT. */ if (select_lex->handle_derived(thd->lex, DT_MERGE)) DBUG_RETURN(TRUE); + table_count= select_lex->leaf_tables.elements; } if (select_lex->first_cond_optimization && @@ -1999,6 +2000,8 @@ JOIN::optimize_inner() eval_select_list_used_tables(); + table_count= select_lex->leaf_tables.elements; + if (select_lex->options & OPTION_SCHEMA_TABLE && optimize_schema_tables_memory_usage(select_lex->leaf_tables)) DBUG_RETURN(1); @@ -14320,6 +14323,7 @@ void JOIN::cleanup(bool full) /* Free the original optimized join created for the group_by_handler */ join_tab= original_join_tab; original_join_tab= 0; + table_count= original_table_count; } if (join_tab) diff --git a/sql/sql_select.h b/sql/sql_select.h index ca34e4a0261..314cac452f2 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1306,6 +1306,7 @@ public: Pushdown_query *pushdown_query; JOIN_TAB *original_join_tab; + uint original_table_count; /******* Join optimization state members start *******/ /* From d98ac8511e39770ef3d8b42937c84e876d1459e7 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Sat, 26 Oct 2024 20:29:56 +0700 Subject: [PATCH 07/11] MDEV-26247 MariaDB Server SEGV on INSERT .. SELECT This problem occured for statements like `INSERT INTO t1 SELECT 1`, which do not have tables in the SELECT part. In such scenarios SELECT_LEX::insert_tables was not properly set at `setup_tables()`, and this led to either incorrect execution or a crash Reviewer: Oleksandr Byelkin --- mysql-test/main/insert_select.result | 49 ++++++++++++++++++++++++++++ mysql-test/main/insert_select.test | 35 ++++++++++++++++++++ sql/sql_base.cc | 18 +++++++--- sql/sql_insert.cc | 2 +- 4 files changed, 99 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/insert_select.result b/mysql-test/main/insert_select.result index 1f8c1f69b4b..35c7880fa5f 100644 --- a/mysql-test/main/insert_select.result +++ b/mysql-test/main/insert_select.result @@ -984,3 +984,52 @@ drop table t1, t2; # # End of 10.3 test # +# +# MDEV-26427 MariaDB Server SEGV on INSERT .. SELECT +# +CREATE TABLE t1 (a int); +INSERT INTO t1 SELECT AVG(1); +SELECT * FROM t1; +a +1 +INSERT INTO t1 SELECT MIN(2) OVER (); +SELECT * FROM t1; +a +1 +2 +CREATE VIEW v1 AS SELECT * FROM t1 ORDER BY a; +INSERT INTO v1 SELECT SUM(3); +SELECT * FROM v1; +a +1 +2 +3 +INSERT INTO v1 SELECT * FROM v1; +SELECT * FROM t1; +a +1 +1 +2 +2 +3 +3 +INSERT INTO t1 SELECT * FROM v1; +SELECT * FROM t1; +a +1 +1 +1 +1 +2 +2 +2 +2 +3 +3 +3 +3 +DROP VIEW v1; +DROP TABLE t1; +# +# End of 10.5 test +# diff --git a/mysql-test/main/insert_select.test b/mysql-test/main/insert_select.test index 7417bab9a61..0e9bd05a93e 100644 --- a/mysql-test/main/insert_select.test +++ b/mysql-test/main/insert_select.test @@ -559,3 +559,38 @@ drop table t1, t2; --echo # --echo # End of 10.3 test --echo # + +--echo # +--echo # MDEV-26427 MariaDB Server SEGV on INSERT .. SELECT +--echo # + +CREATE TABLE t1 (a int); + +INSERT INTO t1 SELECT AVG(1); +--sorted_result +SELECT * FROM t1; + +INSERT INTO t1 SELECT MIN(2) OVER (); +--sorted_result +SELECT * FROM t1; + +CREATE VIEW v1 AS SELECT * FROM t1 ORDER BY a; + +INSERT INTO v1 SELECT SUM(3); +--sorted_result +SELECT * FROM v1; + +INSERT INTO v1 SELECT * FROM v1; +--sorted_result +SELECT * FROM t1; + +INSERT INTO t1 SELECT * FROM v1; +--sorted_result +SELECT * FROM t1; + +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # End of 10.5 test +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4f151d397d4..bcab54ac1ec 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7834,18 +7834,19 @@ bool setup_tables(THD *thd, Name_resolution_context *context, while ((table_list= ti++)) leaves.push_back(table_list, thd->mem_root); } - + + bool is_insert_tables_num_set= false; while ((table_list= ti++)) { TABLE *table= table_list->table; if (table) table->pos_in_table_list= table_list; - if (first_select_table && + if (select_insert && !is_insert_tables_num_set && table_list->top_table() == first_select_table) { /* new counting for SELECT of INSERT ... SELECT command */ - first_select_table= 0; - thd->lex->select_lex.insert_tables= tablenr; + thd->lex->first_select_lex()->insert_tables= tablenr; + is_insert_tables_num_set= true; tablenr= 0; } if(table_list->jtbm_subselect) @@ -7867,6 +7868,15 @@ bool setup_tables(THD *thd, Name_resolution_context *context, my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast(MAX_TABLES)); DBUG_RETURN(1); } + if (select_insert && !is_insert_tables_num_set) + { + /* + This happens for statements like `INSERT INTO t1 SELECT 1`, + when there are no tables in the SELECT part. + In this case all leaf tables belong to the INSERT part + */ + thd->lex->first_select_lex()->insert_tables= tablenr; + } } else { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0a08866c5fa..e1d87e29869 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1570,7 +1570,7 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list, if (insert_into_view && !fields.elements) { thd->lex->empty_field_list_on_rset= 1; - if (!thd->lex->select_lex.leaf_tables.head()->table || + if (!thd->lex->first_select_lex()->leaf_tables.head()->table || table_list->is_multitable()) { my_error(ER_VIEW_NO_INSERT_FIELD_LIST, MYF(0), From 17cb65593ae4b5c606aee8525c5ff46ffabff630 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 20 Apr 2024 00:17:30 +0200 Subject: [PATCH 08/11] MDEV-22964: archive.archive and main.mysqlbinlog_{row,stmt}_compressed) zlib-ng results in different compression length. The compression length isn't that important as the test output examines the uncompressed results. fixes for zlib-ng backport of 75488a57f23b99f5d531366c4717e2ce63cebd7e --- .../main/mysqlbinlog_row_compressed.result | 192 +++++++++--------- .../main/mysqlbinlog_row_compressed.test | 3 +- .../main/mysqlbinlog_stmt_compressed.result | 128 ++++++------ .../main/mysqlbinlog_stmt_compressed.test | 3 +- mysql-test/suite/archive/archive.test | 2 +- 5 files changed, 163 insertions(+), 165 deletions(-) diff --git a/mysql-test/main/mysqlbinlog_row_compressed.result b/mysql-test/main/mysqlbinlog_row_compressed.result index 39be61ba916..193036de2b4 100644 --- a/mysql-test/main/mysqlbinlog_row_compressed.result +++ b/mysql-test/main/mysqlbinlog_row_compressed.result @@ -15,21 +15,21 @@ FLUSH BINARY LOGS; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; -# at 4 -# server id 1 end_log_pos 256 CRC32 XXX Start: xxx +# at +# server id 1 end_log_pos CRC32 XXX Start: xxx ROLLBACK/*!*/; -# at 256 -# server id 1 end_log_pos 285 CRC32 XXX Gtid list [] -# at 285 -# server id 1 end_log_pos 329 CRC32 XXX Binlog checkpoint master-bin.000001 -# at 329 -# server id 1 end_log_pos 371 CRC32 XXX GTID 0-1-1 ddl +# at +# server id 1 end_log_pos CRC32 XXX Gtid list [] +# at +# server id 1 end_log_pos CRC32 XXX Binlog checkpoint master-bin.000001 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-1 ddl /*M!100101 SET @@session.skip_parallel_replication=0*//*!*/; /*M!100001 SET @@session.gtid_domain_id=0*//*!*/; /*M!100001 SET @@session.server_id=1*//*!*/; /*M!100001 SET @@session.gtid_seq_no=1*//*!*/; -# at 371 -# server id 1 end_log_pos 533 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 use `test`/*!*/; SET TIMESTAMP=X/*!*/; SET @@session.pseudo_thread_id=5/*!*/; @@ -42,26 +42,26 @@ SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; CREATE TABLE t1 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 TINYINT, f4 MEDIUMINT, f5 BIGINT, f6 INT, f7 INT, f8 char(1)) /*!*/; -# at 533 -# server id 1 end_log_pos 575 CRC32 XXX GTID 0-1-2 ddl +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-2 ddl /*M!100001 SET @@session.gtid_seq_no=2*//*!*/; -# at 575 -# server id 1 end_log_pos 727 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; CREATE TABLE t2 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 INT, f4 INT, f5 MEDIUMINT, f6 INT, f7 INT, f8 char(1)) /*!*/; -# at 727 -# server id 1 end_log_pos 769 CRC32 XXX GTID 0-1-3 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-3 /*M!100001 SET @@session.gtid_seq_no=3*//*!*/; START TRANSACTION /*!*/; -# at 769 -# at 843 -# server id 1 end_log_pos 843 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t1 VALUES (10, 1, 2, 3, 4, 5, 6, 7, "") -# server id 1 end_log_pos 899 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 899 -# server id 1 end_log_pos 967 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -74,23 +74,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 1 -# at 967 -# server id 1 end_log_pos 1040 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1040 -# server id 1 end_log_pos 1082 CRC32 XXX GTID 0-1-4 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-4 /*M!100001 SET @@session.gtid_seq_no=4*//*!*/; START TRANSACTION /*!*/; -# at 1082 -# at 1158 -# server id 1 end_log_pos 1158 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t1 VALUES (11, 1, 2, 3, 4, 5, 6, 7, NULL) -# server id 1 end_log_pos 1214 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 1214 -# server id 1 end_log_pos 1281 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=11 /* INT meta=0 nullable=0 is_null=0 */ @@ -103,23 +103,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9=NULL /* STRING(1) meta=65025 nullable=1 is_null=1 */ # Number of rows: 1 -# at 1281 -# server id 1 end_log_pos 1354 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1354 -# server id 1 end_log_pos 1396 CRC32 XXX GTID 0-1-5 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-5 /*M!100001 SET @@session.gtid_seq_no=5*//*!*/; START TRANSACTION /*!*/; -# at 1396 -# at 1474 -# server id 1 end_log_pos 1474 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t1 VALUES (12, 1, 2, 3, NULL, 5, 6, 7, "A") -# server id 1 end_log_pos 1530 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 1530 -# server id 1 end_log_pos 1596 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=12 /* INT meta=0 nullable=0 is_null=0 */ @@ -132,23 +132,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 1 -# at 1596 -# server id 1 end_log_pos 1669 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1669 -# server id 1 end_log_pos 1711 CRC32 XXX GTID 0-1-6 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-6 /*M!100001 SET @@session.gtid_seq_no=6*//*!*/; START TRANSACTION /*!*/; -# at 1711 -# at 1786 -# server id 1 end_log_pos 1786 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t1 VALUES (13, 1, 2, 3, 0, 5, 6, 7, "A") -# server id 1 end_log_pos 1842 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 1842 -# server id 1 end_log_pos 1909 CRC32 XXX Write_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t1` ### SET ### @1=13 /* INT meta=0 nullable=0 is_null=0 */ @@ -161,23 +161,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 1 -# at 1909 -# server id 1 end_log_pos 1982 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1982 -# server id 1 end_log_pos 2024 CRC32 XXX GTID 0-1-7 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-7 /*M!100001 SET @@session.gtid_seq_no=7*//*!*/; START TRANSACTION /*!*/; -# at 2024 -# at 2078 -# server id 1 end_log_pos 2078 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> INSERT INTO t2 SELECT * FROM t1 -# server id 1 end_log_pos 2134 CRC32 XXX Table_map: `test`.`t2` mapped to number num -# at 2134 -# server id 1 end_log_pos 2225 CRC32 XXX Write_compressed_rows: table id 33 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t2` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Write_compressed_rows: table id flags: STMT_END_F ### INSERT INTO `test`.`t2` ### SET ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -223,23 +223,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 4 -# at 2225 -# server id 1 end_log_pos 2298 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2298 -# server id 1 end_log_pos 2340 CRC32 XXX GTID 0-1-8 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-8 /*M!100001 SET @@session.gtid_seq_no=8*//*!*/; START TRANSACTION /*!*/; -# at 2340 -# at 2406 -# server id 1 end_log_pos 2406 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> UPDATE t2 SET f4=5 WHERE f4>0 or f4 is NULL -# server id 1 end_log_pos 2462 CRC32 XXX Table_map: `test`.`t2` mapped to number num -# at 2462 -# server id 1 end_log_pos 2561 CRC32 XXX Update_compressed_rows: table id 33 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t2` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Update_compressed_rows: table id flags: STMT_END_F ### UPDATE `test`.`t2` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -304,23 +304,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 3 -# at 2561 -# server id 1 end_log_pos 2634 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2634 -# server id 1 end_log_pos 2676 CRC32 XXX GTID 0-1-9 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-9 /*M!100001 SET @@session.gtid_seq_no=9*//*!*/; START TRANSACTION /*!*/; -# at 2676 -# at 2713 -# server id 1 end_log_pos 2713 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> DELETE FROM t1 -# server id 1 end_log_pos 2769 CRC32 XXX Table_map: `test`.`t1` mapped to number num -# at 2769 -# server id 1 end_log_pos 2861 CRC32 XXX Delete_compressed_rows: table id 32 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t1` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Delete_compressed_rows: table id flags: STMT_END_F ### DELETE FROM `test`.`t1` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -366,23 +366,23 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 4 -# at 2861 -# server id 1 end_log_pos 2934 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2934 -# server id 1 end_log_pos 2976 CRC32 XXX GTID 0-1-10 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-10 /*M!100001 SET @@session.gtid_seq_no=10*//*!*/; START TRANSACTION /*!*/; -# at 2976 -# at 3013 -# server id 1 end_log_pos 3013 CRC32 XXX Annotate_rows: +# at +# at +# server id 1 end_log_pos CRC32 XXX Annotate_rows: #Q> DELETE FROM t2 -# server id 1 end_log_pos 3069 CRC32 XXX Table_map: `test`.`t2` mapped to number num -# at 3069 -# server id 1 end_log_pos 3154 CRC32 XXX Delete_compressed_rows: table id 33 flags: STMT_END_F +# server id 1 end_log_pos CRC32 XXX Table_map: `test`.`t2` mapped to number num +# at +# server id 1 end_log_pos CRC32 XXX Delete_compressed_rows: table id flags: STMT_END_F ### DELETE FROM `test`.`t2` ### WHERE ### @1=10 /* INT meta=0 nullable=0 is_null=0 */ @@ -428,13 +428,13 @@ START TRANSACTION ### @8=7 /* INT meta=0 nullable=1 is_null=0 */ ### @9='A' /* STRING(1) meta=65025 nullable=1 is_null=0 */ # Number of rows: 4 -# at 3154 -# server id 1 end_log_pos 3227 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 3227 -# server id 1 end_log_pos 3275 CRC32 XXX Rotate to master-bin.000002 pos: 4 +# at +# server id 1 end_log_pos CRC32 XXX Rotate to master-bin.000002 pos: 4 DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/main/mysqlbinlog_row_compressed.test b/mysql-test/main/mysqlbinlog_row_compressed.test index f493c4db2cd..5abed1a7e77 100644 --- a/mysql-test/main/mysqlbinlog_row_compressed.test +++ b/mysql-test/main/mysqlbinlog_row_compressed.test @@ -4,7 +4,6 @@ --source include/have_log_bin.inc --source include/have_binlog_format_row.inc ---source include/have_normal_zlib.inc # # @@ -30,7 +29,7 @@ DELETE FROM t2; FLUSH BINARY LOGS; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /mapped to number \d*/mapped to number num/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/ +--replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /mapped to number \d*/mapped to number num/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/ /xid=\d*/xid=/ /table id \d+/table id / /end_log_pos \d+/end_log_pos / /# at \d+/# at / --exec $MYSQL_BINLOG --verbose --verbose --base64-output=DECODE-ROWS $datadir/$binlog --echo diff --git a/mysql-test/main/mysqlbinlog_stmt_compressed.result b/mysql-test/main/mysqlbinlog_stmt_compressed.result index cb9f2c63ca1..be0c1400700 100644 --- a/mysql-test/main/mysqlbinlog_stmt_compressed.result +++ b/mysql-test/main/mysqlbinlog_stmt_compressed.result @@ -15,21 +15,21 @@ FLUSH BINARY LOGS; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; -# at 4 -# server id 1 end_log_pos 256 CRC32 XXX Start: xxx +# at +# server id 1 end_log_pos CRC32 XXX Start: xxx ROLLBACK/*!*/; -# at 256 -# server id 1 end_log_pos 285 CRC32 XXX Gtid list [] -# at 285 -# server id 1 end_log_pos 329 CRC32 XXX Binlog checkpoint master-bin.000001 -# at 329 -# server id 1 end_log_pos 371 CRC32 XXX GTID 0-1-1 ddl +# at +# server id 1 end_log_pos CRC32 XXX Gtid list [] +# at +# server id 1 end_log_pos CRC32 XXX Binlog checkpoint master-bin.000001 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-1 ddl /*M!100101 SET @@session.skip_parallel_replication=0*//*!*/; /*M!100001 SET @@session.gtid_domain_id=0*//*!*/; /*M!100001 SET @@session.server_id=1*//*!*/; /*M!100001 SET @@session.gtid_seq_no=1*//*!*/; -# at 371 -# server id 1 end_log_pos 533 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 use `test`/*!*/; SET TIMESTAMP=X/*!*/; SET @@session.pseudo_thread_id=5/*!*/; @@ -42,136 +42,136 @@ SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; CREATE TABLE t1 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 TINYINT, f4 MEDIUMINT, f5 BIGINT, f6 INT, f7 INT, f8 char(1)) /*!*/; -# at 533 -# server id 1 end_log_pos 575 CRC32 XXX GTID 0-1-2 ddl +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-2 ddl /*M!100001 SET @@session.gtid_seq_no=2*//*!*/; -# at 575 -# server id 1 end_log_pos 727 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; CREATE TABLE t2 (pk INT PRIMARY KEY, f1 INT, f2 INT, f3 INT, f4 INT, f5 MEDIUMINT, f6 INT, f7 INT, f8 char(1)) /*!*/; -# at 727 -# server id 1 end_log_pos 769 CRC32 XXX GTID 0-1-3 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-3 /*M!100001 SET @@session.gtid_seq_no=3*//*!*/; START TRANSACTION /*!*/; -# at 769 -# server id 1 end_log_pos 897 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; INSERT INTO t1 VALUES (10, 1, 2, 3, 4, 5, 6, 7, "") /*!*/; -# at 897 -# server id 1 end_log_pos 970 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 970 -# server id 1 end_log_pos 1012 CRC32 XXX GTID 0-1-4 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-4 /*M!100001 SET @@session.gtid_seq_no=4*//*!*/; START TRANSACTION /*!*/; -# at 1012 -# server id 1 end_log_pos 1140 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; INSERT INTO t1 VALUES (11, 1, 2, 3, 4, 5, 6, 7, NULL) /*!*/; -# at 1140 -# server id 1 end_log_pos 1213 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1213 -# server id 1 end_log_pos 1255 CRC32 XXX GTID 0-1-5 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-5 /*M!100001 SET @@session.gtid_seq_no=5*//*!*/; START TRANSACTION /*!*/; -# at 1255 -# server id 1 end_log_pos 1385 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; INSERT INTO t1 VALUES (12, 1, 2, 3, NULL, 5, 6, 7, "A") /*!*/; -# at 1385 -# server id 1 end_log_pos 1458 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1458 -# server id 1 end_log_pos 1500 CRC32 XXX GTID 0-1-6 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-6 /*M!100001 SET @@session.gtid_seq_no=6*//*!*/; START TRANSACTION /*!*/; -# at 1500 -# server id 1 end_log_pos 1627 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; INSERT INTO t1 VALUES (13, 1, 2, 3, 0, 5, 6, 7, "A") /*!*/; -# at 1627 -# server id 1 end_log_pos 1700 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1700 -# server id 1 end_log_pos 1742 CRC32 XXX GTID 0-1-7 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-7 /*M!100001 SET @@session.gtid_seq_no=7*//*!*/; START TRANSACTION /*!*/; -# at 1742 -# server id 1 end_log_pos 1850 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; INSERT INTO t2 SELECT * FROM t1 /*!*/; -# at 1850 -# server id 1 end_log_pos 1923 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 1923 -# server id 1 end_log_pos 1965 CRC32 XXX GTID 0-1-8 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-8 /*M!100001 SET @@session.gtid_seq_no=8*//*!*/; START TRANSACTION /*!*/; -# at 1965 -# server id 1 end_log_pos 2082 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; UPDATE t2 SET f4=5 WHERE f4>0 or f4 is NULL /*!*/; -# at 2082 -# server id 1 end_log_pos 2155 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2155 -# server id 1 end_log_pos 2197 CRC32 XXX GTID 0-1-9 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-9 /*M!100001 SET @@session.gtid_seq_no=9*//*!*/; START TRANSACTION /*!*/; -# at 2197 -# server id 1 end_log_pos 2288 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; DELETE FROM t1 /*!*/; -# at 2288 -# server id 1 end_log_pos 2361 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2361 -# server id 1 end_log_pos 2403 CRC32 XXX GTID 0-1-10 +# at +# server id 1 end_log_pos CRC32 XXX GTID 0-1-10 /*M!100001 SET @@session.gtid_seq_no=10*//*!*/; START TRANSACTION /*!*/; -# at 2403 -# server id 1 end_log_pos 2494 CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query_compressed thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; DELETE FROM t2 /*!*/; -# at 2494 -# server id 1 end_log_pos 2567 CRC32 XXX Query thread_id=5 exec_time=x error_code=0 +# at +# server id 1 end_log_pos CRC32 XXX Query thread_id=5 exec_time=x error_code=0 SET TIMESTAMP=X/*!*/; COMMIT /*!*/; -# at 2567 -# server id 1 end_log_pos 2615 CRC32 XXX Rotate to master-bin.000002 pos: 4 +# at +# server id 1 end_log_pos CRC32 XXX Rotate to master-bin.000002 pos: 4 DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; diff --git a/mysql-test/main/mysqlbinlog_stmt_compressed.test b/mysql-test/main/mysqlbinlog_stmt_compressed.test index 1f1591e7a00..5c3fb58c50c 100644 --- a/mysql-test/main/mysqlbinlog_stmt_compressed.test +++ b/mysql-test/main/mysqlbinlog_stmt_compressed.test @@ -4,7 +4,6 @@ --source include/have_log_bin.inc --source include/have_binlog_format_statement.inc ---source include/have_normal_zlib.inc # # # mysqlbinlog: compressed query event @@ -29,7 +28,7 @@ DELETE FROM t2; FLUSH BINARY LOGS; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR ---replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /mapped to number \d*/mapped to number num/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/ +--replace_regex /\d{6} *\d*:\d\d:\d\d// /Start:.*at startup/Start: xxx/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /mapped to number \d*/mapped to number num/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /@@session.sql_mode=\d+/@@session.sql_mode=#/ /collation_server=\d+/collation_server=#/ /xid=\d*/xid=/ /table id \d+/table id / /end_log_pos \d+/end_log_pos / /# at \d+/# at / --exec $MYSQL_BINLOG --verbose --verbose --base64-output=DECODE-ROWS $datadir/$binlog --echo diff --git a/mysql-test/suite/archive/archive.test b/mysql-test/suite/archive/archive.test index 38bee206ef2..94a6e0c48bd 100644 --- a/mysql-test/suite/archive/archive.test +++ b/mysql-test/suite/archive/archive.test @@ -1613,7 +1613,7 @@ SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; INSERT INTO t1 VALUES(1, 'sampleblob1'),(2, 'sampleblob2'); # Compression length depends on zip library ---replace_result 583 584 291 292 +--replace_result 583 584 585 584 291 292 SELECT DATA_LENGTH, AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1' AND TABLE_SCHEMA='test'; DROP TABLE t1; From aa49770d795af9f1848aabf737443c227b991ed4 Mon Sep 17 00:00:00 2001 From: Lena Startseva Date: Mon, 21 Oct 2024 12:21:51 +0700 Subject: [PATCH 09/11] MDEV-31005: Make working cursor-protocol Excluded cases in main./secure_file_priv_win Fix for v.10.5 --- mysql-test/main/secure_file_priv_win.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/secure_file_priv_win.test b/mysql-test/main/secure_file_priv_win.test index 60fc8e29b6e..2130b1f84e9 100644 --- a/mysql-test/main/secure_file_priv_win.test +++ b/mysql-test/main/secure_file_priv_win.test @@ -13,10 +13,11 @@ LET $MYSQL_TMP_DIR_UCASE= `SELECT upper('$MYSQL_TMP_DIR')`; LET $MYSQL_TMP_DIR_LCASE= `SELECT lower('$MYSQL_TMP_DIR')`; --disable_ps2_protocol - +--disable_cursor_protocol #create the file --replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR/B11764517.tmp'; +--enable_cursor_protocol --replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR show global variables like 'secure_file_priv'; @@ -52,6 +53,7 @@ eval LOAD DATA INFILE '$MYSQL_TMP_DIR_LCASE/B11764517.tmp' INTO TABLE t1; --error ER_OPTION_PREVENTS_STATEMENT eval LOAD DATA INFILE "$MYSQL_TMP_DIR\\\\..a..\\\\..\\\\..\\\\B11764517.tmp" into table t1; +--disable_cursor_protocol --replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR --error ER_OPTION_PREVENTS_STATEMENT eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR\\\\..a..\\\\..\\\\..\\\\B11764517-2.tmp'; @@ -67,6 +69,7 @@ eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR_UCASE/B11764517-4.tmp'; --replace_result $MYSQL_TMP_DIR_LCASE MYSQL_TMP_DIR_LCASE eval SELECT * FROM t1 INTO OUTFILE '$MYSQL_TMP_DIR_LCASE/B11764517-5.tmp'; +--enable_cursor_protocol --error 0,1 --remove_file $MYSQL_TMP_DIR/B11764517.tmp; From bc6121819cf648237d0c2c63e48d53acf816db76 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Mon, 16 Dec 2024 19:34:09 +0200 Subject: [PATCH 10/11] MDEV-35098 rpl.rpl_mysqldump_gtid_slave_pos fails in buildbot The test turns out to be senstive to @@global.gtid_cleanup_batch_size. With a rather small default value of the latter SELECTing from mysql.gtid_slave_pos may not be deterministic: tests that run before may increase a pending for automitic deletion batch. The test is refined to set its own value for the batch size which is virtually unreachable. Thanks to Kristian Nielsen for the analysis. --- .../suite/rpl/r/rpl_mysqldump_gtid_slave_pos.result | 4 ++++ mysql-test/suite/rpl/t/rpl_mysqldump_gtid_slave_pos.test | 8 ++++++++ 2 files changed, 12 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 1849f896758..9340498c537 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 @@ -32,6 +32,7 @@ insert into t1 set a = 2; insert into t1 set a = 1; include/save_master_gtid.inc connection slave; +SET @@global.gtid_cleanup_batch_size = $val; include/start_slave.inc include/sync_with_master_gtid.inc select * from mysql.gtid_slave_pos; @@ -55,6 +56,7 @@ set statement sql_log_bin=0 for delete from mysql.gtid_slave_pos; insert into mysql.gtid_slave_pos values (99 + 2, 1, 1, 1); # 5. include/rpl_restart_server.inc [server_number=2] +SET @@global.gtid_cleanup_batch_size = $val; select * from mysql.gtid_slave_pos; domain_id sub_id server_id seq_no 101 1 1 1 @@ -99,6 +101,7 @@ set statement sql_log_bin=0 for delete from mysql.gtid_slave_pos; insert into mysql.gtid_slave_pos values (99 + 1, 1, 1, 1); # 5. include/rpl_restart_server.inc [server_number=2] +SET @@global.gtid_cleanup_batch_size = $val; select * from mysql.gtid_slave_pos; domain_id sub_id server_id seq_no 100 1 1 1 @@ -145,5 +148,6 @@ connection master; DROP TABLE t1; include/save_master_gtid.inc connection slave; +SET @@global.gtid_cleanup_batch_size= $old_gtid_cleanup_batch_size; include/sync_with_master_gtid.inc include/rpl_end.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 e66a92a6153..820fc56134b 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 @@ -47,6 +47,12 @@ while ($i) --source include/save_master_gtid.inc --connection slave +# enforce determistic SELECT * from mysql.gtid_slave_pos +--let $old_gtid_cleanup_batch_size = `select @@GLOBAL.gtid_cleanup_batch_size` +# the number of generated transactions on master must not exceed this value: +--let $val= 2147483647 +--evalp SET @@global.gtid_cleanup_batch_size = $val + --source include/start_slave.inc --source include/sync_with_master_gtid.inc # Prior tests in a mtr batch could leave the min value of sub_id column with @@ -85,6 +91,7 @@ while ($i) --echo # 5. --let $rpl_server_number= 2 --source include/rpl_restart_server.inc + --evalp SET @@global.gtid_cleanup_batch_size = $val select * from mysql.gtid_slave_pos; select @@global.gtid_slave_pos as "before dump restore"; --let $dump=dump_$i.sql @@ -130,6 +137,7 @@ DROP TABLE t1; --source include/save_master_gtid.inc --connection slave +--evalp SET @@global.gtid_cleanup_batch_size= $old_gtid_cleanup_batch_size --remove_files_wildcard $MYSQLTEST_VARDIR/tmp dump_*.sql --source include/sync_with_master_gtid.inc From 77c991766330ac995666afe25e5d03cdca6fe004 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Tue, 17 Dec 2024 10:40:57 +1100 Subject: [PATCH 11/11] MDEV-34716 Fix mysql.servers socket max length too short The limit of socket length on unix according to libc is 108, see sockaddr_un::sun_path, but in the table it is a string of max length 64, which results in truncation of socket and failure to connect by plugins using servers such as spider. --- mysql-test/main/mysqldump-system,win.rdiff | 4 +-- mysql-test/main/mysqldump-system.result | 4 +-- mysql-test/main/servers.result | 5 ++++ mysql-test/main/servers.test | 4 +++ mysql-test/main/system_mysql_db.result | 2 +- .../main/system_mysql_db_fix40123.result | 2 +- .../main/system_mysql_db_fix50030.result | 2 +- .../main/system_mysql_db_fix50117.result | 2 +- .../main/system_mysql_db_fix50568.result | 2 +- .../suite/funcs_1/r/is_columns_mysql.result | 4 +-- .../r/is_columns_mysql_embedded.result | 4 +-- scripts/mysql_system_tables.sql | 2 +- scripts/mysql_system_tables_fix.sql | 4 +++ .../mysql-test/spider/r/alter_server.result | 29 +++++++++++++++++++ .../mysql-test/spider/t/alter_server.cnf | 5 ++++ .../mysql-test/spider/t/alter_server.test | 27 +++++++++++++++++ 16 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 storage/spider/mysql-test/spider/r/alter_server.result create mode 100644 storage/spider/mysql-test/spider/t/alter_server.cnf create mode 100644 storage/spider/mysql-test/spider/t/alter_server.test diff --git a/mysql-test/main/mysqldump-system,win.rdiff b/mysql-test/main/mysqldump-system,win.rdiff index a46b422e95f..26ed7d9f17d 100644 --- a/mysql-test/main/mysqldump-system,win.rdiff +++ b/mysql-test/main/mysqldump-system,win.rdiff @@ -3,7 +3,7 @@ @@ -442,7 +442,7 @@ mysql.time_zone_transition 3895294076 mysql.plugin 0 - mysql.servers 2783974349 + mysql.servers 4154392229 -mysql.func 3241572444 +mysql.func 310494789 mysql.innodb_table_stats 347867921 @@ -12,7 +12,7 @@ @@ -477,7 +477,7 @@ mysql.time_zone_transition 3895294076 mysql.plugin 0 - mysql.servers 2783974349 + mysql.servers 4154392229 -mysql.func 3241572444 +mysql.func 310494789 mysql.innodb_table_stats 347867921 diff --git a/mysql-test/main/mysqldump-system.result b/mysql-test/main/mysqldump-system.result index 5bfe363d694..e011132b0f9 100644 --- a/mysql-test/main/mysqldump-system.result +++ b/mysql-test/main/mysqldump-system.result @@ -444,7 +444,7 @@ Table Checksum mysql.roles_mapping 3150178430 mysql.time_zone_transition 3895294076 mysql.plugin 0 -mysql.servers 2783974349 +mysql.servers 4154392229 mysql.func 3241572444 mysql.innodb_table_stats 347867921 mysql.table_stats 664320059 @@ -479,7 +479,7 @@ Table Checksum mysql.roles_mapping 3150178430 mysql.time_zone_transition 3895294076 mysql.plugin 0 -mysql.servers 2783974349 +mysql.servers 4154392229 mysql.func 3241572444 mysql.innodb_table_stats 347867921 mysql.table_stats 664320059 diff --git a/mysql-test/main/servers.result b/mysql-test/main/servers.result index c466967a0db..d660aff1bd2 100644 --- a/mysql-test/main/servers.result +++ b/mysql-test/main/servers.result @@ -24,6 +24,11 @@ SELECT * FROM mysql.servers; Server_name Host Db Username Password Port Socket Wrapper Owner s1 3306 bar mysql DROP SERVER s1; +CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS(SOCKET '/tmp/1234567890_1234567890_1234567890_1234567890_1234567890_1234567890.sock'); +SELECT Socket FROM mysql.servers where Server_name = 's1'; +Socket +/tmp/1234567890_1234567890_1234567890_1234567890_1234567890_1234567890.sock +DROP SERVER s1; # # MDEV-33783 CREATE SERVER segfaults on wrong mysql.servers # diff --git a/mysql-test/main/servers.test b/mysql-test/main/servers.test index 6aaaa356c1d..1a58d5849f8 100644 --- a/mysql-test/main/servers.test +++ b/mysql-test/main/servers.test @@ -23,6 +23,10 @@ CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS(SOCKET 'bar'); SELECT * FROM mysql.servers; DROP SERVER s1; +CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS(SOCKET '/tmp/1234567890_1234567890_1234567890_1234567890_1234567890_1234567890.sock'); +SELECT Socket FROM mysql.servers where Server_name = 's1'; +DROP SERVER s1; + --echo # --echo # MDEV-33783 CREATE SERVER segfaults on wrong mysql.servers --echo # diff --git a/mysql-test/main/system_mysql_db.result b/mysql-test/main/system_mysql_db.result index 455d276d037..9900fd877cb 100644 --- a/mysql-test/main/system_mysql_db.result +++ b/mysql-test/main/system_mysql_db.result @@ -129,7 +129,7 @@ servers CREATE TABLE `servers` ( `Username` char(80) NOT NULL DEFAULT '', `Password` char(64) NOT NULL DEFAULT '', `Port` int(4) NOT NULL DEFAULT 0, - `Socket` char(64) NOT NULL DEFAULT '', + `Socket` char(108) NOT NULL DEFAULT '', `Wrapper` char(64) NOT NULL DEFAULT '', `Owner` varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (`Server_name`) diff --git a/mysql-test/main/system_mysql_db_fix40123.result b/mysql-test/main/system_mysql_db_fix40123.result index ff5f34225e9..2dc89622783 100644 --- a/mysql-test/main/system_mysql_db_fix40123.result +++ b/mysql-test/main/system_mysql_db_fix40123.result @@ -167,7 +167,7 @@ servers CREATE TABLE `servers` ( `Username` char(80) NOT NULL DEFAULT '', `Password` char(64) NOT NULL DEFAULT '', `Port` int(4) NOT NULL DEFAULT 0, - `Socket` char(64) NOT NULL DEFAULT '', + `Socket` char(108) NOT NULL DEFAULT '', `Wrapper` char(64) NOT NULL DEFAULT '', `Owner` varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (`Server_name`) diff --git a/mysql-test/main/system_mysql_db_fix50030.result b/mysql-test/main/system_mysql_db_fix50030.result index 17e245bf70f..9116429dc21 100644 --- a/mysql-test/main/system_mysql_db_fix50030.result +++ b/mysql-test/main/system_mysql_db_fix50030.result @@ -171,7 +171,7 @@ servers CREATE TABLE `servers` ( `Username` char(80) NOT NULL DEFAULT '', `Password` char(64) NOT NULL DEFAULT '', `Port` int(4) NOT NULL DEFAULT 0, - `Socket` char(64) NOT NULL DEFAULT '', + `Socket` char(108) NOT NULL DEFAULT '', `Wrapper` char(64) NOT NULL DEFAULT '', `Owner` varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (`Server_name`) diff --git a/mysql-test/main/system_mysql_db_fix50117.result b/mysql-test/main/system_mysql_db_fix50117.result index 0332524c43f..2ae70d00945 100644 --- a/mysql-test/main/system_mysql_db_fix50117.result +++ b/mysql-test/main/system_mysql_db_fix50117.result @@ -151,7 +151,7 @@ servers CREATE TABLE `servers` ( `Username` char(80) NOT NULL DEFAULT '', `Password` char(64) NOT NULL DEFAULT '', `Port` int(4) NOT NULL DEFAULT 0, - `Socket` char(64) NOT NULL DEFAULT '', + `Socket` char(108) NOT NULL DEFAULT '', `Wrapper` char(64) NOT NULL DEFAULT '', `Owner` varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (`Server_name`) diff --git a/mysql-test/main/system_mysql_db_fix50568.result b/mysql-test/main/system_mysql_db_fix50568.result index 0feea2ba896..f520fa3d80b 100644 --- a/mysql-test/main/system_mysql_db_fix50568.result +++ b/mysql-test/main/system_mysql_db_fix50568.result @@ -172,7 +172,7 @@ servers CREATE TABLE `servers` ( `Username` char(80) NOT NULL DEFAULT '', `Password` char(64) NOT NULL DEFAULT '', `Port` int(4) NOT NULL DEFAULT 0, - `Socket` char(64) NOT NULL DEFAULT '', + `Socket` char(108) NOT NULL DEFAULT '', `Wrapper` char(64) NOT NULL DEFAULT '', `Owner` varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (`Server_name`) diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result index e707c46e726..62ff9f4e7a6 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result @@ -163,7 +163,7 @@ def mysql servers Owner 9 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_genera def mysql servers Password 5 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL def mysql servers Port 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(4) select,insert,update,references NEVER NULL def mysql servers Server_name 1 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI select,insert,update,references NEVER NULL -def mysql servers Socket 7 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL +def mysql servers Socket 7 '' NO char 108 324 NULL NULL NULL utf8 utf8_general_ci char(108) select,insert,update,references NEVER NULL def mysql servers Username 4 '' NO char 80 240 NULL NULL NULL utf8 utf8_general_ci char(80) select,insert,update,references NEVER NULL def mysql servers Wrapper 8 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) select,insert,update,references NEVER NULL def mysql slow_log db 7 NULL NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) select,insert,update,references NEVER NULL @@ -490,7 +490,7 @@ NULL mysql proxies_priv Timestamp timestamp NULL NULL NULL NULL timestamp 3.0000 mysql servers Username char 80 240 utf8 utf8_general_ci char(80) 3.0000 mysql servers Password char 64 192 utf8 utf8_general_ci char(64) NULL mysql servers Port int NULL NULL NULL NULL int(4) -3.0000 mysql servers Socket char 64 192 utf8 utf8_general_ci char(64) +3.0000 mysql servers Socket char 108 324 utf8 utf8_general_ci char(108) 3.0000 mysql servers Wrapper char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Owner varchar 512 1536 utf8 utf8_general_ci varchar(512) NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp(6) diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result index 606a555a5e4..858d587d1a1 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result @@ -149,7 +149,7 @@ def mysql servers Owner 9 '' NO varchar 512 1536 NULL NULL NULL utf8 utf8_genera def mysql servers Password 5 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) NEVER NULL def mysql servers Port 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(4) NEVER NULL def mysql servers Server_name 1 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI NEVER NULL -def mysql servers Socket 7 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) NEVER NULL +def mysql servers Socket 7 '' NO char 108 324 NULL NULL NULL utf8 utf8_general_ci char(108) NEVER NULL def mysql servers Username 4 '' NO char 80 240 NULL NULL NULL utf8 utf8_general_ci char(80) NEVER NULL def mysql servers Wrapper 8 '' NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) NEVER NULL def mysql slow_log db 7 NULL NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512) NEVER NULL @@ -473,7 +473,7 @@ NULL mysql proxies_priv Timestamp timestamp NULL NULL NULL NULL timestamp 3.0000 mysql servers Username char 80 240 utf8 utf8_general_ci char(80) 3.0000 mysql servers Password char 64 192 utf8 utf8_general_ci char(64) NULL mysql servers Port int NULL NULL NULL NULL int(4) -3.0000 mysql servers Socket char 64 192 utf8 utf8_general_ci char(64) +3.0000 mysql servers Socket char 108 324 utf8 utf8_general_ci char(108) 3.0000 mysql servers Wrapper char 64 192 utf8 utf8_general_ci char(64) 3.0000 mysql servers Owner varchar 512 1536 utf8 utf8_general_ci varchar(512) NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp(6) diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 5a00356d409..a6631690a00 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -108,7 +108,7 @@ CREATE TABLE IF NOT EXISTS func ( name char(64) binary DEFAULT '' NOT NULL, ret CREATE TABLE IF NOT EXISTS plugin ( name varchar(64) DEFAULT '' NOT NULL, dl varchar(128) DEFAULT '' NOT NULL, PRIMARY KEY (name) ) engine=Aria transactional=1 CHARACTER SET utf8 COLLATE utf8_general_ci comment='MySQL plugins'; -CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host varchar(2048) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(80) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(64) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) engine=Aria transactional=1 CHARACTER SET utf8 comment='MySQL Foreign Servers table'; +CREATE TABLE IF NOT EXISTS servers ( Server_name char(64) NOT NULL DEFAULT '', Host varchar(2048) NOT NULL DEFAULT '', Db char(64) NOT NULL DEFAULT '', Username char(80) NOT NULL DEFAULT '', Password char(64) NOT NULL DEFAULT '', Port INT(4) NOT NULL DEFAULT '0', Socket char(108) NOT NULL DEFAULT '', Wrapper char(64) NOT NULL DEFAULT '', Owner varchar(512) NOT NULL DEFAULT '', PRIMARY KEY (Server_name)) engine=Aria transactional=1 CHARACTER SET utf8 comment='MySQL Foreign Servers table'; CREATE TABLE IF NOT EXISTS tables_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(80) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Grantor char(141) DEFAULT '' NOT NULL, Timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter','Create View','Show view','Trigger','Delete versioning rows') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') COLLATE utf8_general_ci DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor) ) engine=Aria transactional=1 CHARACTER SET utf8 COLLATE utf8_bin comment='Table privileges'; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index e5bdc4314f7..f0b5cac46fe 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -851,3 +851,7 @@ DELIMITER ; ALTER TABLE servers MODIFY Host varchar(2048) NOT NULL DEFAULT '', MODIFY Owner varchar(512) NOT NULL DEFAULT ''; + +# MDEV-34716 Fix mysql.servers socket max length too short +ALTER TABLE servers + MODIFY Socket char(108) NOT NULL DEFAULT ''; diff --git a/storage/spider/mysql-test/spider/r/alter_server.result b/storage/spider/mysql-test/spider/r/alter_server.result new file mode 100644 index 00000000000..19255f3cdf8 --- /dev/null +++ b/storage/spider/mysql-test/spider/r/alter_server.result @@ -0,0 +1,29 @@ +for master_1 +for child2 +for child3 +set spider_same_server_link= 1; +CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +select Socket from mysql.servers where Server_name = "srv"; +Socket +/tmp/1234567890_1234567890_1234567890_1234567890_1234567890_1234567890.sock +create table t2 (c int); +alter SERVER srv OPTIONS (DATABASE 'test'); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +insert into t1 values (1), (2), (3); +select * from t1; +c +1 +2 +3 +select * from t2; +c +1 +2 +3 +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/t/alter_server.cnf b/storage/spider/mysql-test/spider/t/alter_server.cnf new file mode 100644 index 00000000000..69672af4ef6 --- /dev/null +++ b/storage/spider/mysql-test/spider/t/alter_server.cnf @@ -0,0 +1,5 @@ +[mysqld.1.1] +socket= /tmp/1234567890_1234567890_1234567890_1234567890_1234567890_1234567890.sock + +[ENV] +MASTER_1_MYSOCK= @mysqld.1.1.socket diff --git a/storage/spider/mysql-test/spider/t/alter_server.test b/storage/spider/mysql-test/spider/t/alter_server.test new file mode 100644 index 00000000000..10228e785cb --- /dev/null +++ b/storage/spider/mysql-test/spider/t/alter_server.test @@ -0,0 +1,27 @@ +--disable_query_log +--disable_result_log +--source test_init.inc +--enable_result_log +--enable_query_log +set spider_same_server_link= 1; + +# Test long socket length +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +select Socket from mysql.servers where Server_name = "srv"; +create table t2 (c int); +# triggers a table read into the server object +alter SERVER srv OPTIONS (DATABASE 'test'); +create table t1 (c int) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +insert into t1 values (1), (2), (3); +select * from t1; +select * from t2; +drop table t1, t2; +drop server srv; + +--disable_query_log +--disable_result_log +--source test_deinit.inc +--enable_result_log +--enable_query_log