diff --git a/client/mysqltest.cc b/client/mysqltest.cc index c4a33a32a04..f7cf82bc9b2 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -7911,6 +7911,20 @@ static const char *trking_info_desc[SESSION_TRACK_END + 1]= /** @brief Append state change information (received through Ok packet) to the output. + @details The appended string is lines prefixed with "-- ". Only + tracking types with info sent from the server are displayed. For + each tracking type, the first line is the type name e.g. + "-- Tracker : SESSION_TRACK_SYSTEM_VARIABLES". + + The subsequent lines are the actual tracking info. When type is + SESSION_TRACK_SYSTEM_VARIABLES, the actual tracking info is a list + of name-value pairs of lines, sorted by name, e.g. if the info + received from the server is "autocommit=ON;time_zone=SYSTEM", the + corresponding string is + + -- autocommit: ON + -- time_zone: SYSTEM + @param [in,out] ds Dynamic string to hold the content to be printed. @param [in] mysql Connection handle. */ @@ -7918,11 +7932,16 @@ static const char *trking_info_desc[SESSION_TRACK_END + 1]= static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) { #ifndef EMBEDDED_LIBRARY + DYNAMIC_STRING ds_sort, *ds_type= NULL; for (unsigned int type= SESSION_TRACK_BEGIN; type <= SESSION_TRACK_END; type++) { const char *data; size_t data_length; + /* + Append the tracking type line, if any corresponding tracking + info is received. + */ if (!mysql_session_track_get_first(mysql, (enum_session_state_type) type, &data, &data_length)) @@ -7938,26 +7957,56 @@ static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql) DBUG_ASSERT(0); dynstr_append_mem(ds, STRING_WITH_LEN("Tracker???\n")); } - - dynstr_append_mem(ds, STRING_WITH_LEN("-- ")); - dynstr_append_mem(ds, data, data_length); } else continue; + + /* + The remaining of this function: format and append the actual + tracking info. + */ + if (type == SESSION_TRACK_SYSTEM_VARIABLES) + { + /* Prepare a string to be sorted before being appended. */ + if (init_dynamic_string(&ds_sort, "", 1024, 1024)) + die("Out of memory"); + ds_type= &ds_sort; + } + else + ds_type= ds; + /* Append the first piece of info */ + dynstr_append_mem(ds_type, STRING_WITH_LEN("-- ")); + dynstr_append_mem(ds_type, data, data_length); + /* Whether we are appending the value of a variable */ + bool appending_value= type == SESSION_TRACK_SYSTEM_VARIABLES; + /* Append remaining pieces */ while (!mysql_session_track_get_next(mysql, (enum_session_state_type) type, &data, &data_length)) { - dynstr_append_mem(ds, STRING_WITH_LEN("\n-- ")); + if (appending_value) + dynstr_append_mem(ds_type, STRING_WITH_LEN(": ")); + else + dynstr_append_mem(ds_type, STRING_WITH_LEN("\n-- ")); + appending_value= !appending_value && type == SESSION_TRACK_SYSTEM_VARIABLES; if (data == NULL) { DBUG_ASSERT(data_length == 0); - dynstr_append_mem(ds, STRING_WITH_LEN("")); + dynstr_append_mem(ds_type, STRING_WITH_LEN("")); } else - dynstr_append_mem(ds, data, data_length); + dynstr_append_mem(ds_type, data, data_length); } - dynstr_append_mem(ds, STRING_WITH_LEN("\n\n")); + DBUG_ASSERT(!appending_value); + if (type == SESSION_TRACK_SYSTEM_VARIABLES) + { + dynstr_append_mem(ds_type, STRING_WITH_LEN("\n")); + dynstr_append_sorted(ds, ds_type, false); + dynstr_append_mem(ds, STRING_WITH_LEN("\n")); + dynstr_free(&ds_sort); + } + else + dynstr_append_mem(ds, STRING_WITH_LEN("\n\n")); } #endif /* EMBEDDED_LIBRARY */ } @@ -12115,7 +12164,8 @@ void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val) /* Build a list of pointer to each line in ds_input, sort the list and use the sorted list to append the strings - sorted to the output ds + sorted to the output ds. The string ds_input needs to + end with a newline. SYNOPSIS dynstr_append_sorted() diff --git a/mysql-test/main/column_compression.result b/mysql-test/main/column_compression.result index 4ac35912072..e68d9385f1e 100644 --- a/mysql-test/main/column_compression.result +++ b/mysql-test/main/column_compression.result @@ -2918,10 +2918,8 @@ CREATE TABLE t1 (a VARCHAR(500) COMPRESSED CHARACTER SET utf8mb3) ENGINE=InnoDB; INSERT INTO t1 SET a=REPEAT('x',127); ALTER TABLE t1 FORCE, ALGORITHM=COPY; DROP TABLE t1; -# # End of 10.4 tests # -# # MDEV-19727 Add Type_handler::Key_part_spec_init_ft # CREATE TABLE t1 (a VARCHAR(1000) COMPRESSED, FULLTEXT INDEX(a)); @@ -2929,5 +2927,20 @@ ERROR HY000: Compressed column 'a' can't be used in key specification CREATE TABLE t1 (a TEXT COMPRESSED, FULLTEXT INDEX(a)); ERROR HY000: Compressed column 'a' can't be used in key specification # -# End of 10.5 tests +# MDEV-16699 heap-use-after-free in group_concat with compressed or GIS columns # +create table t1 (c text compressed); +insert into t1 values ('foo'),(repeat('a',55000)); +select length(group_concat(c order by 1)) from t1; +length(group_concat(c order by 1)) +55004 +create table t2 as select group_concat(c order by 1), concat(c), c from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `group_concat(c order by 1)` mediumtext DEFAULT NULL, + `concat(c)` text DEFAULT NULL, + `c` text /*M!100301 COMPRESSED*/ DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop table t1, t2; +# End of 10.5 tests diff --git a/mysql-test/main/column_compression.test b/mysql-test/main/column_compression.test index 5fa8192df3b..01b408f362e 100644 --- a/mysql-test/main/column_compression.test +++ b/mysql-test/main/column_compression.test @@ -453,10 +453,7 @@ INSERT INTO t1 SET a=REPEAT('x',127); ALTER TABLE t1 FORCE, ALGORITHM=COPY; DROP TABLE t1; - ---echo # --echo # End of 10.4 tests ---echo # --echo # --echo # MDEV-19727 Add Type_handler::Key_part_spec_init_ft @@ -476,5 +473,13 @@ CREATE TABLE t1 (a TEXT COMPRESSED, FULLTEXT INDEX(a)); --disable_prepare_warnings --echo # ---echo # End of 10.5 tests +--echo # MDEV-16699 heap-use-after-free in group_concat with compressed or GIS columns --echo # +create table t1 (c text compressed); +insert into t1 values ('foo'),(repeat('a',55000)); +select length(group_concat(c order by 1)) from t1; +create table t2 as select group_concat(c order by 1), concat(c), c from t1; +show create table t2; +drop table t1, t2; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result index 33eaf58942e..a2d6529f1cf 100644 --- a/mysql-test/main/gis.result +++ b/mysql-test/main/gis.result @@ -5435,5 +5435,22 @@ AsText(g) POINT(1 1) DROP TABLE t1; # -# End of 10.5 tests +# MDEV-16699 heap-use-after-free in group_concat with compressed or GIS columns # +create table t1 (c polygon); +insert into t1 values +(PolygonFromText('POLYGON((1 2,1 2))')), +(PolygonFromText('POLYGON((0 0,1 1,0 0))')); +select length(group_concat(c, c order by 1,2)) from t1; +length(group_concat(c, c order by 1,2)) +229 +create table t2 as select group_concat(c, c order by 1,2), concat(c), c from t1; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `group_concat(c, c order by 1,2)` mediumblob DEFAULT NULL, + `concat(c)` longblob DEFAULT NULL, + `c` polygon DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop table t1, t2; +# End of 10.5 tests diff --git a/mysql-test/main/gis.test b/mysql-test/main/gis.test index 9f62ac63fe2..4914687eb5d 100644 --- a/mysql-test/main/gis.test +++ b/mysql-test/main/gis.test @@ -3445,5 +3445,15 @@ SELECT AsText(g) FROM t1; DROP TABLE t1; --echo # ---echo # End of 10.5 tests +--echo # MDEV-16699 heap-use-after-free in group_concat with compressed or GIS columns --echo # +create table t1 (c polygon); +insert into t1 values + (PolygonFromText('POLYGON((1 2,1 2))')), + (PolygonFromText('POLYGON((0 0,1 1,0 0))')); +select length(group_concat(c, c order by 1,2)) from t1; +create table t2 as select group_concat(c, c order by 1,2), concat(c), c from t1; +show create table t2; +drop table t1, t2; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/mysqltest_tracking_info.result b/mysql-test/main/mysqltest_tracking_info.result index cad96ef80c4..7b12ed5bb30 100644 --- a/mysql-test/main/mysqltest_tracking_info.result +++ b/mysql-test/main/mysqltest_tracking_info.result @@ -6,26 +6,22 @@ SET @@session.session_track_system_variables='character_set_connection'; # tracking info on SET NAMES 'utf8'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- character_set_connection --- utf8mb3 +-- character_set_connection: utf8mb3 SET NAMES 'big5'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- character_set_connection --- big5 +-- character_set_connection: big5 # tracking info on once SET NAMES 'utf8'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- character_set_connection --- utf8mb3 +-- character_set_connection: utf8mb3 SET NAMES 'big5'; # tracking info on SET NAMES 'utf8'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- character_set_connection --- utf8mb3 +-- character_set_connection: utf8mb3 # tracking info off once SET NAMES 'big5'; @@ -37,8 +33,7 @@ set @save_optimizer_switch=@@optimizer_switch; SET @@session.session_track_system_variables='optimizer_switch'; set optimizer_switch='index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- optimizer_switch --- index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off +-- optimizer_switch: index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=off,cset_narrowing=off Warnings: Warning 1681 'engine_condition_pushdown=on' is deprecated and will be removed in a future release @@ -71,13 +66,11 @@ ERROR HY000: Unknown system variable 'a' connect con,localhost,root,,test; SET NAMES 'utf8'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- character_set_connection --- utf8mb3 +-- character_set_connection: utf8mb3 SET NAMES 'big5'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- character_set_connection --- big5 +-- character_set_connection: big5 select @@session_track_system_variables; @@session_track_system_variables diff --git a/mysql-test/main/selectivity_innodb_notembedded.result b/mysql-test/main/selectivity_innodb_notembedded.result index fa5574c4917..8e7920cb4ee 100644 --- a/mysql-test/main/selectivity_innodb_notembedded.result +++ b/mysql-test/main/selectivity_innodb_notembedded.result @@ -218,26 +218,28 @@ index (key1, pk), primary key (pk) ); insert into t1 -select +select seq, FLOOR(seq/100), 'filler' -from +from seq_1_to_1000; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK set optimizer_trace=1; -explain select * from t1 +explain select * from t1 where pk in (1,2,3,4,5) and key1 <= 4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY,key1 PRIMARY 4 NULL 5 Using where +create temporary table opt_trace as +select * from information_schema.optimizer_trace; # Must have a note that "multiplier is too high": -select +select json_detailed(json_extract(trace,'$**.selectivity_for_indexes')) as JS -from -information_schema.optimizer_trace; +from +opt_trace; JS [ [ @@ -253,10 +255,10 @@ JS ] ] # Must not include 1.79...e308 as cost: -select +select json_detailed(json_extract(trace,'$**.best_access_path')) as JS -from -information_schema.optimizer_trace; +from +opt_trace; JS [ { @@ -278,20 +280,22 @@ JS } } ] +drop table opt_trace; # Disable the fix and try the same: set @@optimizer_adjust_secondary_key_costs=''; -explain select * from t1 +explain select * from t1 where pk in (1,2,3,4,5) and key1 <= 4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY,key1 PRIMARY 4 NULL 5 Using where -drop table t1; +create temporary table opt_trace as +select * from information_schema.optimizer_trace; # Shows a high multiplier, without a "note": -select +select json_detailed(json_extract(trace,'$**.selectivity_for_indexes')) as JS -from -information_schema.optimizer_trace; +from +opt_trace; JS [ [ @@ -307,10 +311,10 @@ JS ] ] # Includes 1.79...e308 as cost: -select +select json_detailed(json_extract(trace,'$**.best_access_path')) as JS -from -information_schema.optimizer_trace; +from +opt_trace; JS [ { @@ -332,7 +336,9 @@ JS } } ] +drop table opt_trace; set optimizer_adjust_secondary_key_costs=default; +drop table t1; # # Clean up # diff --git a/mysql-test/main/selectivity_notembedded.result b/mysql-test/main/selectivity_notembedded.result index 3638bbcac00..d8dbb80fa59 100644 --- a/mysql-test/main/selectivity_notembedded.result +++ b/mysql-test/main/selectivity_notembedded.result @@ -213,26 +213,28 @@ index (key1, pk), primary key (pk) ); insert into t1 -select +select seq, FLOOR(seq/100), 'filler' -from +from seq_1_to_1000; analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected test.t1 analyze status Table is already up to date set optimizer_trace=1; -explain select * from t1 +explain select * from t1 where pk in (1,2,3,4,5) and key1 <= 4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY,key1 PRIMARY 4 NULL 5 Using index condition; Using where +create temporary table opt_trace as +select * from information_schema.optimizer_trace; # Must have a note that "multiplier is too high": -select +select json_detailed(json_extract(trace,'$**.selectivity_for_indexes')) as JS -from -information_schema.optimizer_trace; +from +opt_trace; JS [ [ @@ -248,10 +250,10 @@ JS ] ] # Must not include 1.79...e308 as cost: -select +select json_detailed(json_extract(trace,'$**.best_access_path')) as JS -from -information_schema.optimizer_trace; +from +opt_trace; JS [ { @@ -273,20 +275,22 @@ JS } } ] +drop table opt_trace; # Disable the fix and try the same: set @@optimizer_adjust_secondary_key_costs=''; -explain select * from t1 +explain select * from t1 where pk in (1,2,3,4,5) and key1 <= 4; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY,key1 PRIMARY 4 NULL 5 Using index condition; Using where -drop table t1; +create temporary table opt_trace as +select * from information_schema.optimizer_trace; # Shows a high multiplier, without a "note": -select +select json_detailed(json_extract(trace,'$**.selectivity_for_indexes')) as JS -from -information_schema.optimizer_trace; +from +opt_trace; JS [ [ @@ -302,10 +306,10 @@ JS ] ] # Includes 1.79...e308 as cost: -select +select json_detailed(json_extract(trace,'$**.best_access_path')) as JS -from -information_schema.optimizer_trace; +from +opt_trace; JS [ { @@ -327,7 +331,9 @@ JS } } ] +drop table opt_trace; set optimizer_adjust_secondary_key_costs=default; +drop table t1; # # Clean up # diff --git a/mysql-test/main/selectivity_notembedded.test b/mysql-test/main/selectivity_notembedded.test index 2c4431adb23..d53cb8db7b4 100644 --- a/mysql-test/main/selectivity_notembedded.test +++ b/mysql-test/main/selectivity_notembedded.test @@ -233,50 +233,59 @@ create table t1 ( ); insert into t1 -select +select seq, FLOOR(seq/100), 'filler' -from +from seq_1_to_1000; analyze table t1; set optimizer_trace=1; -explain select * from t1 +explain select * from t1 where pk in (1,2,3,4,5) and key1 <= 4; +create temporary table opt_trace as +select * from information_schema.optimizer_trace; + --echo # Must have a note that "multiplier is too high": -select +select json_detailed(json_extract(trace,'$**.selectivity_for_indexes')) as JS -from - information_schema.optimizer_trace; +from + opt_trace; --echo # Must not include 1.79...e308 as cost: -select +select json_detailed(json_extract(trace,'$**.best_access_path')) as JS -from - information_schema.optimizer_trace; +from + opt_trace; +drop table opt_trace; --echo # Disable the fix and try the same: set @@optimizer_adjust_secondary_key_costs=''; -explain select * from t1 +explain select * from t1 where pk in (1,2,3,4,5) and key1 <= 4; -drop table t1; + +create temporary table opt_trace as +select * from information_schema.optimizer_trace; + --echo # Shows a high multiplier, without a "note": -select +select json_detailed(json_extract(trace,'$**.selectivity_for_indexes')) as JS -from - information_schema.optimizer_trace; +from + opt_trace; --echo # Includes 1.79...e308 as cost: -select +select json_detailed(json_extract(trace,'$**.best_access_path')) as JS -from - information_schema.optimizer_trace; -set optimizer_adjust_secondary_key_costs=default; +from + opt_trace; +drop table opt_trace; +set optimizer_adjust_secondary_key_costs=default; +drop table t1; --echo # --echo # Clean up --echo # diff --git a/mysql-test/main/session_tracker_last_gtid.result b/mysql-test/main/session_tracker_sysvar.result similarity index 57% rename from mysql-test/main/session_tracker_last_gtid.result rename to mysql-test/main/session_tracker_sysvar.result index 5a78d5f03ce..6b56cb400b8 100644 --- a/mysql-test/main/session_tracker_last_gtid.result +++ b/mysql-test/main/session_tracker_sysvar.result @@ -5,31 +5,35 @@ SET gtid_seq_no=1000; SET @@session.session_track_system_variables='last_gtid'; create table t1 (a int) engine=innodb; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- last_gtid --- 0-1-1000 +-- last_gtid: 0-1-1000 select @@last_gtid; @@last_gtid 0-1-1000 -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- last_gtid --- 0-1-1000 +-- last_gtid: 0-1-1000 insert into t1 values (1); -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- last_gtid --- 0-1-1001 +-- last_gtid: 0-1-1001 select @@last_gtid; @@last_gtid 0-1-1001 -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- last_gtid --- 0-1-1001 +-- last_gtid: 0-1-1001 drop table t1; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- last_gtid --- 0-1-1002 +-- last_gtid: 0-1-1002 reset master; +# +# MDEV-35086 Trying to lock mutex when the mutex was already locked (session_tracker.cc), server hangs +# +set session_track_system_variables='*'; +alter table t1 nowait force; +ERROR 42S02: Table 'test.t1' doesn't exist +use mysql; +set session_track_system_variables=default; +# End of 10.5 tests diff --git a/mysql-test/main/session_tracker_last_gtid.test b/mysql-test/main/session_tracker_sysvar.test similarity index 61% rename from mysql-test/main/session_tracker_last_gtid.test rename to mysql-test/main/session_tracker_sysvar.test index 58aee2de837..54b69782697 100644 --- a/mysql-test/main/session_tracker_last_gtid.test +++ b/mysql-test/main/session_tracker_sysvar.test @@ -18,3 +18,14 @@ drop table t1; --disable_session_track_info reset master; + +--echo # +--echo # MDEV-35086 Trying to lock mutex when the mutex was already locked (session_tracker.cc), server hangs +--echo # +set session_track_system_variables='*'; +--error ER_NO_SUCH_TABLE +alter table t1 nowait force; +use mysql; +set session_track_system_variables=default; + +--echo # End of 10.5 tests diff --git a/mysql-test/suite/handler/interface.result b/mysql-test/suite/handler/interface.result index 3758400345b..2a0f36e5fa2 100644 --- a/mysql-test/suite/handler/interface.result +++ b/mysql-test/suite/handler/interface.result @@ -338,9 +338,9 @@ CREATE TABLE t1 (g GEOMETRY NOT NULL, SPATIAL gi(g)); INSERT INTO t1 VALUES (POINT(0,0)); HANDLER t1 OPEN AS h; HANDLER h READ `gi`= (10); -ERROR HY000: SPATIAL index `gi` does not support this operation +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field HANDLER h READ `gi`> (10); -ERROR HY000: SPATIAL index `gi` does not support this operation +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field HANDLER h CLOSE; DROP TABLE t1; CREATE TABLE t1 (w VARCHAR(100), FULLTEXT fk(w)); @@ -352,3 +352,12 @@ HANDLER h READ `fk`> (10); ERROR HY000: FULLTEXT index `fk` does not support this operation HANDLER h CLOSE; DROP TABLE t1; +# +# MDEV-35082 HANDLER with FULLTEXT keys is not always rejected +# +create table t (a int primary key, v text not null, fulltext(v)); +handler t open; +handler t read v next; +ERROR HY000: FULLTEXT index `v` does not support this operation +drop table t; +# End of 10.5 tests diff --git a/mysql-test/suite/handler/interface.test b/mysql-test/suite/handler/interface.test index a4ed640dbc0..43abe47cf9b 100644 --- a/mysql-test/suite/handler/interface.test +++ b/mysql-test/suite/handler/interface.test @@ -385,9 +385,9 @@ DROP TABLE t1; CREATE TABLE t1 (g GEOMETRY NOT NULL, SPATIAL gi(g)); INSERT INTO t1 VALUES (POINT(0,0)); HANDLER t1 OPEN AS h; ---error ER_KEY_DOESNT_SUPPORT +--error ER_CANT_CREATE_GEOMETRY_OBJECT HANDLER h READ `gi`= (10); ---error ER_KEY_DOESNT_SUPPORT +--error ER_CANT_CREATE_GEOMETRY_OBJECT HANDLER h READ `gi`> (10); HANDLER h CLOSE; DROP TABLE t1; @@ -401,3 +401,14 @@ HANDLER h READ `fk`= (10); HANDLER h READ `fk`> (10); HANDLER h CLOSE; DROP TABLE t1; + +--echo # +--echo # MDEV-35082 HANDLER with FULLTEXT keys is not always rejected +--echo # +create table t (a int primary key, v text not null, fulltext(v)); +handler t open; +--error ER_KEY_DOESNT_SUPPORT +handler t read v next; +drop table t; + +--echo # End of 10.5 tests diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result index 2cc992be73a..434e060e258 100644 --- a/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result +++ b/mysql-test/suite/innodb_fts/r/innodb_fts_misc.result @@ -1188,9 +1188,9 @@ DROP TABLE t; CREATE TABLE t(a CHAR(1),FULLTEXT KEY(a)) ENGINE=INNODB; HANDLER t OPEN; HANDLER t READ a NEXT; -a +ERROR HY000: FULLTEXT index `a` does not support this operation HANDLER t READ a PREV; -a +ERROR HY000: FULLTEXT index `a` does not support this operation DROP TABLE t; CREATE TABLE `%`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; CREATE TABLE `A B`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; diff --git a/mysql-test/suite/innodb_fts/r/misc.result b/mysql-test/suite/innodb_fts/r/misc.result index 684996fb748..4afd9bf1f74 100644 --- a/mysql-test/suite/innodb_fts/r/misc.result +++ b/mysql-test/suite/innodb_fts/r/misc.result @@ -1183,9 +1183,9 @@ DROP TABLE t; CREATE TABLE t(a CHAR(1),FULLTEXT KEY(a)) ENGINE=INNODB; HANDLER t OPEN; HANDLER t READ a NEXT; -a +ERROR HY000: FULLTEXT index `a` does not support this operation HANDLER t READ a PREV; -a +ERROR HY000: FULLTEXT index `a` does not support this operation DROP TABLE t; CREATE TABLE `%`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; CREATE TABLE `A B`(a TEXT, FULLTEXT INDEX(a)) ENGINE=INNODB; diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test index c2d1d82657d..3bedafcec34 100644 --- a/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test +++ b/mysql-test/suite/innodb_fts/t/innodb_fts_misc.test @@ -1155,7 +1155,9 @@ DROP TABLE t; # InnoDB FTS does not support index scan from handler CREATE TABLE t(a CHAR(1),FULLTEXT KEY(a)) ENGINE=INNODB; HANDLER t OPEN; +--error ER_KEY_DOESNT_SUPPORT HANDLER t READ a NEXT; +--error ER_KEY_DOESNT_SUPPORT HANDLER t READ a PREV; DROP TABLE t; diff --git a/mysql-test/suite/innodb_fts/t/misc.test b/mysql-test/suite/innodb_fts/t/misc.test index f897cf1265d..f3c10d16205 100644 --- a/mysql-test/suite/innodb_fts/t/misc.test +++ b/mysql-test/suite/innodb_fts/t/misc.test @@ -1148,7 +1148,9 @@ DROP TABLE t; # InnoDB FTS does not support index scan from handler CREATE TABLE t(a CHAR(1),FULLTEXT KEY(a)) ENGINE=INNODB; HANDLER t OPEN; +--error ER_KEY_DOESNT_SUPPORT HANDLER t READ a NEXT; +--error ER_KEY_DOESNT_SUPPORT HANDLER t READ a PREV; DROP TABLE t; diff --git a/mysql-test/suite/plugins/r/fulltext_notembedded.result b/mysql-test/suite/plugins/r/fulltext_notembedded.result new file mode 100644 index 00000000000..131e3bb3380 --- /dev/null +++ b/mysql-test/suite/plugins/r/fulltext_notembedded.result @@ -0,0 +1,8 @@ +# +# MDEV-35050 Found wrong usage of mutex upon setting plugin session variables +# +install soname 'mypluglib'; +set session_track_system_variables="*"; +set session simple_parser_simple_thdvar_one = 10; +uninstall soname 'mypluglib'; +# End of 10.5 tests diff --git a/mysql-test/suite/plugins/r/fulltext_plugin.result b/mysql-test/suite/plugins/r/fulltext_plugin.result index 6fcba7735c9..c5283e6aece 100644 --- a/mysql-test/suite/plugins/r/fulltext_plugin.result +++ b/mysql-test/suite/plugins/r/fulltext_plugin.result @@ -8,11 +8,3 @@ DROP TABLE t1; UNINSTALL PLUGIN simple_parser; show status like 'a%status'; Variable_name Value -# -# MDEV-35050 Found wrong usage of mutex upon setting plugin session variables -# -install soname 'mypluglib'; -set session_track_system_variables="*"; -set session simple_parser_simple_thdvar_one = 10; -uninstall soname 'mypluglib'; -# End of 10.5 tests diff --git a/mysql-test/suite/plugins/t/fulltext_notembedded.test b/mysql-test/suite/plugins/t/fulltext_notembedded.test new file mode 100644 index 00000000000..49238f3571b --- /dev/null +++ b/mysql-test/suite/plugins/t/fulltext_notembedded.test @@ -0,0 +1,12 @@ +--source include/have_simple_parser.inc +--source include/not_embedded.inc + +--echo # +--echo # MDEV-35050 Found wrong usage of mutex upon setting plugin session variables +--echo # +install soname 'mypluglib'; +set session_track_system_variables="*"; +set session simple_parser_simple_thdvar_one = 10; +uninstall soname 'mypluglib'; + +--echo # End of 10.5 tests diff --git a/mysql-test/suite/plugins/t/fulltext_plugin.test b/mysql-test/suite/plugins/t/fulltext_plugin.test index f6f6e169945..c0e1d8e17bf 100644 --- a/mysql-test/suite/plugins/t/fulltext_plugin.test +++ b/mysql-test/suite/plugins/t/fulltext_plugin.test @@ -1,4 +1,3 @@ ---source include/not_embedded.inc --source include/have_simple_parser.inc --echo # @@ -15,13 +14,3 @@ UNINSTALL PLUGIN simple_parser; # Bug #69682 - mysqld crashes after uninstall of plugin with "first" status var # show status like 'a%status'; - ---echo # ---echo # MDEV-35050 Found wrong usage of mutex upon setting plugin session variables ---echo # -install soname 'mypluglib'; -set session_track_system_variables="*"; -set session simple_parser_simple_thdvar_one = 10; -uninstall soname 'mypluglib'; - ---echo # End of 10.5 tests diff --git a/mysql-test/suite/versioning/r/delete_history.result b/mysql-test/suite/versioning/r/delete_history.result index 965e97e3de3..afb5fd0ccea 100644 --- a/mysql-test/suite/versioning/r/delete_history.result +++ b/mysql-test/suite/versioning/r/delete_history.result @@ -221,3 +221,14 @@ ERROR HY000: The target table v1 of the DELETE is not updatable DROP VIEW v1; DROP TABLE t1; # End of 10.4 tests +# +# MDEV-33470 Unique hash index is broken on DML for system-versioned table +# +create or replace table t ( +c int, unique (c) using hash) +with system versioning; +insert into t values (0); +delete from t; +delete history from t; +drop table t; +# End of 10.5 tests diff --git a/mysql-test/suite/versioning/r/rpl_row.result b/mysql-test/suite/versioning/r/rpl_row.result index 89c3ce21033..fe1eeb17941 100644 --- a/mysql-test/suite/versioning/r/rpl_row.result +++ b/mysql-test/suite/versioning/r/rpl_row.result @@ -49,4 +49,28 @@ x y 1 1 connection master; drop table t1; +# +# MDEV-31297 Create table as select on system versioned tables do not work consistently on replication +# +connection master; +create table t engine=innodb with system versioning as select 1 as i; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `i` int(1) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING +select * from t; +i +1 +connection slave; +show create table t; +Table Create Table +t CREATE TABLE `t` ( + `i` int(1) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci WITH SYSTEM VERSIONING +select * from t; +i +1 +connection master; +drop table t; include/rpl_end.inc diff --git a/mysql-test/suite/versioning/t/delete_history.test b/mysql-test/suite/versioning/t/delete_history.test index 758afb7c570..7531668f112 100644 --- a/mysql-test/suite/versioning/t/delete_history.test +++ b/mysql-test/suite/versioning/t/delete_history.test @@ -227,4 +227,17 @@ DROP TABLE t1; --echo # End of 10.4 tests +--echo # +--echo # MDEV-33470 Unique hash index is broken on DML for system-versioned table +--echo # +create or replace table t ( + c int, unique (c) using hash) +with system versioning; +insert into t values (0); +delete from t; +delete history from t; +drop table t; + +--echo # End of 10.5 tests + --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/rpl_row.test b/mysql-test/suite/versioning/t/rpl_row.test index 2e5d4c76f4a..0673a50fbc3 100644 --- a/mysql-test/suite/versioning/t/rpl_row.test +++ b/mysql-test/suite/versioning/t/rpl_row.test @@ -56,4 +56,19 @@ drop table t1; --remove_files_wildcard $TMP *.txt --remove_files_wildcard $TMP *.sql +--echo # +--echo # MDEV-31297 Create table as select on system versioned tables do not work consistently on replication +--echo # +--connection master +create table t engine=innodb with system versioning as select 1 as i; +show create table t; +select * from t; + +--sync_slave_with_master +show create table t; +select * from t; + +--connection master +drop table t; + --source include/rpl_end.inc diff --git a/sql/field.cc b/sql/field.cc index 59a4295b75a..304ef569740 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8966,6 +8966,24 @@ int Field_blob::key_cmp(const uchar *a,const uchar *b) const } +#ifndef DBUG_OFF +/* helper to assert that new_table->blob_storage is NULL */ +static struct blob_storage_check +{ + union { bool b; intptr p; } val; + blob_storage_check() { val.p= -1; val.b= false; } +} blob_storage_check; +#endif +Field *Field_blob::make_new_field(MEM_ROOT *root, TABLE *newt, bool keep_type) +{ + DBUG_ASSERT((intptr(newt->blob_storage) & blob_storage_check.val.p) == 0); + if (newt->group_concat) + return new (root) Field_blob(field_length, maybe_null(), &field_name, + charset()); + return Field::make_new_field(root, newt, keep_type); +} + + Field *Field_blob::new_key_field(MEM_ROOT *root, TABLE *new_table, uchar *new_ptr, uint32 length, uchar *new_null_ptr, uint new_null_bit) diff --git a/sql/field.h b/sql/field.h index fda99ab3ac6..8a61c326318 100644 --- a/sql/field.h +++ b/sql/field.h @@ -4593,6 +4593,7 @@ public: return get_key_image_itRAW(ptr_arg, buff, length); } void set_key_image(const uchar *buff,uint length) override; + Field *make_new_field(MEM_ROOT *, TABLE *new_table, bool keep_type) override; Field *new_key_field(MEM_ROOT *root, TABLE *new_table, uchar *new_ptr, uint32 length, uchar *new_null_ptr, uint new_null_bit) override; diff --git a/sql/handler.cc b/sql/handler.cc index b9294180210..0384b41617e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -8400,6 +8400,21 @@ bool Table_scope_and_contents_source_st::vers_fix_system_fields( } +int get_select_field_pos(Alter_info *alter_info, int select_field_count, + bool versioned) +{ + int select_field_pos= alter_info->create_list.elements - select_field_count; + if (select_field_count && versioned && + /* + ALTER_PARSER_ADD_COLUMN indicates system fields was created implicitly, + select_field_count guarantees it's not ALTER TABLE + */ + alter_info->flags & ALTER_PARSER_ADD_COLUMN) + select_field_pos-= 2; + return select_field_pos; +} + + bool Table_scope_and_contents_source_st::vers_check_system_fields( THD *thd, Alter_info *alter_info, const Lex_table_name &table_name, const Lex_table_name &db, int select_count) @@ -8413,6 +8428,8 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields( { uint fieldnr= 0; List_iterator field_it(alter_info->create_list); + uint select_field_pos= (uint) get_select_field_pos(alter_info, select_count, + true); while (Create_field *f= field_it++) { /* @@ -8423,7 +8440,7 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields( SELECT go last there. */ bool is_dup= false; - if (fieldnr >= alter_info->create_list.elements - select_count) + if (fieldnr >= select_field_pos && f->invisible < INVISIBLE_SYSTEM) { List_iterator dup_it(alter_info->create_list); for (Create_field *dup= dup_it++; !is_dup && dup != f; dup= dup_it++) diff --git a/sql/handler.h b/sql/handler.h index 51b08cc943b..7b6c21927ac 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -5521,4 +5521,6 @@ uint ha_count_rw_2pc(THD *thd, bool all); uint ha_check_and_coalesce_trx_read_only(THD *thd, Ha_trx_info *ha_list, bool all); +int get_select_field_pos(Alter_info *alter_info, int select_field_count, + bool versioned); #endif /* HANDLER_INCLUDED */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index ad72c3bc1b0..0a9d22d1f40 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -4392,6 +4392,7 @@ bool Item_func_group_concat::setup(THD *thd) count_field_types(select_lex, tmp_table_param, all_fields, 0); tmp_table_param->force_copy_fields= force_copy_fields; tmp_table_param->hidden_field_count= (arg_count_order > 0); + tmp_table_param->group_concat= true; DBUG_ASSERT(table == 0); if (order_or_distinct) { @@ -4412,11 +4413,10 @@ bool Item_func_group_concat::setup(THD *thd) Note that in the table, we first have the ORDER BY fields, then the field list. */ - if (!(table= create_tmp_table(thd, tmp_table_param, all_fields, - (ORDER*) 0, 0, TRUE, - (select_lex->options | - thd->variables.option_bits), - HA_POS_ERROR, &empty_clex_str))) + table= create_tmp_table(thd, tmp_table_param, all_fields, NULL, 0, TRUE, + (select_lex->options | thd->variables.option_bits), + HA_POS_ERROR, &empty_clex_str); + if (!table) DBUG_RETURN(TRUE); table->file->extra(HA_EXTRA_NO_ROWS); table->no_rows= 1; @@ -4427,6 +4427,8 @@ bool Item_func_group_concat::setup(THD *thd) */ if (order_or_distinct && table->s->blob_fields) table->blob_storage= new (thd->mem_root) Blob_mem_storage(); + else + table->blob_storage= NULL; /* Need sorting or uniqueness: init tree and choose a function to sort. diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc index 0ccef54e900..eec69f83966 100644 --- a/sql/session_tracker.cc +++ b/sql/session_tracker.cc @@ -433,6 +433,7 @@ bool Session_sysvars_tracker::vars_list::store(THD *thd, String *buf) if (!*node->test_load) { mysql_mutex_unlock(&LOCK_plugin); + mysql_mutex_unlock(&LOCK_global_system_variables); continue; } sys_var *svar= node->m_svar; diff --git a/sql/sql_class.h b/sql/sql_class.h index 8688f1ee35d..1aab0a58d1d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -6515,6 +6515,7 @@ public: aggregate functions as normal functions. */ bool precomputed_group_by; + bool group_concat; bool force_copy_fields; /* If TRUE, create_tmp_field called from create_tmp_table will convert @@ -6533,7 +6534,7 @@ public: group_length(0), group_null_parts(0), using_outer_summary_function(0), schema_table(0), materialized_subquery(0), force_not_null_cols(0), - precomputed_group_by(0), + precomputed_group_by(0), group_concat(0), force_copy_fields(0), bit_fields_as_long(0), skip_create_table(0) { init(); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 2158758eca5..086aaf3e69f 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -659,28 +659,26 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler, } } + const KEY *c_key= table->s->key_info + handler->keyno; + if (c_key->algorithm == HA_KEY_ALG_FULLTEXT || + (ha_rkey_mode != HA_READ_KEY_EXACT && + (table->file->index_flags(handler->keyno, 0, TRUE) & + (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE)) == 0)) + { + my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), + table->file->index_type(handler->keyno), c_key->name.str); + return 1; + } + /* Check key parts */ if (mode == RKEY) { - TABLE *table= handler->table; KEY *keyinfo= table->key_info + handler->keyno; KEY_PART_INFO *key_part= keyinfo->key_part; List_iterator it_ke(*key_expr); Item *item; key_part_map keypart_map; uint key_len; - const KEY *c_key= table->s->key_info + handler->keyno; - - if ((c_key->flags & HA_SPATIAL) || - c_key->algorithm == HA_KEY_ALG_FULLTEXT || - (ha_rkey_mode != HA_READ_KEY_EXACT && - (table->file->index_flags(handler->keyno, 0, TRUE) & - (HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE)) == 0)) - { - my_error(ER_KEY_DOESNT_SUPPORT, MYF(0), - table->file->index_type(handler->keyno), keyinfo->name.str); - return 1; - } if (key_expr->elements > keyinfo->user_defined_key_parts) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 0a0b8e78b71..4aefa572c1c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1817,10 +1817,6 @@ int vers_insert_history_row(TABLE *table) if (row_start->cmp(row_start->ptr, row_end->ptr) >= 0) return 0; - if (table->vfield && - table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_READ)) - return HA_ERR_GENERIC; - return table->file->ha_write_row(table->record[0]); } @@ -4529,20 +4525,14 @@ TABLE *select_create::create_table_from_items(THD *thd, List *items, bool save_table_creation_was_logged; DBUG_ENTER("select_create::create_table_from_items"); + tmp_table.reset(); tmp_table.s= &share; init_tmp_table_share(thd, &share, "", 0, "", ""); - - tmp_table.s->db_create_options=0; - tmp_table.null_row= 0; - tmp_table.maybe_null= 0; tmp_table.in_use= thd; if (!(thd->variables.option_bits & OPTION_EXPLICIT_DEF_TIMESTAMP)) promote_first_timestamp_column(&alter_info->create_list); - if (create_info->fix_create_fields(thd, alter_info, *create_table)) - DBUG_RETURN(NULL); - while ((item=it++)) { Field *tmp_field= item->create_field_for_create_select(thd->mem_root, @@ -4580,6 +4570,9 @@ TABLE *select_create::create_table_from_items(THD *thd, List *items, alter_info->create_list.push_back(cr_field, thd->mem_root); } + if (create_info->fix_create_fields(thd, alter_info, *create_table)) + DBUG_RETURN(NULL); + /* Item*::type_handler() always returns pointers to type_handler_{time2|datetime2|timestamp2} no matter what diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 528fe545f64..7ae8e71fa4b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -20043,6 +20043,7 @@ TABLE *Create_tmp_table::start(THD *thd, table->copy_blobs= 1; table->in_use= thd; table->no_rows_with_nulls= param->force_not_null_cols; + table->group_concat= param->group_concat; table->expr_arena= thd; table->s= share; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5db48a3172c..54be2f96cdc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2651,7 +2651,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, DBUG_RETURN(TRUE); } - select_field_pos= alter_info->create_list.elements - select_field_count; + select_field_pos= get_select_field_pos(alter_info, select_field_count, + create_info->versioned()); null_fields= 0; create_info->varchar= 0; max_key_length= file->max_key_length(); @@ -2716,7 +2717,16 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, /* If this was a CREATE ... SELECT statement, accept a field redefinition if we are changing a field in the SELECT part + + The cases are: + + field_no < select_field_pos: both field and dup are table fields; + dup_no >= select_field_pos: both field and dup are select fields or + field is implicit systrem field and dup is select field. + + We are not allowed to put row_start/row_end into SELECT expression. */ + DBUG_ASSERT(dup_no < field_no); if (field_no < select_field_pos || dup_no >= select_field_pos || dup_field->invisible >= INVISIBLE_SYSTEM) { diff --git a/sql/table.cc b/sql/table.cc index 6535c342521..c170de7d25f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -9363,6 +9363,8 @@ void TABLE::vers_update_end() in_use->query_start_sec_part())) DBUG_ASSERT(0); vers_end_field()->set_has_explicit_value(); + if (vfield) + update_virtual_fields(file, VCOL_UPDATE_FOR_WRITE); } /** diff --git a/sql/table.h b/sql/table.h index a6d0f0bb3d2..b99c5f0d3be 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1495,7 +1495,6 @@ public: Used only in the MODE_NO_AUTO_VALUE_ON_ZERO mode. */ bool auto_increment_field_not_null; - bool insert_or_update; /* Can be used by the handler */ /* NOTE: alias_name_used is only a hint! It works only in need_correct_ident() condition. On other cases it is FALSE even if table_name is alias. @@ -1516,12 +1515,11 @@ public: REGINFO reginfo; /* field connections */ MEM_ROOT mem_root; - /** - Initialized in Item_func_group_concat::setup for appropriate - temporary table if GROUP_CONCAT is used with ORDER BY | DISTINCT - and BLOB field count > 0. - */ - Blob_mem_storage *blob_storage; + /* this is for temporary tables created inside Item_func_group_concat */ + union { + bool group_concat; /* used during create_tmp_table() */ + Blob_mem_storage *blob_storage; /* used after create_tmp_table() */ + }; GRANT_INFO grant; /* The arena which the items for expressions from the table definition @@ -1912,7 +1910,14 @@ public: DBUG_ASSERT(fields_nullable); DBUG_ASSERT(field < n_fields); size_t bit= size_t{field} + referenced * n_fields; - fields_nullable[bit / 8]|= (unsigned char)(1 << (bit % 8)); +#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +#endif + fields_nullable[bit / 8]|= static_cast(1 << (bit % 8)); +#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6 +# pragma GCC diagnostic pop +#endif } /** @@ -1929,7 +1934,7 @@ public: unsigned n_field= get_n_fields(); DBUG_ASSERT(field < n_field); size_t bit= size_t{field} + referenced * n_field; - return fields_nullable[bit / 8] & (1 << (bit % 8)); + return fields_nullable[bit / 8] & (1U << (bit % 8)); } } FOREIGN_KEY_INFO; diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index d2d667d1382..f91e7ee5f94 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -6472,6 +6472,15 @@ int ha_connect::create(const char *name, TABLE *table_arg, PGLOBAL g= xp->g; DBUG_ENTER("ha_connect::create"); + + if (table_arg->versioned()) + { + /* Due to microseconds not supported by CONNECT (MDEV-15967) system versioning + cannot work as expected (MDEV-15968, MDEV-28288) */ + my_error(ER_VERS_NOT_SUPPORTED, MYF(0), "CONNECT storage engine"); + DBUG_RETURN(HA_ERR_UNSUPPORTED); + } + /* This assignment fixes test failures if some "ALTER TABLE t1 ADD KEY(a)" query exits on ER_ACCESS_DENIED_ERROR diff --git a/storage/connect/mysql-test/connect/r/tbl.result b/storage/connect/mysql-test/connect/r/tbl.result index d3d1c550530..0932220a263 100644 --- a/storage/connect/mysql-test/connect/r/tbl.result +++ b/storage/connect/mysql-test/connect/r/tbl.result @@ -141,3 +141,12 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; +# +# MDEV-28288 System versioning doesn't support correct work for +# engine=connect and doesn't always give any warnings/errors +# +create table t2 ( +x int, +y int +) engine=connect table_type=FIX file_name='test.txt' with system versioning; +ERROR HY000: System-versioned tables do not support CONNECT storage engine diff --git a/storage/connect/mysql-test/connect/t/tbl.test b/storage/connect/mysql-test/connect/t/tbl.test index 4f8497d4e6a..19f633e9bf7 100644 --- a/storage/connect/mysql-test/connect/t/tbl.test +++ b/storage/connect/mysql-test/connect/t/tbl.test @@ -51,3 +51,14 @@ DROP TABLE t1; DROP TABLE t2; DROP TABLE t3; DROP TABLE t4; + + +--echo # +--echo # MDEV-28288 System versioning doesn't support correct work for +--echo # engine=connect and doesn't always give any warnings/errors +--echo # +--error ER_VERS_NOT_SUPPORTED +create table t2 ( + x int, + y int +) engine=connect table_type=FIX file_name='test.txt' with system versioning; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 61cc2ce1e3a..da15546c486 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -12673,7 +12673,10 @@ create_table_info_t::create_foreign_keys() } } } - +#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +#endif switch (fk->delete_opt) { case FK_OPTION_UNDEF: case FK_OPTION_RESTRICT: @@ -12715,6 +12718,9 @@ create_table_info_t::create_foreign_keys() ut_ad(0); break; } +#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6 +# pragma GCC diagnostic pop +#endif } if (dict_foreigns_has_s_base_col(local_fk_set, table)) { diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 31d3afb7818..5afc2b8e9a2 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -3010,6 +3010,10 @@ innobase_set_foreign_key_option( break; } +#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +#endif switch (fk_key->update_opt) { case FK_OPTION_NO_ACTION: case FK_OPTION_RESTRICT: @@ -3026,6 +3030,9 @@ innobase_set_foreign_key_option( break; } +#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 6 +# pragma GCC diagnostic pop +#endif return(innobase_check_fk_option(foreign)); } diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 65881c10e4f..70b245cb868 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -997,11 +997,11 @@ int ha_myisam::write_row(const uchar *buf) return mi_write(file,buf); } -void ha_myisam::setup_vcols_for_repair(HA_CHECK *param) +int ha_myisam::setup_vcols_for_repair(HA_CHECK *param) { DBUG_ASSERT(file->s->base.reclength <= file->s->vreclength); if (!table->vfield) - return; + return 0; if (file->s->base.reclength == file->s->vreclength) { @@ -1018,14 +1018,18 @@ void ha_myisam::setup_vcols_for_repair(HA_CHECK *param) } } if (!indexed_vcols) - return; + return 0; file->s->vreclength= new_vreclength; + if (!mi_alloc_rec_buff(file, -1, &file->rec_buff)) + return HA_ERR_OUT_OF_MEM; + bzero(file->rec_buff, mi_get_rec_buff_len(file, file->rec_buff)); } DBUG_ASSERT(file->s->base.reclength < file->s->vreclength || !table->s->stored_fields); param->init_fix_record= init_compute_vcols; param->fix_record= compute_vcols; table->use_all_columns(); + return 0; } int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) @@ -1061,7 +1065,11 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt) (uint) (share->global_changed ? 1 : 0))))) return HA_ADMIN_ALREADY_DONE; - setup_vcols_for_repair(param); + if ((error = setup_vcols_for_repair(param))) + { + thd_proc_info(thd, old_proc_info); + return error; + } error = chk_status(param, file); // Not fatal error = chk_size(param, file); @@ -1157,7 +1165,8 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) if (!(share->state.changed & STATE_NOT_ANALYZED)) return HA_ADMIN_ALREADY_DONE; - setup_vcols_for_repair(param); + if ((error = setup_vcols_for_repair(param))) + return error; error = chk_key(param, file); if (!error) @@ -1192,7 +1201,8 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) param->backup_time= check_opt->start_time; start_records=file->state->records; - setup_vcols_for_repair(param); + if ((error = setup_vcols_for_repair(param))) + return error; while ((error=repair(thd,*param,0)) && param->retry_repair) { @@ -1245,7 +1255,8 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) param->tmpfile_createflag= O_RDWR | O_TRUNC; param->sort_buffer_length= THDVAR(thd, sort_buffer_size); - setup_vcols_for_repair(param); + if ((error = setup_vcols_for_repair(param))) + return error; if ((error= repair(thd,*param,1)) && param->retry_repair) { @@ -1665,7 +1676,11 @@ int ha_myisam::enable_indexes(key_map map, bool persist) param->stats_method= (enum_handler_stats_method)THDVAR(thd, stats_method); param->tmpdir=&mysql_tmpdir_list; - setup_vcols_for_repair(param); + if ((error = setup_vcols_for_repair(param))) + { + thd_proc_info(thd, save_proc_info); + DBUG_RETURN(error); + } if ((error= (repair(thd,*param,0) != HA_ADMIN_OK)) && param->retry_repair) { diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index e72636e9e22..24790040cf8 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -48,7 +48,7 @@ class ha_myisam final : public handler char *data_file_name, *index_file_name; bool can_enable_indexes; int repair(THD *thd, HA_CHECK ¶m, bool optimize); - void setup_vcols_for_repair(HA_CHECK *param); + int setup_vcols_for_repair(HA_CHECK *param); public: ha_myisam(handlerton *hton, TABLE_SHARE *table_arg);