diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake index dae3b56b584..9d3d3cd50c5 100644 --- a/cmake/dtrace.cmake +++ b/cmake/dtrace.cmake @@ -125,16 +125,20 @@ FUNCTION(DTRACE_INSTRUMENT target) WORKING_DIRECTORY ${objdir} ) ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Linux") - # dtrace on Linux runs gcc and uses flags from environment - SET(CFLAGS_SAVED $ENV{CFLAGS}) - SET(ENV{CFLAGS} ${CMAKE_C_FLAGS}) + IF (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # dtrace on Linux runs gcc and uses flags from environment + SET(CFLAGS_SAVED $ENV{CFLAGS}) + SET(ENV{CFLAGS} ${CMAKE_C_FLAGS}) + ENDIF() SET(outfile "${CMAKE_BINARY_DIR}/probes_mysql.o") # Systemtap object EXECUTE_PROCESS( COMMAND ${DTRACE} -G -s ${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base -o ${outfile} ) - SET(ENV{CFLAGS} ${CFLAGS_SAVED}) + IF (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + SET(ENV{CFLAGS} ${CFLAGS_SAVED}) + ENDIF() ENDIF() # Do not try to extend the library if we have not built the .o file diff --git a/mysql-test/main/partition.result b/mysql-test/main/partition.result index a9a19cf7748..f6a656b581f 100644 --- a/mysql-test/main/partition.result +++ b/mysql-test/main/partition.result @@ -2858,6 +2858,26 @@ id select_type table type possible_keys key key_len ref rows Extra set optimizer_switch=@tmp_os; drop table t1,t2,t3; # +# MDEV-31030 Assertion `!error' failed in ha_partition::update_row on UPDATE +# +create table t (c int) +partition by list (1 div c) ( +partition p0 values in (null), +partition p values in (1)); +insert ignore into t values (0), (1), (0); +Warnings: +Warning 1365 Division by 0 +Warning 1365 Division by 0 +update t set c= 2; +ERROR HY000: Table has no partition for value 0 +update ignore t set c= 3; +select * from t; +c +0 +0 +1 +drop table t; +# # MDEV-32388 MSAN / Valgrind errors in # Item_func_like::get_mm_leaf upon query from partitioned table # diff --git a/mysql-test/main/partition.test b/mysql-test/main/partition.test index ed7437e4a15..440a7a42971 100644 --- a/mysql-test/main/partition.test +++ b/mysql-test/main/partition.test @@ -3070,6 +3070,22 @@ set optimizer_switch=@tmp_os; drop table t1,t2,t3; +--echo # +--echo # MDEV-31030 Assertion `!error' failed in ha_partition::update_row on UPDATE +--echo # + +create table t (c int) +partition by list (1 div c) ( + partition p0 values in (null), + partition p values in (1)); +insert ignore into t values (0), (1), (0); +--error ER_NO_PARTITION_FOR_GIVEN_VALUE +update t set c= 2; +--disable_warnings +update ignore t set c= 3; +--enable_warnings +select * from t; +drop table t; --echo # --echo # MDEV-32388 MSAN / Valgrind errors in diff --git a/mysql-test/main/ps_11bugs.result b/mysql-test/main/ps_11bugs.result index 3bc7039583b..87a3487141b 100644 --- a/mysql-test/main/ps_11bugs.result +++ b/mysql-test/main/ps_11bugs.result @@ -191,3 +191,58 @@ Warnings: Warning 1292 Truncated incorrect INTEGER value: '+ -><()~*:""&|' SET @@sort_buffer_size=DEFAULT; End of 5.0 tests. +# Start of 10.5 tests +# +# MDEV-25593 Assertion `0' failed in Type_handler_temporal_result::Item_get_date on double EXECUTE +# +SET time_zone='+00:00'; +SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30'); +PREPARE stmt FROM 'SELECT ? AS c1'; +EXECUTE stmt USING current_timestamp; +c1 +2001-01-01 10:20:30 +EXECUTE stmt USING @unknown; +c1 +NULL +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT ? AS c1 FROM DUAL'; +EXECUTE stmt USING current_time; +c1 +10:20:30 +EXECUTE stmt USING DEFAULT; +c1 +NULL +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT ? AS c1 FROM DUAL'; +EXECUTE stmt USING current_time; +c1 +10:20:30 +EXECUTE stmt USING IGNORE; +c1 +NULL +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM "SELECT DATE('') between''AND ? AS c1"; +EXECUTE stmt USING current_time; +c1 +1 +Warnings: +Warning 1292 Truncated incorrect datetime value: '' +Warning 1292 Truncated incorrect datetime value: '' +EXECUTE stmt USING @unknown; +c1 +NULL +Warnings: +Warning 1292 Truncated incorrect datetime value: '' +Warning 1292 Truncated incorrect datetime value: '' +DEALLOCATE PREPARE stmt; +PREPARE stmt FROM 'SELECT CONCAT(UNIX_TIMESTAMP(?)) AS c1'; +EXECUTE stmt USING CURRENT_TIMESTAMP; +c1 +978344430 +EXECUTE stmt USING @unknown; +c1 +NULL +DEALLOCATE PREPARE stmt; +SET timestamp=DEFAULT; +SET time_zone=DEFAULT; +# End of 10.5 tests diff --git a/mysql-test/main/ps_11bugs.test b/mysql-test/main/ps_11bugs.test index 1888de060fc..7a0843e9352 100644 --- a/mysql-test/main/ps_11bugs.test +++ b/mysql-test/main/ps_11bugs.test @@ -217,3 +217,41 @@ SELECT LEFT("12345", @@ft_boolean_syntax); SET @@sort_buffer_size=DEFAULT; --echo End of 5.0 tests. + + +--echo # Start of 10.5 tests + +--echo # +--echo # MDEV-25593 Assertion `0' failed in Type_handler_temporal_result::Item_get_date on double EXECUTE +--echo # + +SET time_zone='+00:00'; +SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30'); +PREPARE stmt FROM 'SELECT ? AS c1'; +EXECUTE stmt USING current_timestamp; +EXECUTE stmt USING @unknown; +DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM 'SELECT ? AS c1 FROM DUAL'; +EXECUTE stmt USING current_time; +EXECUTE stmt USING DEFAULT; +DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM 'SELECT ? AS c1 FROM DUAL'; +EXECUTE stmt USING current_time; +EXECUTE stmt USING IGNORE; +DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM "SELECT DATE('') between''AND ? AS c1"; +EXECUTE stmt USING current_time; +EXECUTE stmt USING @unknown; +DEALLOCATE PREPARE stmt; + +PREPARE stmt FROM 'SELECT CONCAT(UNIX_TIMESTAMP(?)) AS c1'; +EXECUTE stmt USING CURRENT_TIMESTAMP; +EXECUTE stmt USING @unknown; +DEALLOCATE PREPARE stmt; +SET timestamp=DEFAULT; +SET time_zone=DEFAULT; + +--echo # End of 10.5 tests diff --git a/mysql-test/main/servers.result b/mysql-test/main/servers.result index 585f0f62af0..c466967a0db 100644 --- a/mysql-test/main/servers.result +++ b/mysql-test/main/servers.result @@ -24,3 +24,17 @@ SELECT * FROM mysql.servers; Server_name Host Db Username Password Port Socket Wrapper Owner s1 3306 bar mysql DROP SERVER s1; +# +# MDEV-33783 CREATE SERVER segfaults on wrong mysql.servers +# +create server s1 foreign data wrapper foo options(user 'a'); +alter server s1 options(host 'server.example.org'); +rename table mysql.servers to mysql.servers_save; +create table mysql.servers (x int); +alter server s1 options(host 'server.example.org'); +ERROR HY000: The foreign server name you are trying to reference does not exist. Data source error: s1 +create server s2 foreign data wrapper foo options(user 'a'); +ERROR HY000: Can't read record in system table +drop table mysql.servers; +rename table mysql.servers_save to mysql.servers; +drop server s1; diff --git a/mysql-test/main/servers.test b/mysql-test/main/servers.test index 645206c376e..6aaaa356c1d 100644 --- a/mysql-test/main/servers.test +++ b/mysql-test/main/servers.test @@ -22,3 +22,18 @@ DROP SERVER s1; CREATE SERVER s1 FOREIGN DATA WRAPPER mysql OPTIONS(SOCKET 'bar'); SELECT * FROM mysql.servers; DROP SERVER s1; + +--echo # +--echo # MDEV-33783 CREATE SERVER segfaults on wrong mysql.servers +--echo # +create server s1 foreign data wrapper foo options(user 'a'); +alter server s1 options(host 'server.example.org'); +rename table mysql.servers to mysql.servers_save; +create table mysql.servers (x int); +--error ER_FOREIGN_SERVER_DOESNT_EXIST +alter server s1 options(host 'server.example.org'); +--error ER_CANT_FIND_SYSTEM_REC +create server s2 foreign data wrapper foo options(user 'a'); +drop table mysql.servers; +rename table mysql.servers_save to mysql.servers; +drop server s1; diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index 8068088fec8..cbb42331792 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -10,8 +10,6 @@ # ############################################################################## -galera_as_slave_ctas : MDEV-28378 timeout galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATING -> COMMITTED -galera_concurrent_ctas : MDEV-32779 galera_concurrent_ctas: assertion in the galera::ReplicatorSMM::finish_cert() galera_as_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() galera_slave_replay : MDEV-32780 galera_as_slave_replay: assertion in the wsrep::transaction::before_rollback() diff --git a/mysql-test/suite/galera/r/galera_concurrent_ctas.result b/mysql-test/suite/galera/r/galera_concurrent_ctas.result index 933f1d2a98e..a25e367bf74 100644 --- a/mysql-test/suite/galera/r/galera_concurrent_ctas.result +++ b/mysql-test/suite/galera/r/galera_concurrent_ctas.result @@ -3,6 +3,7 @@ connection node_1; connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1; connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; +connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2; connection node_1; SET DEBUG_SYNC = 'wsrep_create_table_as_select WAIT_FOR continue'; CREATE table t1 as SELECT SLEEP(0.1);; @@ -17,14 +18,30 @@ connection node_1b; SET SESSION debug_sync = 'now WAIT_FOR sync.wsrep_apply_cb_reached'; # Signal first CTAS to continue and wait until CTAS has executed SET DEBUG_SYNC= 'now SIGNAL continue'; +connection node_2b; +# Wait first CTAS to replicate +SELECT * FROM t1; +SLEEP(0.2) +0 +connection node_1b; SET GLOBAL debug_dbug= ''; SET DEBUG_SYNC = 'now SIGNAL signal.wsrep_apply_cb'; connection node_2a; connection node_1b; SET DEBUG_SYNC= 'RESET'; connection node_2; +SELECT * FROM t1; +SLEEP(0.2) +0 connection node_1; +SELECT * FROM t1; +SLEEP(0.2) +0 DROP TABLE t1; +disconnect node_1a; +disconnect node_1b; +disconnect node_2a; +disconnect node_2b; disconnect node_2; disconnect node_1; # End of test diff --git a/mysql-test/suite/galera/r/galera_wan.result b/mysql-test/suite/galera/r/galera_wan.result index 21cd5258590..3904c1dc517 100644 --- a/mysql-test/suite/galera/r/galera_wan.result +++ b/mysql-test/suite/galera/r/galera_wan.result @@ -35,3 +35,10 @@ SELECT VARIABLE_VALUE LIKE '%gmcast.segment = 3%' FROM INFORMATION_SCHEMA.GLOBAL VARIABLE_VALUE LIKE '%gmcast.segment = 3%' 1 DROP TABLE t1; +connection node_1; +call mtr.add_suppression("WSREP: read_completion_condition.*"); +call mtr.add_suppression("WSREP: read_handler.*"); +disconnect node_3; +disconnect node_4; +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera/t/galera_concurrent_ctas.combinations b/mysql-test/suite/galera/t/galera_concurrent_ctas.combinations new file mode 100644 index 00000000000..1eeb8fb4614 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_concurrent_ctas.combinations @@ -0,0 +1,4 @@ +[binlogoff] + +[binlogon] +log-bin diff --git a/mysql-test/suite/galera/t/galera_concurrent_ctas.test b/mysql-test/suite/galera/t/galera_concurrent_ctas.test index e22ac811c8b..ed579f19a0d 100644 --- a/mysql-test/suite/galera/t/galera_concurrent_ctas.test +++ b/mysql-test/suite/galera/t/galera_concurrent_ctas.test @@ -9,6 +9,7 @@ --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1 --connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2 +--connect node_2b, 127.0.0.1, root, , test, $NODE_MYPORT_2 --connection node_1 # @@ -48,6 +49,14 @@ SET SESSION debug_sync = 'now WAIT_FOR sync.wsrep_apply_cb_reached'; SET DEBUG_SYNC= 'now SIGNAL continue'; --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'Creating table CREATE table t1 as SELECT SLEEP(0.1)' --source include/wait_condition.inc + +--connection node_2b +--echo # Wait first CTAS to replicate +--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1' +--source include/wait_condition.inc +SELECT * FROM t1; + +--connection node_1b # # Release second CTAS and cleanup # @@ -74,12 +83,18 @@ SET DEBUG_SYNC= 'RESET'; # --connection node_2 --reap +SELECT * FROM t1; --connection node_1 ---error 0,ER_TABLE_EXISTS_ERROR,ER_QUERY_INTERRUPTED +--error 0,ER_QUERY_INTERRUPTED,ER_LOCK_DEADLOCK --reap +SELECT * FROM t1; DROP TABLE t1; +--disconnect node_1a +--disconnect node_1b +--disconnect node_2a +--disconnect node_2b --source include/galera_end.inc --echo # End of test diff --git a/mysql-test/suite/galera/t/galera_wan.test b/mysql-test/suite/galera/t/galera_wan.test index 73be33fa33d..ab2346ebe94 100644 --- a/mysql-test/suite/galera/t/galera_wan.test +++ b/mysql-test/suite/galera/t/galera_wan.test @@ -40,3 +40,12 @@ SELECT COUNT(*) AS EXPECT_1 FROM t1; SELECT VARIABLE_VALUE LIKE '%gmcast.segment = 3%' FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME = 'wsrep_provider_options'; DROP TABLE t1; + +--connection node_1 +call mtr.add_suppression("WSREP: read_completion_condition.*"); +call mtr.add_suppression("WSREP: read_handler.*"); + +--disconnect node_3 +--disconnect node_4 + +--source include/galera_end.inc diff --git a/mysql-test/suite/plugins/r/server_audit_pwd_mask.result b/mysql-test/suite/plugins/r/server_audit_pwd_mask.result index 7cf3b05bcf1..ce90230f1ea 100644 --- a/mysql-test/suite/plugins/r/server_audit_pwd_mask.result +++ b/mysql-test/suite/plugins/r/server_audit_pwd_mask.result @@ -1,3 +1,6 @@ +# +# MDEV-35507 and MDEV-35522 +# install plugin ed25519 soname 'auth_ed25519'; install plugin server_audit soname 'server_audit'; set global server_audit_file_path='server_audit.log'; @@ -6,17 +9,25 @@ set global server_audit_logging=on; # unsafe to log passwords (pwd-123) CREATE USER u1 IDENTIFIED BY 'pwd_123'; create user u2 IDENTIFIED VIA ed25519 USING PASSWORD('pwd_123'); +CREATE OR REPLACE USER u1 IDENTIFIED BY 'pwd_123'; SET PASSWORD FOR u1 = PASSWORD('pwd_123'); ALTER USER u1 IDENTIFIED BY 'pwd_123'; +ALTER USER if exists u1 IDENTIFIED BY 'pwd_123'; +SET STATEMENT max_statement_time=10 FOR ALTER USER u1 IDENTIFIED BY 'pwd_123'; alter user u2 identified VIA ed25519 USING password('pwd_123'); GRANT ALL ON test TO u1 IDENTIFIED BY "pwd_123"; GRANT ALL ON test TO u1 identified VIA ed25519 as password('pwd_123') or ed25519 using password('pwd_123'); +CREATE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123"); +CREATE OR REPLACE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123"); +CREATE OR REPLACE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123"); # pattern should not be found NOT FOUND /pwd_123/ in server_audit.log # pattern should not be found # cleaunup +DROP SERVER s1; DROP USER u1; DROP USER u2; set global server_audit_logging=off; UNINSTALL PLUGIN ed25519; UNINSTALL PLUGIN server_audit; +# end of 10.5 tests diff --git a/mysql-test/suite/plugins/t/server_audit_pwd_mask.test b/mysql-test/suite/plugins/t/server_audit_pwd_mask.test index af6425b2035..b393e22d11e 100644 --- a/mysql-test/suite/plugins/t/server_audit_pwd_mask.test +++ b/mysql-test/suite/plugins/t/server_audit_pwd_mask.test @@ -13,6 +13,10 @@ if (!$AUTH_ED25519_SO) { let $MYSQLD_DATADIR= `SELECT @@datadir`; let SEARCH_FILE= $MYSQLD_DATADIR/server_audit.log; +--echo # +--echo # MDEV-35507 and MDEV-35522 +--echo # + install plugin ed25519 soname 'auth_ed25519'; install plugin server_audit soname 'server_audit'; @@ -25,17 +29,24 @@ set global server_audit_logging=on; CREATE USER u1 IDENTIFIED BY 'pwd_123'; create user u2 IDENTIFIED VIA ed25519 USING PASSWORD('pwd_123'); +CREATE OR REPLACE USER u1 IDENTIFIED BY 'pwd_123'; SET PASSWORD FOR u1 = PASSWORD('pwd_123'); ALTER USER u1 IDENTIFIED BY 'pwd_123'; +ALTER USER if exists u1 IDENTIFIED BY 'pwd_123'; +SET STATEMENT max_statement_time=10 FOR ALTER USER u1 IDENTIFIED BY 'pwd_123'; alter user u2 identified VIA ed25519 USING password('pwd_123'); GRANT ALL ON test TO u1 IDENTIFIED BY "pwd_123"; GRANT ALL ON test TO u1 identified VIA ed25519 as password('pwd_123') or ed25519 using password('pwd_123'); +CREATE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123"); +CREATE OR REPLACE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123"); +CREATE OR REPLACE SERVER s1 FOREIGN DATA WRAPPER mariadb OPTIONS ( PASSWORD "pwd_123"); --let SEARCH_PATTERN=pwd_123 --echo # pattern should not be found --source include/search_pattern_in_file.inc --echo # pattern should not be found --echo # cleaunup +DROP SERVER s1; DROP USER u1; DROP USER u2; set global server_audit_logging=off; @@ -44,3 +55,5 @@ set global server_audit_logging=off; UNINSTALL PLUGIN ed25519; UNINSTALL PLUGIN server_audit; --enable_warnings + +--echo # end of 10.5 tests diff --git a/mysql-test/suite/versioning/r/load_data.result b/mysql-test/suite/versioning/r/load_data.result deleted file mode 100644 index 1fcde73e565..00000000000 --- a/mysql-test/suite/versioning/r/load_data.result +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE t1 (a INT, b INT, c INT, vc INT AS (c), UNIQUE(a), UNIQUE(b)) WITH SYSTEM VERSIONING; -INSERT IGNORE INTO t1 (a,b,c) VALUES (1,2,3); -SELECT a, b, c FROM t1 INTO OUTFILE '15330.data'; -Warnings: -Warning 1287 ' INTO FROM...' instead -LOAD DATA INFILE '15330.data' IGNORE INTO TABLE t1 (a,b,c); -Warnings: -Warning 1062 Duplicate entry '1' for key 'a' -LOAD DATA INFILE '15330.data' REPLACE INTO TABLE t1 (a,b,c); -DROP TABLE t1; diff --git a/mysql-test/suite/versioning/r/replace.result b/mysql-test/suite/versioning/r/replace.result index 57a992cce49..8ac4047c5ff 100644 --- a/mysql-test/suite/versioning/r/replace.result +++ b/mysql-test/suite/versioning/r/replace.result @@ -61,3 +61,14 @@ connection con1; replace into t1 values (1),(2); ERROR 23000: Duplicate entry '1' for key 'PRIMARY' drop table t1; +# +# MDEV-15330 Server crash or assertion `table->insert_values' failure in write_record upon LOAD DATA +# +create table t1 (a int, b int, c int, vc int as (c), unique(a), unique(b)) with system versioning; +insert ignore into t1 (a,b,c) values (1,2,3); +select a, b, c into outfile '15330.data' from t1; +load data infile '15330.data' ignore into table t1 (a,b,c); +Warnings: +Warning 1062 Duplicate entry '1' for key 'a' +load data infile '15330.data' replace into table t1 (a,b,c); +drop table t1; diff --git a/mysql-test/suite/versioning/t/load_data.test b/mysql-test/suite/versioning/t/load_data.test deleted file mode 100644 index 317d0de52c6..00000000000 --- a/mysql-test/suite/versioning/t/load_data.test +++ /dev/null @@ -1,18 +0,0 @@ -# -# MDEV-15330 Server crash or assertion `table->insert_values' failure in write_record upon LOAD DATA -# -CREATE TABLE t1 (a INT, b INT, c INT, vc INT AS (c), UNIQUE(a), UNIQUE(b)) WITH SYSTEM VERSIONING; -INSERT IGNORE INTO t1 (a,b,c) VALUES (1,2,3); - ---disable_cursor_protocol ---enable_prepare_warnings ---disable_ps2_protocol -SELECT a, b, c FROM t1 INTO OUTFILE '15330.data'; ---disable_prepare_warnings ---enable_ps2_protocol ---enable_cursor_protocol -LOAD DATA INFILE '15330.data' IGNORE INTO TABLE t1 (a,b,c); -LOAD DATA INFILE '15330.data' REPLACE INTO TABLE t1 (a,b,c); - -# Cleanup -DROP TABLE t1; diff --git a/mysql-test/suite/versioning/t/replace.test b/mysql-test/suite/versioning/t/replace.test index 83489f4a4b9..d69eebd1b9c 100644 --- a/mysql-test/suite/versioning/t/replace.test +++ b/mysql-test/suite/versioning/t/replace.test @@ -77,4 +77,32 @@ replace into t1 values (1),(2); drop table t1; +--echo # +--echo # MDEV-15330 Server crash or assertion `table->insert_values' failure in write_record upon LOAD DATA +--echo # +if ($default_engine == MEMORY) +{ + --disable_query_log + set default_storage_engine= myisam; + --enable_query_log +} +create table t1 (a int, b int, c int, vc int as (c), unique(a), unique(b)) with system versioning; +insert ignore into t1 (a,b,c) values (1,2,3); + +--disable_cursor_protocol +--disable_ps2_protocol +select a, b, c into outfile '15330.data' from t1; +--enable_ps2_protocol +--enable_cursor_protocol +load data infile '15330.data' ignore into table t1 (a,b,c); +load data infile '15330.data' replace into table t1 (a,b,c); +--let $datadir=`select @@datadir` +--remove_file $datadir/test/15330.data + +# cleanup +drop table t1; +--disable_query_log +eval set default_storage_engine= $default_engine; +--enable_query_log + --source suite/versioning/common_finish.inc diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 20eda30657b..af4de984fe1 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -826,6 +826,7 @@ enum sa_keywords SQLCOM_TRUNCATE, SQLCOM_QUERY_ADMIN, SQLCOM_DCL, + SQLCOM_FOUND=-1, }; struct sa_keyword @@ -837,30 +838,87 @@ struct sa_keyword }; -struct sa_keyword xml_word= {3, "XML", 0, SQLCOM_NOTHING}; -struct sa_keyword user_word= {4, "USER", 0, SQLCOM_NOTHING}; -struct sa_keyword data_word= {4, "DATA", 0, SQLCOM_NOTHING}; -struct sa_keyword server_word= {6, "SERVER", 0, SQLCOM_NOTHING}; -struct sa_keyword master_word= {6, "MASTER", 0, SQLCOM_NOTHING}; -struct sa_keyword password_word= {8, "PASSWORD", 0, SQLCOM_NOTHING}; -struct sa_keyword function_word= {8, "FUNCTION", 0, SQLCOM_NOTHING}; -struct sa_keyword statement_word= {9, "STATEMENT", 0, SQLCOM_NOTHING}; -struct sa_keyword procedure_word= {9, "PROCEDURE", 0, SQLCOM_NOTHING}; +struct sa_keyword xml_word[]= +{ + {3, "XML", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword user_word[]= +{ + {4, "USER", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword data_word[]= +{ + {4, "DATA", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword server_word[]= +{ + {6, "SERVER", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword master_word[]= +{ + {6, "MASTER", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword password_word[]= +{ + {8, "PASSWORD", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword function_word[]= +{ + {8, "FUNCTION", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword statement_word[]= +{ + {9, "STATEMENT", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword procedure_word[]= +{ + {9, "PROCEDURE", 0, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword replace_user_word[]= +{ + {7, "REPLACE", user_word, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword or_replace_user_word[]= +{ + {2, "OR", replace_user_word, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword replace_server_word[]= +{ + {7, "REPLACE", server_word, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; +struct sa_keyword or_replace_server_word[]= +{ + {2, "OR", replace_server_word, SQLCOM_FOUND}, + {0, NULL, 0, SQLCOM_NOTHING} +}; struct sa_keyword keywords_to_skip[]= { - {3, "SET", &statement_word, SQLCOM_QUERY_ADMIN}, - {0, NULL, 0, SQLCOM_DDL} + {3, "SET", statement_word, SQLCOM_QUERY_ADMIN}, + {0, NULL, 0, SQLCOM_NOTHING} }; struct sa_keyword not_ddl_keywords[]= { - {4, "DROP", &user_word, SQLCOM_DCL}, - {6, "CREATE", &user_word, SQLCOM_DCL}, - {6, "RENAME", &user_word, SQLCOM_DCL}, - {0, NULL, 0, SQLCOM_DDL} + {4, "DROP", user_word, SQLCOM_DCL}, + {6, "CREATE", user_word, SQLCOM_DCL}, + {6, "CREATE", or_replace_user_word, SQLCOM_DCL}, + {6, "RENAME", user_word, SQLCOM_DCL}, + {0, NULL, 0, SQLCOM_NOTHING} }; @@ -871,7 +929,7 @@ struct sa_keyword ddl_keywords[]= {6, "CREATE", 0, SQLCOM_DDL}, {6, "RENAME", 0, SQLCOM_DDL}, {8, "TRUNCATE", 0, SQLCOM_DDL}, - {0, NULL, 0, SQLCOM_DDL} + {0, NULL, 0, SQLCOM_NOTHING} }; @@ -879,15 +937,15 @@ struct sa_keyword dml_keywords[]= { {2, "DO", 0, SQLCOM_DML}, {4, "CALL", 0, SQLCOM_DML}, - {4, "LOAD", &data_word, SQLCOM_DML}, - {4, "LOAD", &xml_word, SQLCOM_DML}, + {4, "LOAD", data_word, SQLCOM_DML}, + {4, "LOAD", xml_word, SQLCOM_DML}, {6, "DELETE", 0, SQLCOM_DML}, {6, "INSERT", 0, SQLCOM_DML}, {6, "SELECT", 0, SQLCOM_DML}, {6, "UPDATE", 0, SQLCOM_DML}, {7, "HANDLER", 0, SQLCOM_DML}, {7, "REPLACE", 0, SQLCOM_DML}, - {0, NULL, 0, SQLCOM_DML} + {0, NULL, 0, SQLCOM_NOTHING} }; @@ -895,38 +953,41 @@ struct sa_keyword dml_no_select_keywords[]= { {2, "DO", 0, SQLCOM_DML}, {4, "CALL", 0, SQLCOM_DML}, - {4, "LOAD", &data_word, SQLCOM_DML}, - {4, "LOAD", &xml_word, SQLCOM_DML}, + {4, "LOAD", data_word, SQLCOM_DML}, + {4, "LOAD", xml_word, SQLCOM_DML}, {6, "DELETE", 0, SQLCOM_DML}, {6, "INSERT", 0, SQLCOM_DML}, {6, "UPDATE", 0, SQLCOM_DML}, {7, "HANDLER", 0, SQLCOM_DML}, {7, "REPLACE", 0, SQLCOM_DML}, - {0, NULL, 0, SQLCOM_DML} + {0, NULL, 0, SQLCOM_NOTHING} }; struct sa_keyword dcl_keywords[]= { - {6, "CREATE", &user_word, SQLCOM_DCL}, - {4, "DROP", &user_word, SQLCOM_DCL}, - {6, "RENAME", &user_word, SQLCOM_DCL}, + {6, "CREATE", user_word, SQLCOM_DCL}, + {6, "CREATE", or_replace_user_word, SQLCOM_DCL}, + {4, "DROP", user_word, SQLCOM_DCL}, + {6, "RENAME", user_word, SQLCOM_DCL}, {5, "GRANT", 0, SQLCOM_DCL}, {6, "REVOKE", 0, SQLCOM_DCL}, - {3, "SET", &password_word, SQLCOM_DCL}, - {0, NULL, 0, SQLCOM_DDL} + {3, "SET", password_word, SQLCOM_DCL}, + {0, NULL, 0, SQLCOM_NOTHING} }; struct sa_keyword passwd_keywords[]= { - {3, "SET", &password_word, SQLCOM_SET_OPTION}, - {5, "ALTER", &server_word, SQLCOM_ALTER_SERVER}, - {5, "ALTER", &user_word, SQLCOM_ALTER_USER}, + {3, "SET", password_word, SQLCOM_SET_OPTION}, + {5, "ALTER", server_word, SQLCOM_ALTER_SERVER}, + {5, "ALTER", user_word, SQLCOM_ALTER_USER}, {5, "GRANT", 0, SQLCOM_GRANT}, - {6, "CREATE", &user_word, SQLCOM_CREATE_USER}, - {6, "CREATE", &server_word, SQLCOM_CREATE_SERVER}, - {6, "CHANGE", &master_word, SQLCOM_CHANGE_MASTER}, + {6, "CREATE", user_word, SQLCOM_CREATE_USER}, + {6, "CREATE", or_replace_user_word, SQLCOM_CREATE_USER}, + {6, "CREATE", server_word, SQLCOM_CREATE_SERVER}, + {6, "CREATE", or_replace_server_word, SQLCOM_CREATE_SERVER}, + {6, "CHANGE", master_word, SQLCOM_CHANGE_MASTER}, {0, NULL, 0, SQLCOM_NOTHING} }; @@ -1749,7 +1810,7 @@ static int filter_query_type(const char *query, struct sa_keyword *kwd) query++; } - qwe_in_list= 0; + qwe_in_list= SQLCOM_NOTHING; if (!(len= get_next_word(query, fword))) goto not_in_list; query+= len+1; @@ -1767,8 +1828,7 @@ static int filter_query_type(const char *query, struct sa_keyword *kwd) query++; nlen= get_next_word(query, nword); } - if (l_keywords->next->length != nlen || - strncmp(l_keywords->next->wd, nword, nlen) != 0) + if (filter_query_type(query, l_keywords->next) == SQLCOM_NOTHING) goto do_loop; } @@ -1783,6 +1843,25 @@ not_in_list: return qwe_in_list; } +static const char *skip_set_statement(const char *query) +{ + if (filter_query_type(query, keywords_to_skip)) + { + char fword[MAX_KEYWORD + 1]; + int len; + do + { + len= get_next_word(query, fword); + query+= len ? len : 1; + if (len == 3 && strncmp(fword, "FOR", 3) == 0) + break; + } while (*query); + + if (*query == 0) + return 0; + } + return query; +} static int log_statement_ex(const struct connection_info *cn, time_t ev_time, unsigned long thd_id, @@ -1826,21 +1905,8 @@ static int log_statement_ex(const struct connection_info *cn, { const char *orig_query= query; - if (filter_query_type(query, keywords_to_skip)) - { - char fword[MAX_KEYWORD + 1]; - int len; - do - { - len= get_next_word(query, fword); - query+= len ? len : 1; - if (len == 3 && strncmp(fword, "FOR", 3) == 0) - break; - } while (*query); - - if (*query == 0) - return 0; - } + if ((query= skip_set_statement(query)) == SQLCOM_NOTHING) + return 0; if (events & EVENT_QUERY_DDL) { @@ -1896,7 +1962,7 @@ do_log_query: if (query_log_limit > 0 && uh_buffer_size > query_log_limit+2) uh_buffer_size= query_log_limit+2; - switch (filter_query_type(query, passwd_keywords)) + switch (filter_query_type(skip_set_statement(query), passwd_keywords)) { case SQLCOM_GRANT: case SQLCOM_CREATE_USER: diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_ps.result b/plugin/type_inet/mysql-test/type_inet/type_inet6_ps.result new file mode 100644 index 00000000000..4458f5e2f75 --- /dev/null +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_ps.result @@ -0,0 +1,17 @@ +# Start of 10.5 tests +# +# MDEV-35427 Assertion `is_null() >= item->null_value' failed in Timestamp_or_zero_datetime_native_null::Timestamp_or_zero_datetime_native_null on EXECUTE +# +SET time_zone='+00:00'; +SET timestamp=1000000000; +PREPARE s FROM 'SELECT CONCAT (UNIX_TIMESTAMP(?))'; +EXECUTE s USING CAST('::' AS INET6); +CONCAT (UNIX_TIMESTAMP(?)) +999993600 +EXECUTE s USING NULL; +CONCAT (UNIX_TIMESTAMP(?)) +NULL +DEALLOCATE PREPARE s; +SET timestamp=DEFAULT; +SET time_zone=DEFAULT; +# End of 10.5 tests diff --git a/plugin/type_inet/mysql-test/type_inet/type_inet6_ps.test b/plugin/type_inet/mysql-test/type_inet/type_inet6_ps.test new file mode 100644 index 00000000000..4251e820e17 --- /dev/null +++ b/plugin/type_inet/mysql-test/type_inet/type_inet6_ps.test @@ -0,0 +1,16 @@ +--echo # Start of 10.5 tests + +--echo # +--echo # MDEV-35427 Assertion `is_null() >= item->null_value' failed in Timestamp_or_zero_datetime_native_null::Timestamp_or_zero_datetime_native_null on EXECUTE +--echo # + +SET time_zone='+00:00'; +SET timestamp=1000000000; +PREPARE s FROM 'SELECT CONCAT (UNIX_TIMESTAMP(?))'; +EXECUTE s USING CAST('::' AS INET6); +EXECUTE s USING NULL; +DEALLOCATE PREPARE s; +SET timestamp=DEFAULT; +SET time_zone=DEFAULT; + +--echo # End of 10.5 tests diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 522f2a82faf..6b0ff438b91 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4711,7 +4711,10 @@ int ha_partition::update_row(const uchar *old_data, const uchar *new_data) Notice that HA_READ_BEFORE_WRITE_REMOVAL does not require this protocol, so this is not supported for this engine. */ - error= get_part_for_buf(old_data, m_rec0, m_part_info, &old_part_id); + { + Abort_on_warning_instant_set old_abort_on_warning(thd, 0); + error= get_part_for_buf(old_data, m_rec0, m_part_info, &old_part_id); + } DBUG_ASSERT(!error); DBUG_ASSERT(old_part_id == m_last_part); DBUG_ASSERT(bitmap_is_set(&(m_part_info->read_partitions), old_part_id)); diff --git a/sql/handler.h b/sql/handler.h index 9a542a08102..72213b8cc7d 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3133,12 +3133,19 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); bitmap with first N+1 bits set (keypart_map for a key prefix of [0..N] keyparts) */ -#define make_keypart_map(N) (((key_part_map)2 << (N)) - 1) +inline key_part_map make_keypart_map(uint N) +{ + return ((key_part_map)2 << (N)) - 1; +} + /* bitmap with first N bits set (keypart_map for a key prefix of [0..N-1] keyparts) */ -#define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1) +inline key_part_map make_prev_keypart_map(uint N) +{ + return ((key_part_map)1 << (N)) - 1; +} /** Base class to be used by handlers different shares */ diff --git a/sql/item.cc b/sql/item.cc index 9372f43d4ff..af20ae04e12 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4495,6 +4495,7 @@ bool Item_param::set_from_item(THD *thd, Item *item) if (item->null_value) { set_null(); + set_handler(&type_handler_null); DBUG_RETURN(false); } else @@ -4512,7 +4513,10 @@ bool Item_param::set_from_item(THD *thd, Item *item) DBUG_RETURN(set_value(thd, item, &tmp, h)); } else + { set_null(); + set_handler(&type_handler_null); + } DBUG_RETURN(0); } @@ -5032,7 +5036,7 @@ Item_param::set_param_type_and_swap_value(Item_param *src) } -void Item_param::set_default() +void Item_param::set_default(bool set_type_handler_null) { m_is_settable_routine_parameter= false; state= DEFAULT_VALUE; @@ -5045,13 +5049,17 @@ void Item_param::set_default() can misbehave (e.g. crash on asserts). */ null_value= true; + if (set_type_handler_null) + set_handler(&type_handler_null); } -void Item_param::set_ignore() +void Item_param::set_ignore(bool set_type_handler_null) { m_is_settable_routine_parameter= false; state= IGNORE_VALUE; null_value= true; + if (set_type_handler_null) + set_handler(&type_handler_null); } /** diff --git a/sql/item.h b/sql/item.h index 59212e5db68..9a51e017b21 100644 --- a/sql/item.h +++ b/sql/item.h @@ -4318,8 +4318,8 @@ public: int save_in_field(Field *field, bool no_conversions) override; - void set_default(); - void set_ignore(); + void set_default(bool set_type_handler_null); + void set_ignore(bool set_type_handler_null); void set_null(); void set_int(longlong i, uint32 max_length_arg); void set_double(double i); @@ -6955,7 +6955,7 @@ public: { // It should not be possible to have "EXECUTE .. USING DEFAULT(a)" DBUG_ASSERT(0); - param->set_default(); + param->set_default(true); return false; } table_map used_tables() const override; @@ -7084,7 +7084,7 @@ public: } bool save_in_param(THD *, Item_param *param) override { - param->set_default(); + param->set_default(true); return false; } Item *do_get_copy(THD *thd) const override @@ -7118,7 +7118,7 @@ public: } bool save_in_param(THD *, Item_param *param) override { - param->set_ignore(); + param->set_ignore(true); return false; } diff --git a/sql/item_create.h b/sql/item_create.h index 25a75a22163..166e173b3c2 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -304,7 +304,7 @@ class Native_functions_hash: public HASH public: Native_functions_hash() { - bzero(this, sizeof(*this)); + bzero((void*) this, sizeof(*this)); } ~Native_functions_hash() { diff --git a/sql/service_wsrep.cc b/sql/service_wsrep.cc index 0a26951b47e..d58a05b3eb5 100644 --- a/sql/service_wsrep.cc +++ b/sql/service_wsrep.cc @@ -187,39 +187,29 @@ extern "C" my_bool wsrep_thd_is_SR(const THD *thd) thd->wsrep_cs().transaction().state() == wsrep::transaction::s_executing; } -extern "C" void wsrep_handle_SR_rollback(THD *bf_thd, +extern "C" void wsrep_handle_SR_rollback(THD *bf_thd __attribute__((unused)), THD *victim_thd) { + /* + We should always be in victim_thd context, either client session is + rolling back or rollbacker thread should be in control. + */ DBUG_ASSERT(victim_thd); + DBUG_ASSERT(current_thd == victim_thd); DBUG_ASSERT(wsrep_thd_is_SR(victim_thd)); - if (!victim_thd || !wsrep_on(bf_thd)) return; - WSREP_DEBUG("handle rollback, for deadlock: thd %llu trx_id %" PRIu64 " frags %zu conf %s", + /* Defensive measure to avoid crash in production. */ + if (!victim_thd) return; + + WSREP_DEBUG("Handle SR rollback, for deadlock: thd %llu trx_id %" PRIu64 " frags %zu conf %s", victim_thd->thread_id, victim_thd->wsrep_trx_id(), victim_thd->wsrep_sr().fragments_certified(), wsrep_thd_transaction_state_str(victim_thd)); - /* Note: do not store/reset globals before wsrep_bf_abort() call - to avoid losing BF thd context. */ - if (!(bf_thd && bf_thd != victim_thd)) - { - DEBUG_SYNC(victim_thd, "wsrep_before_SR_rollback"); - } - mysql_mutex_lock(&victim_thd->LOCK_thd_data); - if (bf_thd) - { - wsrep_bf_abort(bf_thd, victim_thd); - } - else - { - wsrep_thd_self_abort(victim_thd); - } - mysql_mutex_unlock(&victim_thd->LOCK_thd_data); - if (bf_thd) - { - wsrep_store_threadvars(bf_thd); - } + DEBUG_SYNC(victim_thd, "wsrep_before_SR_rollback"); + + wsrep_thd_self_abort(victim_thd); } extern "C" my_bool wsrep_thd_bf_abort(THD *bf_thd, THD *victim_thd, diff --git a/sql/set_var.h b/sql/set_var.h index c8da3c1c169..416993e5c34 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -247,9 +247,11 @@ protected: Typically it's the same as session_value_ptr(), but it's different, for example, for ENUM, that is printed as a string, but stored as a number. */ + __attribute__((no_sanitize("undefined"))) uchar *session_var_ptr(THD *thd) const { return ((uchar*)&(thd->variables)) + offset; } + __attribute__((no_sanitize("undefined"))) uchar *global_var_ptr() const { return ((uchar*)&global_system_variables) + offset; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9c8969b289e..3fe63b885fd 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -908,10 +908,10 @@ static bool insert_bulk_params(Prepared_statement *stmt, param->set_null(); break; case STMT_INDICATOR_DEFAULT: - param->set_default(); + param->set_default(false); break; case STMT_INDICATOR_IGNORE: - param->set_ignore(); + param->set_ignore(false); break; default: DBUG_ASSERT(0); diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 8350b9dba9b..59a4679847b 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -462,7 +462,7 @@ get_server_from_table_to_cache(TABLE *table) RETURN VALUES 0 - no error - other - error code + other - ER_ error code */ static int @@ -546,15 +546,19 @@ insert_server_record_into_cache(FOREIGN_SERVER *server) advance of insertion into the mysql.servers table RETURN VALUE - VOID - + 0 - no errors + >0 - ER_ error code */ -static void +static int store_server_fields(TABLE *table, FOREIGN_SERVER *server) { table->use_all_columns(); + + if (table->s->fields < 9) + return ER_CANT_FIND_SYSTEM_REC; + /* "server" has already been prepped by prepare_server_struct_for_<> so, all we need to do is check if the value is set (> -1 for port) @@ -563,30 +567,43 @@ store_server_fields(TABLE *table, FOREIGN_SERVER *server) have changed will be set. If an insert, then all will be set, even if with empty strings */ - if (server->host) + if (server->host && table->field[1]->store(server->host, - (uint) strlen(server->host), system_charset_info); - if (server->db) + (uint) strlen(server->host), system_charset_info)) + goto err; + if (server->db && table->field[2]->store(server->db, - (uint) strlen(server->db), system_charset_info); - if (server->username) + (uint) strlen(server->db), system_charset_info)) + goto err; + if (server->username && table->field[3]->store(server->username, - (uint) strlen(server->username), system_charset_info); - if (server->password) + (uint) strlen(server->username), system_charset_info)) + goto err; + if (server->password && table->field[4]->store(server->password, - (uint) strlen(server->password), system_charset_info); - if (server->port > -1) - table->field[5]->store(server->port); - - if (server->socket) + (uint) strlen(server->password), system_charset_info)) + goto err; + if (server->port > -1 && + table->field[5]->store(server->port)) + goto err; + if (server->socket && table->field[6]->store(server->socket, - (uint) strlen(server->socket), system_charset_info); - if (server->scheme) + (uint) strlen(server->socket), system_charset_info)) + goto err; + if (server->scheme && table->field[7]->store(server->scheme, - (uint) strlen(server->scheme), system_charset_info); - if (server->owner) + (uint) strlen(server->scheme), system_charset_info)) + goto err; + if (server->owner && table->field[8]->store(server->owner, - (uint) strlen(server->owner), system_charset_info); + (uint) strlen(server->owner), system_charset_info)) + goto err; + return 0; + +err: + THD *thd= table->in_use; + DBUG_ASSERT(thd->is_error()); + return thd->get_stmt_da()->get_sql_errno(); } /* @@ -608,7 +625,7 @@ store_server_fields(TABLE *table, FOREIGN_SERVER *server) RETURN VALUE 0 - no errors - >0 - error code + >0 - ER_ error code */ @@ -642,7 +659,8 @@ int insert_server_record(TABLE *table, FOREIGN_SERVER *server) error= 1; } /* store each field to be inserted */ - store_server_fields(table, server); + if ((error= store_server_fields(table, server))) + DBUG_RETURN(error); DBUG_PRINT("info",("record for server '%s' not found!", server->server_name)); @@ -972,9 +990,15 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server) table->use_all_columns(); /* set the field that's the PK to the value we're looking for */ - table->field[0]->store(server->server_name, + if (table->field[0]->store(server->server_name, server->server_name_length, - system_charset_info); + system_charset_info)) + { + DBUG_ASSERT(0); /* Protected by servers_cache */ + THD *thd= table->in_use; + DBUG_ASSERT(thd->is_error()); + return thd->get_stmt_da()->get_sql_errno(); + } if (unlikely((error= table->file->ha_index_read_idx_map(table->record[0], 0, @@ -992,7 +1016,8 @@ update_server_record(TABLE *table, FOREIGN_SERVER *server) { /* ok, so we can update since the record exists in the table */ store_record(table,record[1]); - store_server_fields(table, server); + if ((error= store_server_fields(table, server))) + goto end; if (unlikely((error=table->file->ha_update_row(table->record[1], table->record[0])) && error != HA_ERR_RECORD_IS_THE_SAME)) diff --git a/storage/connect/mysql-test/connect/r/odbc_sqlite3.result b/storage/connect/mysql-test/connect/r/odbc_sqlite3.result index bce69227073..0a241305a62 100644 --- a/storage/connect/mysql-test/connect/r/odbc_sqlite3.result +++ b/storage/connect/mysql-test/connect/r/odbc_sqlite3.result @@ -2,14 +2,14 @@ Table Create Table t1 CREATE TABLE `t1` ( `Description` char(128) NOT NULL, `Attributes` varchar(256) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=latin1 `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers' +) ENGINE=CONNECT DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `TABLE_TYPE`='ODBC' `CATFUNC`='Drivers' SET NAMES utf8; CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=ODBC CONNECTION='Driver=SQLite3 ODBC Driver;Database=MTR_SUITE_DIR/std_data/test.sqlite3;NoWCHAR=yes' CHARSET=utf8 DATA_CHARSET=utf8;; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` varchar(64) DEFAULT NULL -) ENGINE=CONNECT DEFAULT CHARSET=utf8 CONNECTION='Driver=SQLite3 ODBC Driver;Database=MTR_SUITE_DIR/std_data/test.sqlite3;NoWCHAR=yes' `TABLE_TYPE`='ODBC' `DATA_CHARSET`='utf8' +) ENGINE=CONNECT DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci CONNECTION='Driver=SQLite3 ODBC Driver;Database=MTR_SUITE_DIR/std_data/test.sqlite3;NoWCHAR=yes' `TABLE_TYPE`='ODBC' `DATA_CHARSET`='utf8' SELECT * FROM t1; a test1 @@ -21,8 +21,8 @@ CREATE TABLE t2 AS SELECT * FROM t1; SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( - `a` varchar(64) CHARACTER SET utf8 DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1 + `a` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM t2; a test1 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_34659.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_34659.result index e77939396b0..e0f8b25d3c1 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_34659.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_34659.result @@ -16,6 +16,13 @@ SELECT * FROM t2 ORDER BY CAST(c AS INET6); c 456 123 +SELECT * FROM t2 GROUP BY CAST(c AS char(60)); +c +123 +456 +SELECT * FROM t2 GROUP BY CAST(c AS INET6); +c +456 DROP TABLE t1,t2; drop server srv; for master_1 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_35422.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_35422.result new file mode 100644 index 00000000000..1d19fe84cac --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_35422.result @@ -0,0 +1,24 @@ +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'); +create table t2 (c varchar(10)); +create table t1 (c varchar(10)) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +insert into t1 values ('abc'), ('abd'), ('abcd'), ('abc'); +SELECT DISTINCT c FROM t1; +c +abc +abd +abcd +SELECT DISTINCT c FROM t1 WHERE (c LIKE 'abc%'); +c +abc +abcd +drop table t1, t2; +drop server srv; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_34659.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_34659.test index 3b481d2277f..3b1dc206866 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_34659.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_34659.test @@ -13,6 +13,8 @@ CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT='WRAPPER "mysql",SRV "srv",TABLE " insert into t2 values (456), (123); SELECT * FROM t2 ORDER BY CAST(c AS char(60)); SELECT * FROM t2 ORDER BY CAST(c AS INET6); +SELECT * FROM t2 GROUP BY CAST(c AS char(60)); +SELECT * FROM t2 GROUP BY CAST(c AS INET6); # Cleanup DROP TABLE t1,t2; drop server srv; diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_35422.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_35422.test new file mode 100644 index 00000000000..dc89bc88edc --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_35422.test @@ -0,0 +1,21 @@ +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log +set spider_same_server_link= 1; +evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql +OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +create table t2 (c varchar(10)); +create table t1 (c varchar(10)) ENGINE=Spider +COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; +insert into t1 values ('abc'), ('abd'), ('abcd'), ('abc'); +SELECT DISTINCT c FROM t1; +SELECT DISTINCT c FROM t1 WHERE (c LIKE 'abc%'); +drop table t1, t2; +drop server srv; +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index f96648c69c7..ad76907c397 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -14140,6 +14140,11 @@ int spider_mbase_handler::append_group_by_part( DBUG_RETURN(error_num); } +/* + Append the GROUP BY part. + + Only used by the group by handler for query construction. +*/ int spider_mbase_handler::append_group_by( ORDER *order, spider_string *str, @@ -14158,6 +14163,13 @@ int spider_mbase_handler::append_group_by( str->q_append(SPIDER_SQL_GROUP_STR, SPIDER_SQL_GROUP_LEN); for (; order; order = order->next) { + /* + This is not expected to happen, as NULL check was performed + at the creation of the group by handler, and any NULL item_ptr + would have resulted in the gbh not being created. + */ + if (!order->item_ptr) + DBUG_RETURN(ER_INTERNAL_ERROR); if ((error_num = spider_db_print_item_type(order->item_ptr, NULL, spider, str, alias, alias_length, dbton_id, use_fields, fields))) { @@ -14197,6 +14209,11 @@ int spider_mbase_handler::append_order_by_part( DBUG_RETURN(error_num); } +/* + Append the ORDER BY part. + + Only used by the group by handler for query construction. +*/ int spider_mbase_handler::append_order_by( ORDER *order, spider_string *str, @@ -14215,6 +14232,13 @@ int spider_mbase_handler::append_order_by( str->q_append(SPIDER_SQL_ORDER_STR, SPIDER_SQL_ORDER_LEN); for (; order; order = order->next) { + /* + This is not expected to happen, as NULL check was performed + at the creation of the group by handler, and any NULL item_ptr + would have resulted in the gbh not being created. + */ + if (!order->item_ptr) + DBUG_RETURN(ER_INTERNAL_ERROR); if ((error_num = spider_db_print_item_type(order->item_ptr, NULL, spider, str, alias, alias_length, dbton_id, use_fields, fields))) { diff --git a/storage/spider/spd_group_by_handler.cc b/storage/spider/spd_group_by_handler.cc index 628e902f179..9145fdf885e 100644 --- a/storage/spider/spd_group_by_handler.cc +++ b/storage/spider/spd_group_by_handler.cc @@ -1622,8 +1622,10 @@ group_by_handler *spider_create_group_by_handler( { for (order = query->group_by; order; order = order->next) { - if (spider_db_print_item_type((*order->item), NULL, spider, NULL, NULL, 0, - roop_count, TRUE, fields_arg)) + if (order->item_ptr == NULL || + spider_db_print_item_type(order->item_ptr, NULL, spider, + NULL, NULL, 0, roop_count, TRUE, + fields_arg)) { DBUG_PRINT("info",("spider dbton_id=%d can't create group by", roop_count)); spider_clear_bit(dbton_bitmap, roop_count); @@ -1640,10 +1642,10 @@ group_by_handler *spider_create_group_by_handler( { for (order = query->order_by; order; order = order->next) { - if ((*order->item)->type() == Item::SUM_FUNC_ITEM) - continue; - if (spider_db_print_item_type((*order->item), NULL, spider, NULL, NULL, 0, - roop_count, TRUE, fields_arg)) + if (order->item_ptr == NULL || + spider_db_print_item_type(order->item_ptr, NULL, spider, + NULL, NULL, 0, roop_count, TRUE, + fields_arg)) { DBUG_PRINT("info",("spider dbton_id=%d can't create order by", roop_count)); spider_clear_bit(dbton_bitmap, roop_count);