MDEV-31475 Spider: only reset wide_handler when owning it

A wide_handler is shared among ha_spider of partitions of the same
spider table, where the last partition is designated the owner of the
wide_handler, and is responsible for its deallocation. Therefore in
case of failure, we only reset wide_handler in error handling if the
current ha_spider is the owner of the wide_handler, otherwise it will
result in segv in the destructor of ha_spider, or during
ha_spider::close().
This commit is contained in:
Yuchen Pei 2024-05-01 14:25:39 +10:00
parent 86adee3806
commit 698dae54ef
No known key found for this signature in database
GPG key ID: 3DD1B35105743563
5 changed files with 62 additions and 1 deletions

View file

@ -614,7 +614,8 @@ error_get_share:
owner->wide_handler = NULL;
owner->wide_handler_owner = FALSE;
}
wide_handler = NULL;
if (!wide_handler_owner)
wide_handler = NULL;
error_wide_handler_alloc:
DBUG_RETURN(error_num);
}

View file

@ -94,6 +94,7 @@ public:
#ifdef WITH_PARTITION_STORAGE_ENGINE
SPIDER_PARTITION_HANDLER *partition_handler;
#endif
/* Whether this ha_spider is the owner of its wide_handler. */
bool wide_handler_owner = FALSE;
SPIDER_WIDE_HANDLER *wide_handler = NULL;

View file

@ -0,0 +1,23 @@
for master_1
for child2
for child3
CREATE TABLE t3 (c1 MEDIUMINT NULL, c2 CHAR(5)) ENGINE=Spider PARTITION BY KEY(c1) PARTITIONS 2;
ALTER TABLE t3 DROP PRIMARY KEY;
ERROR 42000: Can't DROP INDEX `PRIMARY`; check that it exists
SELECT * FROM t3 WHERE c1 <=> '1000-00-01 00:00:00' ORDER BY c1,c2 LIMIT 2;
ERROR HY000: Unable to connect to foreign data source: localhost
CREATE TABLE t1 (a INT UNSIGNED NOT NULL PRIMARY KEY, b INT UNSIGNED NOT NULL, c INT UNSIGNED, UNIQUE (b, c) USING HASH) ENGINE=Spider;
SELECT t1.c1 FROM t3 RIGHT JOIN t1 ON t1.c1=current_date() UNION SELECT t1.c2 FROM t1 LEFT OUTER JOIN t3 ON t1.c2;
ERROR HY000: Unable to connect to foreign data source: localhost
drop table t1, t3;
set spider_same_server_link= 1;
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t1 (a INT, b VARCHAR(255), PRIMARY KEY(a)) ENGINE=Spider PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN (3), PARTITION p2 VALUES LESS THAN MAXVALUE COMMENT='srv "srv"');
DROP SERVER srv;
SELECT * FROM t1;
ERROR HY000: The foreign server name you are trying to reference does not exist. Data source error: srv
drop table t1;
for master_1
for child2
for child3

View file

@ -0,0 +1,32 @@
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
# test 1
CREATE TABLE t3 (c1 MEDIUMINT NULL, c2 CHAR(5)) ENGINE=Spider PARTITION BY KEY(c1) PARTITIONS 2;
--error ER_CANT_DROP_FIELD_OR_KEY
ALTER TABLE t3 DROP PRIMARY KEY;
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
SELECT * FROM t3 WHERE c1 <=> '1000-00-01 00:00:00' ORDER BY c1,c2 LIMIT 2;
CREATE TABLE t1 (a INT UNSIGNED NOT NULL PRIMARY KEY, b INT UNSIGNED NOT NULL, c INT UNSIGNED, UNIQUE (b, c) USING HASH) ENGINE=Spider;
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
SELECT t1.c1 FROM t3 RIGHT JOIN t1 ON t1.c1=current_date() UNION SELECT t1.c2 FROM t1 LEFT OUTER JOIN t3 ON t1.c2;
drop table t1, t3;
# test 2
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 t1 (a INT, b VARCHAR(255), PRIMARY KEY(a)) ENGINE=Spider PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN (3), PARTITION p2 VALUES LESS THAN MAXVALUE COMMENT='srv "srv"');
DROP SERVER srv;
--error 1477
SELECT * FROM t1;
drop table t1;
--disable_query_log
--disable_result_log
--source ../../t/test_deinit.inc
--enable_result_log
--enable_query_log

View file

@ -879,6 +879,10 @@ enum spider_hnd_stage {
SPD_HND_STAGE_CLEAR_TOP_TABLE_FIELDS
};
/*
A wide handler is shared among ha_spider of partitions of the same
table. It is owned by the last partition.
*/
typedef struct st_spider_wide_handler
{
spider_hnd_stage stage;