From c487eeed10d2a34d19141c5c3a98fbb38dd26f51 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 31 Aug 2022 15:24:06 +1000 Subject: [PATCH 1/6] MDEV-28592 disks plugin (postfix - remove tabs) --- plugin/disks/information_schema_disks.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc index bba5c850415..414af59098f 100644 --- a/plugin/disks/information_schema_disks.cc +++ b/plugin/disks/information_schema_disks.cc @@ -106,7 +106,7 @@ static int disks_table_add_row_stat( #else if (info.f_flags & MNT_RDONLY) #endif - return 0; + return 0; pTable->field[0]->store(zDisk, strlen(zDisk), system_charset_info); pTable->field[1]->store(zPath, strlen(zPath), system_charset_info); @@ -212,15 +212,15 @@ static int disks_fill_table(THD* pThd, TABLE_LIST* pTables, Item* pCond) ) { struct stat f; - const char *path, *point; + const char *path, *point; #ifdef HAVE_SETMNTENT - path= pEnt->mnt_dir; - point= pEnt->mnt_fsname; + path= pEnt->mnt_dir; + point= pEnt->mnt_fsname; #else - path= pEnt->mnt_mountp; - point= pEnt->mnt_special; + path= pEnt->mnt_mountp; + point= pEnt->mnt_special; #endif - // Try to keep to real storage by excluding + // Try to keep to real storage by excluding // read only mounts, and mount points that aren't directories if (hasmntopt(pEnt, MNTOPT_RO) != NULL) continue; From 4f2dc716ee95492f58c86e7ee615de55e7ae30f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 31 Aug 2022 15:58:52 +0300 Subject: [PATCH 2/6] MDEV-13668 fixup: Remove test work-arounds --- mysql-test/suite/innodb/r/innodb-index-online.result | 5 ++--- mysql-test/suite/innodb/t/innodb-index-online.test | 10 ++-------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-index-online.result b/mysql-test/suite/innodb/r/innodb-index-online.result index a0227d31393..4fd64b5c48a 100644 --- a/mysql-test/suite/innodb/r/innodb-index-online.result +++ b/mysql-test/suite/innodb/r/innodb-index-online.result @@ -231,7 +231,7 @@ WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted'); connection con1; SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2e_created WAIT_FOR dml2_done'; SET lock_wait_timeout = 10; -ALTER TABLE t1 DROP INDEX c2d, ADD INDEX c2e(c2), +ALTER TABLE t1 CHANGE c2 c22 INT, DROP INDEX c2d, ADD INDEX c2e(c22), ALGORITHM = INPLACE; connection default; INSERT INTO t1 SELECT 80 + c1, c2, c3 FROM t1; @@ -353,7 +353,7 @@ SET @rowlog_decrypt_1= WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted'); connection con1; SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2f_created WAIT_FOR dml3_done'; -ALTER TABLE t1 ADD INDEX c2f(c2); +ALTER TABLE t1 ADD INDEX c2f(c22f), CHANGE c2 c22f INT; connection default; SET DEBUG_SYNC = 'now WAIT_FOR c2f_created'; SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl'; @@ -392,7 +392,6 @@ SET DEBUG_SYNC = 'now SIGNAL dml3_done'; connection con1; Warnings: Note 1831 Duplicate index `c2f`. This is deprecated and will be disallowed in a future release -ALTER TABLE t1 CHANGE c2 c22f INT; SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl'; name count ddl_background_drop_indexes 0 diff --git a/mysql-test/suite/innodb/t/innodb-index-online.test b/mysql-test/suite/innodb/t/innodb-index-online.test index 4cdbdb7c584..d0f477cd0ef 100644 --- a/mysql-test/suite/innodb/t/innodb-index-online.test +++ b/mysql-test/suite/innodb/t/innodb-index-online.test @@ -225,9 +225,7 @@ SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2e_created WAIT_FOR dml2_done'; # Ensure that the ALTER TABLE will be executed even with some concurrent DML. SET lock_wait_timeout = 10; --send -# FIXME: MDEV-13668 -#ALTER TABLE t1 CHANGE c2 c22 INT, DROP INDEX c2d, ADD INDEX c2e(c22), -ALTER TABLE t1 DROP INDEX c2d, ADD INDEX c2e(c2), +ALTER TABLE t1 CHANGE c2 c22 INT, DROP INDEX c2d, ADD INDEX c2e(c22), ALGORITHM = INPLACE; # Generate some log (delete-mark, delete-unmark, insert etc.) @@ -321,9 +319,7 @@ connection con1; # Accumulate and apply some modification log. SET DEBUG_SYNC = 'row_log_apply_before SIGNAL c2f_created WAIT_FOR dml3_done'; --send -# FIXME: MDEV-13668 -#ALTER TABLE t1 ADD INDEX c2f(c22f), CHANGE c2 c22f INT; -ALTER TABLE t1 ADD INDEX c2f(c2); +ALTER TABLE t1 ADD INDEX c2f(c22f), CHANGE c2 c22f INT; connection default; SET DEBUG_SYNC = 'now WAIT_FOR c2f_created'; @@ -348,8 +344,6 @@ SET DEBUG_SYNC = 'now SIGNAL dml3_done'; connection con1; reap; -# FIXME: MDEV-13668 -ALTER TABLE t1 CHANGE c2 c22f INT; eval $innodb_metrics_select; From e4cffc92c783b0d0be35fa2e696ed517b381f81f Mon Sep 17 00:00:00 2001 From: Nayuta Yanagisawa Date: Thu, 30 Jun 2022 01:58:57 +0900 Subject: [PATCH 3/6] MDEV-27172 Prefix indices on Spider tables may lead to wrong query results Spider converts HA_READ_KEY_EXACT to the equality (=) in the function spider_db_append_key_where_internal() but the conversion is not necessarily correct for tables with prefix indices. We fix the bug by converting HA_READ_KEY_EXACT to 'LIKE "foo%"' when a target key is a prefix key. The fix is partly inspired by FEDERATED. See ha_federated::create_where_from_key() for more details. --- .../spider/bugfix/r/mdev_27172.result | 84 +++++++ .../mysql-test/spider/bugfix/t/mdev_27172.cnf | 3 + .../spider/bugfix/t/mdev_27172.test | 92 +++++++ storage/spider/spd_db_conn.cc | 230 +++++++++--------- storage/spider/spd_db_include.h | 15 +- storage/spider/spd_db_mysql.cc | 151 +++--------- storage/spider/spd_db_mysql.h | 10 +- 7 files changed, 334 insertions(+), 251 deletions(-) create mode 100644 storage/spider/mysql-test/spider/bugfix/r/mdev_27172.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27172.cnf create mode 100644 storage/spider/mysql-test/spider/bugfix/t/mdev_27172.test diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27172.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27172.result new file mode 100644 index 00000000000..d4c8c7e8ec2 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27172.result @@ -0,0 +1,84 @@ +# +# MDEV-27172 Prefix indices on Spider tables may lead to wrong query results +# +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 +connection child2_1; +SET @general_log_backup = @@global.general_log; +SET @log_output_backup = @@global.log_output; +SET @@global.general_log = 1; +SET @@global.log_output = "TABLE"; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a ( +id int NOT NULL, +greeting VARCHAR(255), +KEY(greeting) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE tbl_b ( +id int NOT NULL, +greeting VARCHAR(255), +KEY k (greeting(5)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE tbl_c ( +id int NOT NULL, +greeting TEXT, +KEY k (greeting(5)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +TRUNCATE TABLE mysql.general_log; +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +CREATE TABLE tbl_a ( +id int NOT NULL, +greeting VARCHAR(255), +KEY k (greeting) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"'; +INSERT INTO tbl_a VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!"); +SELECT * FROM tbl_a WHERE greeting = "Aloha!" + AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; +id greeting +2 Aloha! +CREATE TABLE tbl_b ( +id int NOT NULL, +greeting VARCHAR(255), +KEY k (greeting(5)) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_b", srv "s_2_1"'; +INSERT INTO tbl_b VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!"); +SELECT * FROM tbl_b WHERE greeting = "Aloha!" + AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; +id greeting +2 Aloha! +CREATE TABLE tbl_c ( +id int NOT NULL, +greeting TEXT, +KEY k (greeting(5)) +) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_c", srv "s_2_1"'; +INSERT INTO tbl_c VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!"); +SELECT * FROM tbl_c WHERE greeting = "Aloha!" + AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; +id greeting +2 Aloha! +connection child2_1; +SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %'; +argument +select `id`,`greeting` from `auto_test_remote`.`tbl_a` where `greeting` = 'Aloha!' and ((`greeting` = 'Aloha!')) +select `id`,`greeting` from `auto_test_remote`.`tbl_b` where `greeting` like 'Aloha%' and ((`greeting` = 'Aloha!')) +select `id`,`greeting` from `auto_test_remote`.`tbl_c` where `greeting` like 'Aloha%' and ((`greeting` = 'Aloha!')) +SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %' +connection child2_1; +SET @@global.general_log = @general_log_backup; +SET @@global.log_output = @log_output_backup; +DROP DATABASE auto_test_remote; +connection master_1; +DROP DATABASE auto_test_local; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.test new file mode 100644 index 00000000000..d544a0b400e --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27172.test @@ -0,0 +1,92 @@ +--echo # +--echo # MDEV-27172 Prefix indices on Spider tables may lead to wrong query results +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection child2_1 +SET @general_log_backup = @@global.general_log; +SET @log_output_backup = @@global.log_output; +SET @@global.general_log = 1; +SET @@global.log_output = "TABLE"; + +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +eval CREATE TABLE tbl_a ( + id int NOT NULL, + greeting VARCHAR(255), + KEY(greeting) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +eval CREATE TABLE tbl_b ( + id int NOT NULL, + greeting VARCHAR(255), + KEY k (greeting(5)) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +eval CREATE TABLE tbl_c ( + id int NOT NULL, + greeting TEXT, + KEY k (greeting(5)) +) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; + +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +CREATE DATABASE auto_test_local; +USE auto_test_local; + +# = (equality) +eval CREATE TABLE tbl_a ( + id int NOT NULL, + greeting VARCHAR(255), + KEY k (greeting) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"'; + +INSERT INTO tbl_a VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!"); +SELECT * FROM tbl_a WHERE greeting = "Aloha!" + AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; # hack to disable GBH + +# LIKE +eval CREATE TABLE tbl_b ( + id int NOT NULL, + greeting VARCHAR(255), + KEY k (greeting(5)) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_b", srv "s_2_1"'; + +INSERT INTO tbl_b VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!"); +SELECT * FROM tbl_b WHERE greeting = "Aloha!" + AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; # hack to disable GBH + +# LIKE +eval CREATE TABLE tbl_c ( + id int NOT NULL, + greeting TEXT, + KEY k (greeting(5)) +) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_c", srv "s_2_1"'; + +INSERT INTO tbl_c VALUES (1, "Hi!"),(2, "Aloha!"),(3, "Aloha!!!"); +SELECT * FROM tbl_c WHERE greeting = "Aloha!" + AND CASE greeting WHEN "Aloha!" THEN "one" ELSE 'more' END = "one"; # hack to disable GBH + +--connection child2_1 +SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %'; + +--connection child2_1 +SET @@global.general_log = @general_log_backup; +SET @@global.log_output = @log_output_backup; +DROP DATABASE auto_test_remote; + +--connection master_1 +DROP DATABASE auto_test_local; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 1aafa175a7b..5a8c7492654 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -1824,9 +1824,8 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } else if (sql_kind == SPIDER_SQL_KIND_HANDLER) { @@ -1836,16 +1835,15 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) { - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } @@ -1870,14 +1868,24 @@ int spider_db_append_key_where_internal( if (sql_kind == SPIDER_SQL_KIND_SQL) { if (str->reserve(store_length + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + - SPIDER_SQL_EQUAL_LEN)) + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); + dbton_share->append_column_name(str, field->field_index); - str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + + bool is_like= MY_TEST(key_part->key_part_flag & HA_PART_KEY_SEG); + if (is_like) + { + if (str->append(SPIDER_SQL_LIKE_STR, SPIDER_SQL_LIKE_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + else + { + if (str->append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + } + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, is_like, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } else if (sql_kind == SPIDER_SQL_KIND_HANDLER) { @@ -1887,9 +1895,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -1900,9 +1908,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); } - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } @@ -1935,9 +1943,8 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); str->q_append(op_str, op_len); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_both) start_key_part_map = 0; @@ -1954,9 +1961,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_GT_STR, SPIDER_SQL_GT_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -1967,9 +1974,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_GT_STR, SPIDER_SQL_GT_LEN); } - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } @@ -2003,9 +2010,8 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); str->q_append(op_str, op_len); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_both) start_key_part_map = 0; @@ -2022,9 +2028,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -2035,9 +2041,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); } - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } @@ -2070,9 +2076,8 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (!set_order) { @@ -2088,9 +2093,9 @@ int spider_db_append_key_where_internal( dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -2102,9 +2107,9 @@ int spider_db_append_key_where_internal( str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); } - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } @@ -2126,13 +2131,11 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_MBR_CONTAIN_STR, SPIDER_SQL_MBR_CONTAIN_LEN); - if ( - spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + SPIDER_SQL_CLOSE_PAREN_LEN) - ) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + + SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); dbton_share->append_column_name(str, field->field_index); @@ -2144,13 +2147,11 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_MBR_INTERSECT_STR, SPIDER_SQL_MBR_INTERSECT_LEN); - if ( - spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + SPIDER_SQL_CLOSE_PAREN_LEN) - ) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + + SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); dbton_share->append_column_name(str, field->field_index); @@ -2162,13 +2163,11 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_MBR_WITHIN_STR, SPIDER_SQL_MBR_WITHIN_LEN); - if ( - spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + SPIDER_SQL_CLOSE_PAREN_LEN) - ) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + + SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); dbton_share->append_column_name(str, field->field_index); @@ -2180,13 +2179,11 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_MBR_DISJOINT_STR, SPIDER_SQL_MBR_DISJOINT_LEN); - if ( - spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + SPIDER_SQL_CLOSE_PAREN_LEN) - ) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + + SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); dbton_share->append_column_name(str, field->field_index); @@ -2197,13 +2194,11 @@ int spider_db_append_key_where_internal( if (str->reserve(SPIDER_SQL_MBR_EQUAL_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_MBR_EQUAL_STR, SPIDER_SQL_MBR_EQUAL_LEN); - if ( - spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + - /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + SPIDER_SQL_CLOSE_PAREN_LEN) - ) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_COMMA_LEN + key_name_length + + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 + + SPIDER_SQL_CLOSE_PAREN_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); dbton_share->append_column_name(str, field->field_index); @@ -2219,9 +2214,8 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); str->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (!set_order) { @@ -2237,9 +2231,9 @@ int spider_db_append_key_where_internal( dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == start_key) @@ -2251,9 +2245,9 @@ int spider_db_append_key_where_internal( str->q_append(SPIDER_SQL_GTEQUAL_STR, SPIDER_SQL_GTEQUAL_LEN); } - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } @@ -2328,9 +2322,8 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } else { if (str_part2->reserve(store_length + key_name_length + @@ -2339,9 +2332,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == end_key) @@ -2354,10 +2347,9 @@ int spider_db_append_key_where_internal( str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); } */ - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, share->access_charset)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } } else { @@ -2381,9 +2373,8 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); str->q_append(op_str, op_len); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_both) end_key_part_map = 0; @@ -2399,9 +2390,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == end_key) @@ -2412,9 +2403,9 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); str->q_append(SPIDER_SQL_LT_STR, SPIDER_SQL_LT_LEN); } - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } @@ -2428,9 +2419,8 @@ int spider_db_append_key_where_internal( DBUG_RETURN(HA_ERR_OUT_OF_MEM); dbton_share->append_column_name(str, field->field_index); str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (!set_order) { @@ -2445,9 +2435,9 @@ int spider_db_append_key_where_internal( dbton_share->append_column_name(str_part2, field->field_index); str_part2->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part2, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part2, field, ptr, false, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (use_key == end_key) @@ -2459,9 +2449,9 @@ int spider_db_append_key_where_internal( str->q_append(SPIDER_SQL_LTEQUAL_STR, SPIDER_SQL_LTEQUAL_LEN); } - if (spider_dbton[dbton_id].db_util-> - append_column_value(spider, str_part, field, ptr, - share->access_charset)) + if (spider_dbton[dbton_id].db_util->append_column_value( + spider, str_part, field, ptr, FALSE, + share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } } diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index d51770c1a77..823f0a9c9fc 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -94,6 +94,8 @@ typedef st_spider_result SPIDER_RESULT; #define SPIDER_SQL_DOT_STR "." #define SPIDER_SQL_DOT_LEN (sizeof(SPIDER_SQL_DOT_STR) - 1) +#define SPIDER_SQL_PERCENT_STR "%" +#define SPIDER_SQL_PERCENT_LEN (sizeof(SPIDER_SQL_PERCENT_STR) - 1) #define SPIDER_SQL_EQUAL_STR " = " #define SPIDER_SQL_EQUAL_LEN (sizeof(SPIDER_SQL_EQUAL_STR) - 1) @@ -161,6 +163,8 @@ typedef st_spider_result SPIDER_RESULT; #define SPIDER_SQL_IN_LEN (sizeof(SPIDER_SQL_IN_STR) - 1) #define SPIDER_SQL_NOT_IN_STR "not in(" #define SPIDER_SQL_NOT_IN_LEN (sizeof(SPIDER_SQL_NOT_IN_STR) - 1) +#define SPIDER_SQL_LIKE_STR " like " +#define SPIDER_SQL_LIKE_LEN (sizeof(SPIDER_SQL_LIKE_STR) - 1) #define SPIDER_SQL_NOT_LIKE_STR "not like" #define SPIDER_SQL_NOT_LIKE_LEN (sizeof(SPIDER_SQL_NOT_LIKE_STR) - 1) #define SPIDER_SQL_AS_CHAR_STR " as char" @@ -818,13 +822,10 @@ public: virtual int append_escaped_name_quote( spider_string *str ) = 0; - virtual int append_column_value( - ha_spider *spider, - spider_string *str, - Field *field, - const uchar *new_ptr, - CHARSET_INFO *access_charset - ) = 0; + virtual int append_column_value(ha_spider *spider, spider_string *str, + Field *field, const uchar *new_ptr, + bool is_like, + CHARSET_INFO *access_charset)= 0; virtual int append_trx_isolation( spider_string *str, int trx_isolation diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 4a210a3c67d..5f6107e66a0 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -3680,13 +3680,12 @@ int spider_db_mbase_util::append_escaped_name_quote( DBUG_RETURN(0); } -int spider_db_mbase_util::append_column_value( - ha_spider *spider, - spider_string *str, - Field *field, - const uchar *new_ptr, - CHARSET_INFO *access_charset -) { +int spider_db_mbase_util::append_column_value(ha_spider *spider, + spider_string *str, Field *field, + const uchar *new_ptr, + bool is_like, + CHARSET_INFO *access_charset) +{ char buf[MAX_FIELD_WIDTH]; spider_string tmp_str(buf, MAX_FIELD_WIDTH, &my_charset_bin); String *ptr; @@ -3710,70 +3709,15 @@ int spider_db_mbase_util::append_column_value( ptr = tmp_str.get_str(); } else if (field->type() == MYSQL_TYPE_GEOMETRY) { -/* - uint mlength = SIZEOF_STORED_DOUBLE, lcnt; - uchar *dest = (uchar *) buf; - const uchar *source; - for (lcnt = 0; lcnt < 4; lcnt++) - { - mlength = SIZEOF_STORED_DOUBLE; - source = new_ptr + mlength + SIZEOF_STORED_DOUBLE * lcnt; - while (mlength--) - *dest++ = *--source; - } - tmp_str.length(SIZEOF_STORED_DOUBLE * lcnt); -*/ #ifndef DBUG_OFF double xmin, xmax, ymin, ymax; -/* - float8store(buf,xmin); - float8store(buf+8,xmax); - float8store(buf+16,ymin); - float8store(buf+24,ymax); - memcpy(&xmin,new_ptr,sizeof(xmin)); - memcpy(&xmax,new_ptr + 8,sizeof(xmax)); - memcpy(&ymin,new_ptr + 16,sizeof(ymin)); - memcpy(&ymax,new_ptr + 24,sizeof(ymax)); - float8get(xmin, buf); - float8get(xmax, buf + 8); - float8get(ymin, buf + 16); - float8get(ymax, buf + 24); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); - DBUG_PRINT("info", ("spider geo is %.14g %.14g %.14g %.14g", - xmin, xmax, ymin, ymax)); -*/ float8get(xmin, new_ptr); float8get(xmax, new_ptr + 8); float8get(ymin, new_ptr + 16); float8get(ymax, new_ptr + 24); DBUG_PRINT("info", ("spider geo is %f %f %f %f", xmin, xmax, ymin, ymax)); -/* - float8get(xmin, new_ptr + SIZEOF_STORED_DOUBLE * 4); - float8get(xmax, new_ptr + SIZEOF_STORED_DOUBLE * 5); - float8get(ymin, new_ptr + SIZEOF_STORED_DOUBLE * 6); - float8get(ymax, new_ptr + SIZEOF_STORED_DOUBLE * 7); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); - float8get(xmin, new_ptr + SIZEOF_STORED_DOUBLE * 8); - float8get(xmax, new_ptr + SIZEOF_STORED_DOUBLE * 9); - float8get(ymin, new_ptr + SIZEOF_STORED_DOUBLE * 10); - float8get(ymax, new_ptr + SIZEOF_STORED_DOUBLE * 11); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); - float8get(xmin, new_ptr + SIZEOF_STORED_DOUBLE * 12); - float8get(xmax, new_ptr + SIZEOF_STORED_DOUBLE * 13); - float8get(ymin, new_ptr + SIZEOF_STORED_DOUBLE * 14); - float8get(ymax, new_ptr + SIZEOF_STORED_DOUBLE * 15); - DBUG_PRINT("info", ("spider geo is %f %f %f %f", - xmin, xmax, ymin, ymax)); -*/ #endif -/* - tmp_str.set_quick((char *) new_ptr, SIZEOF_STORED_DOUBLE * 4, - &my_charset_bin); -*/ tmp_str.length(0); tmp_str.q_append((char *) SPIDER_SQL_LINESTRING_HEAD_STR, SPIDER_SQL_LINESTRING_HEAD_LEN); @@ -3798,27 +3742,7 @@ int spider_db_mbase_util::append_column_value( DBUG_PRINT("info", ("spider field->type() is %d", field->type())); DBUG_PRINT("info", ("spider ptr->length() is %d", ptr->length())); -/* - if ( - field->type() == MYSQL_TYPE_BIT || - (field->type() >= MYSQL_TYPE_TINY_BLOB && - field->type() <= MYSQL_TYPE_BLOB) - ) { - uchar *hex_ptr = (uchar *) ptr->ptr(), *end_ptr; - char *str_ptr; - DBUG_PRINT("info", ("spider HEX")); - if (str->reserve(SPIDER_SQL_HEX_LEN + ptr->length() * 2)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - str->q_append(SPIDER_SQL_HEX_STR, SPIDER_SQL_HEX_LEN); - str_ptr = (char *) str->ptr() + str->length(); - for (end_ptr = hex_ptr + ptr->length(); hex_ptr < end_ptr; hex_ptr++) - { - *str_ptr++ = spider_dig_upper[(*hex_ptr) >> 4]; - *str_ptr++ = spider_dig_upper[(*hex_ptr) & 0x0F]; - } - str->length(str->length() + ptr->length() * 2); - } else -*/ + if (field->result_type() == STRING_RESULT) { DBUG_PRINT("info", ("spider STRING_RESULT")); @@ -3841,6 +3765,10 @@ int spider_db_mbase_util::append_column_value( append_escaped_util(str, tmp_str2.get_str()) ) DBUG_RETURN(HA_ERR_OUT_OF_MEM); + + if (is_like && + str->append(SPIDER_SQL_PERCENT_STR, SPIDER_SQL_PERCENT_LEN)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); } else if (str->append(*ptr)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); if (str->reserve(SPIDER_SQL_VALUE_QUOTE_LEN)) @@ -3855,6 +3783,7 @@ int spider_db_mbase_util::append_column_value( str->q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN); } else if (str->append(*ptr)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); + DBUG_RETURN(0); } @@ -7881,12 +7810,10 @@ int spider_mbase_handler::append_insert_for_recovery( DBUG_RETURN(HA_ERR_OUT_OF_MEM); insert_sql->q_append(SPIDER_SQL_NULL_STR, SPIDER_SQL_NULL_LEN); } else { - if ( - spider_db_mbase_utility-> - append_column_value(spider, insert_sql, *field, NULL, - share->access_charset) || - insert_sql->reserve(SPIDER_SQL_COMMA_LEN) - ) + if (spider_db_mysql_utility.append_column_value(spider, insert_sql, + *field, NULL, false, + share->access_charset) || + insert_sql->reserve(SPIDER_SQL_COMMA_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } insert_sql->q_append(SPIDER_SQL_COMMA_STR, SPIDER_SQL_COMMA_LEN); @@ -8275,12 +8202,10 @@ int spider_mbase_handler::append_update_set( #ifndef DBUG_OFF MY_BITMAP *tmp_map = dbug_tmp_use_all_columns(table, &table->read_set); #endif - if ( - spider_db_mbase_utility-> - append_column_value(spider, str, *fields, NULL, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN) - ) { + if (spider_db_mysql_utility.append_column_value( + spider, str, *fields, NULL, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_COMMA_LEN)) + { #ifndef DBUG_OFF dbug_tmp_restore_column_map(&table->read_set, tmp_map); #endif @@ -9079,8 +9004,8 @@ int spider_mbase_handler::append_key_column_values( if (error_num > 0) DBUG_RETURN(error_num); } else { - if (spider_db_mbase_utility->append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_db_mysql_utility.append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } @@ -9160,8 +9085,8 @@ int spider_mbase_handler::append_key_column_values_with_name( if (error_num > 0) DBUG_RETURN(error_num); } else { - if (spider_db_mbase_utility->append_column_value(spider, str, field, ptr, - share->access_charset)) + if (spider_db_mysql_utility.append_column_value( + spider, str, field, ptr, FALSE, share->access_charset)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); } @@ -9533,12 +9458,9 @@ int spider_mbase_handler::append_update_where( mysql_share->append_column_name(str, (*field)->field_index); str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); (*field)->move_field_offset(ptr_diff); - if ( - spider_db_mbase_utility-> - append_column_value(spider, str, *field, NULL, - share->access_charset) || - str->reserve(SPIDER_SQL_AND_LEN) - ) + if (spider_db_mbase_utility->append_column_value( + spider, str, *field, NULL, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_AND_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); (*field)->move_field_offset(-ptr_diff); } @@ -9573,12 +9495,9 @@ int spider_mbase_handler::append_update_where( mysql_share->append_column_name(str, (*field)->field_index); str->q_append(SPIDER_SQL_EQUAL_STR, SPIDER_SQL_EQUAL_LEN); (*field)->move_field_offset(ptr_diff); - if ( - spider_db_mbase_utility-> - append_column_value(spider, str, *field, NULL, - share->access_charset) || - str->reserve(SPIDER_SQL_AND_LEN) - ) + if (spider_db_mysql_utility.append_column_value( + spider, str, *field, NULL, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_AND_LEN)) DBUG_RETURN(HA_ERR_OUT_OF_MEM); (*field)->move_field_offset(-ptr_diff); } @@ -11009,12 +10928,10 @@ int spider_mbase_handler::append_insert_values( } str->q_append(SPIDER_SQL_NULL_STR, SPIDER_SQL_NULL_LEN); } else { - if ( - spider_db_mbase_utility-> - append_column_value(spider, str, *field, NULL, - share->access_charset) || - str->reserve(SPIDER_SQL_COMMA_LEN) - ) { + if (spider_db_mysql_utility.append_column_value( + spider, str, *field, NULL, FALSE, share->access_charset) || + str->reserve(SPIDER_SQL_COMMA_LEN)) + { #ifndef DBUG_OFF dbug_tmp_restore_column_map(&table->read_set, tmp_map); #endif diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index d50bb0d1f9d..4d5327b7533 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -35,13 +35,9 @@ public: int append_escaped_name_quote( spider_string *str ); - int append_column_value( - ha_spider *spider, - spider_string *str, - Field *field, - const uchar *new_ptr, - CHARSET_INFO *access_charset - ); + int append_column_value(ha_spider *spider, spider_string *str, Field *field, + const uchar *new_ptr, bool is_like, + CHARSET_INFO *access_charset); int append_from_with_alias( spider_string *str, const char **table_names, From 47812017c67f1cba46cbc9dceee4c613a00dfd94 Mon Sep 17 00:00:00 2001 From: Brandon Nesterenko Date: Tue, 10 May 2022 14:25:35 -0600 Subject: [PATCH 4/6] MDEV-28530: Revoking privileges from a non-existing user on a master breaks replication on the slave in the presence of replication filters Problem: ======== Replication can break while applying a query log event if its respective command errors on the primary, but is ignored by the replication filter within Grant_tables on the replica. The bug reported by MDEV-28530 shows this with REVOKE ALL PRIVILEGES using a non-existent user. The primary will binlog the REVOKE command with an error code, and the replica will think the command executed with success because the replication filter will ignore the command while accessing the Grant_tables classes. When the replica performs an error check, it sees the difference between the error codes, and replication breaks. Solution: ======== If the replication filter check done by Grant_tables logic ignores the tables, reset thd->slave_expected_error to 0 so that Query_log_event::do_apply_event() can be made aware that the underlying query was ignored when it compares errors. Note that this bug also effects DROP USER if not all users exist in the provided list, and the patch fixes and tests this case. Reviewed By: ============ andrei.elkin@mariadb.com --- .../r/rpl_filter_revoke_missing_user.result | 39 ++++++++ .../rpl/t/rpl_filter_revoke_missing_user.test | 92 +++++++++++++++++++ sql/log_event.cc | 7 ++ sql/sql_acl.cc | 3 + sql/sql_class.h | 2 + 5 files changed, 143 insertions(+) create mode 100644 mysql-test/suite/rpl/r/rpl_filter_revoke_missing_user.result create mode 100644 mysql-test/suite/rpl/t/rpl_filter_revoke_missing_user.test diff --git a/mysql-test/suite/rpl/r/rpl_filter_revoke_missing_user.result b/mysql-test/suite/rpl/r/rpl_filter_revoke_missing_user.result new file mode 100644 index 00000000000..efd73d88964 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_filter_revoke_missing_user.result @@ -0,0 +1,39 @@ +include/master-slave.inc +[connection master] +# +# Set replica to ignore system tables +connection slave; +include/stop_slave.inc +SET @@GLOBAL.replicate_wild_ignore_table="mysql.%"; +include/start_slave.inc +# +# Trying to execute REVOKE ALL PRIVILEGES on a non-existent user and +# DROP USER on a list of users where not all users exist should error +# and be written into the binary log +connection master; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'nonexistentuser'@'%'; +ERROR HY000: Can't revoke all privileges for one or more of the requested users +CREATE USER 'testuser'@'localhost' IDENTIFIED by ''; +DROP USER 'testuser'@'localhost', 'nonexistentuser'@'%'; +ERROR HY000: Operation DROP USER failed for 'nonexistentuser'@'%' +# +# Ensure the events exist in the primary's binary log +FLUSH BINARY LOGS; +# MYSQL_BINLOG MYSQLD_DATADIR/binlog_file > MYSQL_TMP_DIR/mysqlbinlog_out.sql +# There should be three Query events: REVOKE, CREATE USER, and DROP USER +FOUND 3 /Query/ in mysqlbinlog_out.sql +FOUND 1 /REVOKE ALL PRIVILEGES/ in mysqlbinlog_out.sql +FOUND 1 /CREATE USER/ in mysqlbinlog_out.sql +FOUND 1 /DROP USER/ in mysqlbinlog_out.sql +# +# Ensure that the replica receives the event without error +connection slave; +Last_SQL_Error = +Last_SQL_Errno = 0 +# +# Clean up +connection slave; +include/stop_slave.inc +SET @@GLOBAL.replicate_wild_ignore_table=""; +include/start_slave.inc +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_filter_revoke_missing_user.test b/mysql-test/suite/rpl/t/rpl_filter_revoke_missing_user.test new file mode 100644 index 00000000000..ca2c18d36e1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_filter_revoke_missing_user.test @@ -0,0 +1,92 @@ +# +# Purpose: +# This test ensures that a binlogged Query_log_event which failed on the +# primary server does not break replication if it is ignored by Grant_tables +# on the replica. The bug reported by MDEV-28530 shows this with +# REVOKE ALL PRIVILEGES.. using a non-existent user. The primary will binlog +# the REVOKE command with an error code, and the replica will think the command +# executed with success because the replication filter will ignore the command +# while accessing the Grant_tables classes. When the replica performs an error +# check, it sees the difference between the error codes, and replication +# breaks. +# +# Methodology: +# Using a replica configured with replicate_wild_ignore_table="schema.%", +# on the primary, execute REVOKE ALL PRVILEGES using a non-existent user and +# DROP USER using a list of users where not all users exist, and ensure that +# the replica acknowledges and ignores the events without erroring. +# +# References: +# MDEV-28530: Revoking privileges from a non-existing user on a master breaks +# replication on the slave in the presence of replication filters +# + +source include/master-slave.inc; +source include/have_binlog_format_statement.inc; + +--echo # +--echo # Set replica to ignore system tables +connection slave; +let $old_filter= query_get_value(SHOW SLAVE STATUS, Replicate_Wild_Ignore_Table, 1); +source include/stop_slave.inc; +SET @@GLOBAL.replicate_wild_ignore_table="mysql.%"; +source include/start_slave.inc; + + +--echo # +--echo # Trying to execute REVOKE ALL PRIVILEGES on a non-existent user and +--echo # DROP USER on a list of users where not all users exist should error +--echo # and be written into the binary log +--connection master + +--error 1269 +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'nonexistentuser'@'%'; + +CREATE USER 'testuser'@'localhost' IDENTIFIED by ''; +--error 1396 +DROP USER 'testuser'@'localhost', 'nonexistentuser'@'%'; +--save_master_pos + + +--echo # +--echo # Ensure the events exist in the primary's binary log +--let $MYSQLD_DATADIR= `select @@datadir` +--let $binlog_file=query_get_value(SHOW MASTER STATUS, File, 1) +FLUSH BINARY LOGS; +--echo # MYSQL_BINLOG MYSQLD_DATADIR/binlog_file > MYSQL_TMP_DIR/mysqlbinlog_out.sql +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQL_TMP_DIR/mysqlbinlog_out.sql + +--echo # There should be three Query events: REVOKE, CREATE USER, and DROP USER +--let SEARCH_FILE= $MYSQL_TMP_DIR/mysqlbinlog_out.sql + +--let SEARCH_PATTERN= Query +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= REVOKE ALL PRIVILEGES +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= CREATE USER +--source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN= DROP USER +--source include/search_pattern_in_file.inc + + +--echo # +--echo # Ensure that the replica receives the event without error +connection slave; +--sync_with_master +let $error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +--echo Last_SQL_Error = $error +let $errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +--echo Last_SQL_Errno = $errno + + +--echo # +--echo # Clean up +--connection slave +source include/stop_slave.inc; +--eval SET @@GLOBAL.replicate_wild_ignore_table="$old_filter" +source include/start_slave.inc; + +--source include/rpl_end.inc diff --git a/sql/log_event.cc b/sql/log_event.cc index 3639b7a5d00..a5a31d57ed2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5703,6 +5703,13 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, thd->update_server_status(); log_slow_statement(thd); thd->lex->restore_set_statement_var(); + + /* + When THD::slave_expected_error gets reset inside execution stack + that is the case of to be ignored event. In this case the expected + error must change to the reset value as well. + */ + expected_error= thd->slave_expected_error; } thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 930c107cde2..eae180837ae 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1300,7 +1300,10 @@ class Grant_tables Rpl_filter *rpl_filter= thd->system_thread_info.rpl_sql_info->rpl_filter; if (rpl_filter->is_on() && !rpl_filter->tables_ok(0, &first_table_in_list->tl)) + { + thd->slave_expected_error= 0; DBUG_RETURN(1); + } } DBUG_RETURN(0); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 05b8f7eb443..d3e2b72b12d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3209,6 +3209,8 @@ public: /* In case of a slave, set to the error code the master got when executing the query. 0 if no error on the master. + The stored into variable master error code may get reset inside + execution stack when the event turns out to be ignored. */ int slave_expected_error; enum_sql_command last_sql_command; // Last sql_command exceuted in mysql_execute_command() From f501f815bc78fc743a9ccb8bd9f0bb6e888abf4f Mon Sep 17 00:00:00 2001 From: Andrei Date: Fri, 26 Aug 2022 18:35:15 +0300 Subject: [PATCH 5/6] MDEV-28827 Minor unsafe statement warning message improvement The replication unsafe warning's pattern gets corrected in the punctuation part. --- sql/share/errmsg-utf8.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 97520facefe..aff9874edc2 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6469,7 +6469,7 @@ ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS eng "Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction" ER_MESSAGE_AND_STATEMENT - eng "%s Statement: %s" + eng "%s. Statement: %s" ER_SLAVE_CONVERSION_FAILED eng "Column %d of table '%-.192s.%-.192s' cannot be converted from type '%-.50s' to type '%-.50s'" From ac49b7a845f5b5de30d1266879a4c584f9d7c914 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 29 Aug 2022 22:54:25 +0530 Subject: [PATCH 6/6] MDEV-29342 Assertion failure in file que0que.cc line 728 - During shutdown, InnoDB fts fails to update synced doc id when there is only one doc id about to sync. While starting the server, InnoDB fetches the already synced doc id from config table. In the subsequent sync operation, InnoDB fails with DB_DUPLICATE_KEY error. --- mysql-test/suite/innodb_fts/r/misc_debug2.result | 13 +++++++++++++ mysql-test/suite/innodb_fts/t/misc_debug2.test | 15 +++++++++++++++ storage/innobase/fts/fts0fts.cc | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb_fts/r/misc_debug2.result b/mysql-test/suite/innodb_fts/r/misc_debug2.result index b3bc12f92cc..583d43bd9db 100644 --- a/mysql-test/suite/innodb_fts/r/misc_debug2.result +++ b/mysql-test/suite/innodb_fts/r/misc_debug2.result @@ -5,3 +5,16 @@ set debug_dbug="+d,fts_instrument_sync_request"; INSERT INTO mdev21563 VALUES('This is a test'); ALTER TABLE mdev21563 DISCARD TABLESPACE; DROP TABLE mdev21563; +# +# MDEV-29342 Assertion failure in file que0que.cc line 728 +# +CREATE TABLE t1(f1 CHAR(100), FULLTEXT idx(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES('mysql'), ('innodb'); +set debug_dbug="+d,fts_instrument_sync_debug"; +INSERT INTO t1 VALUES('test'); +set debug_dbug="-d,fts_instrument_sync_debug"; +INSERT INTO t1 VALUES('This is a fts issue'); +set debug_dbug="+d,fts_instrument_sync_debug"; +UPDATE t1 SET f1="mariadb"; +set debug_dbug="-d,fts_instrument_sync_debug"; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb_fts/t/misc_debug2.test b/mysql-test/suite/innodb_fts/t/misc_debug2.test index 0a9e137dd80..1ba77f2481e 100644 --- a/mysql-test/suite/innodb_fts/t/misc_debug2.test +++ b/mysql-test/suite/innodb_fts/t/misc_debug2.test @@ -10,3 +10,18 @@ INSERT INTO mdev21563 VALUES('This is a test'); ALTER TABLE mdev21563 DISCARD TABLESPACE; --source include/restart_mysqld.inc DROP TABLE mdev21563; + +--echo # +--echo # MDEV-29342 Assertion failure in file que0que.cc line 728 +--echo # +CREATE TABLE t1(f1 CHAR(100), FULLTEXT idx(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES('mysql'), ('innodb'); +set debug_dbug="+d,fts_instrument_sync_debug"; +INSERT INTO t1 VALUES('test'); +set debug_dbug="-d,fts_instrument_sync_debug"; +INSERT INTO t1 VALUES('This is a fts issue'); +--source include/restart_mysqld.inc +set debug_dbug="+d,fts_instrument_sync_debug"; +UPDATE t1 SET f1="mariadb"; +set debug_dbug="-d,fts_instrument_sync_debug"; +DROP TABLE t1; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 6ac41ac1f03..b16bb6611b0 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -2667,7 +2667,7 @@ retry: } mutex_exit(&cache->doc_id_lock); - if (cmp_doc_id > *doc_id) { + if (cmp_doc_id && cmp_doc_id >= *doc_id) { error = fts_update_sync_doc_id( table, cache->synced_doc_id, trx); }