MDEV-29447 MDEV-26285 MDEV-31338 Refactor spider_db_mbase_util::open_item_func

spider_db_mbase_util::open_item_func() is a monster function.
It is difficult to maintain while it is expected that we need to
modify it when a new SQL function or a new func_type is added.

We split the function into two distinct functions: one handles the
case of str != NULL and the other handles the case of str == NULL.

This refactoring was done in a conservative way because we do not
have comprehensive tests on the function.

It also fixes MDEV-29447 and MDEV-31338 where field items that are
arguments of a func item may be used before created / initialised.

Note this commit is adapted from a patch by Nayuta for MDEV-26285.
This commit is contained in:
Yuchen Pei 2023-01-03 16:24:04 +11:00 committed by Yuchen Pei
parent b37357eb46
commit 423c28f0aa
No known key found for this signature in database
GPG key ID: 3DD1B35105743563
7 changed files with 645 additions and 562 deletions

View file

@ -0,0 +1,33 @@
#
# MDEV-29447 SIGSEGV in spider_db_open_item_field and SIGSEGV spider_db_print_item_type, on SELECT
#
for master_1
for child2
child2_1
child2_2
child2_3
for child3
connection child2_1;
CREATE DATABASE auto_test_remote;
USE auto_test_remote;
CREATE TABLE tbl_a (
a INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
connection master_1;
CREATE DATABASE auto_test_local;
USE auto_test_local;
CREATE TABLE tbl_a (
a INT
) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a", srv "s_2_1"';
SELECT TRIM(LEADING 'c' FROM a) FROM tbl_a;
TRIM(LEADING 'c' FROM a)
connection child2_1;
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

View file

@ -0,0 +1,15 @@
#
# MDEV-31338 UBSAN: runtime error: member access within null pointer of type 'struct SPIDER_FIELD_CHAIN' and SIGSEGV in spider_db_open_item_ident on SELECT
#
for master_1
for child2
for child3
CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (c BLOB) ENGINE=InnoDB;
CREATE TABLE ts (c BLOB) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
SELECT TRIM(BOTH ' ' FROM c) FROM ts ORDER BY c;
TRIM(BOTH ' ' FROM c)
drop table t, ts;
for master_1
for child2
for child3

View file

@ -0,0 +1,3 @@
!include include/default_mysqld.cnf
!include ../my_1_1.cnf
!include ../my_2_1.cnf

View file

@ -0,0 +1,37 @@
--echo #
--echo # MDEV-29447 SIGSEGV in spider_db_open_item_field and SIGSEGV spider_db_print_item_type, on SELECT
--echo #
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
--connection child2_1
CREATE DATABASE auto_test_remote;
USE auto_test_remote;
eval CREATE TABLE tbl_a (
a INT
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
--connection master_1
CREATE DATABASE auto_test_local;
USE auto_test_local;
eval CREATE TABLE tbl_a (
a INT
) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"';
SELECT TRIM(LEADING 'c' FROM a) FROM tbl_a;
--connection child2_1
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_query_log
--enable_result_log

View file

@ -0,0 +1,22 @@
--echo #
--echo # MDEV-31338 UBSAN: runtime error: member access within null pointer of type 'struct SPIDER_FIELD_CHAIN' and SIGSEGV in spider_db_open_item_ident on SELECT
--echo #
--source include/have_innodb.inc
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
evalp CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
CREATE TABLE t (c BLOB) ENGINE=InnoDB;
CREATE TABLE ts (c BLOB) ENGINE=Spider COMMENT='WRAPPER "mysql",srv "srv",TABLE "t"';
SELECT TRIM(BOTH ' ' FROM c) FROM ts ORDER BY c;
drop table t, ts;
--disable_query_log
--disable_result_log
--source ../../t/test_deinit.inc
--enable_result_log
--enable_query_log

File diff suppressed because it is too large Load diff

View file

@ -122,6 +122,25 @@ public:
bool use_fields,
spider_fields *fields
) override;
protected:
int check_item_func(
Item_func *item_func,
ha_spider *spider,
const char *alias,
uint alias_length,
bool use_fields,
spider_fields *fields
);
int print_item_func(
Item_func *item_func,
ha_spider *spider,
spider_string *str,
const char *alias,
uint alias_length,
bool use_fields,
spider_fields *fields
);
public:
#ifdef HANDLER_HAS_DIRECT_AGGREGATE
int open_item_sum_func(
Item_sum *item_sum,