Skip to content

Commit cf6d83e

Browse files
MDEV-24760 SELECT..CASE statement syntax error at Spider Engine table
The root cause of the bug is in `spider_db_mbase_util::open_item_func()`. The function handles an instance of the `Item_func` class based on its `Item_func::Functype`. The `Functype` of `CASE WHEN ... THEN` is `CASE_SEARCHED_FUNC`. However, the Spider SE doesn't recognize this `Functype` because `CASE_SEARCHED_FUNC` is newly added by 4de0d92. This results in the wrong handling of `CASE WHEN ... THEN`. The above also applies to `CASE_SIMPLE_FUNC`.
1 parent efa311a commit cf6d83e

File tree

4 files changed

+176
-79
lines changed

4 files changed

+176
-79
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#
2+
# MDEV-24760 SELECT..CASE statement syntax error at Spider Engine table
3+
#
4+
for master_1
5+
for child2
6+
child2_1
7+
child2_2
8+
child2_3
9+
for child3
10+
connection child2_1;
11+
CREATE DATABASE auto_test_remote;
12+
USE auto_test_remote;
13+
DROP TABLE IF EXISTS tbl_a;
14+
Warnings:
15+
Note 1051 Unknown table 'auto_test_remote.tbl_a'
16+
CREATE TABLE tbl_a (
17+
id int NOT NULL AUTO_INCREMENT,
18+
name varchar(255) DEFAULT NULL,
19+
PRIMARY KEY (id)
20+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
21+
INSERT INTO tbl_a (name) VALUES ('Alice'), ('Bob');
22+
connection master_1;
23+
CREATE DATABASE auto_test_local;
24+
USE auto_test_local;
25+
CREATE TABLE tbl_a (
26+
id int NOT NULL AUTO_INCREMENT,
27+
name varchar(255) DEFAULT NULL,
28+
PRIMARY KEY (id)
29+
) ENGINE=Spider DEFAULT CHARSET=utf8 COMMENT='table "tbl_a"'
30+
PARTITION BY HASH(id) (
31+
PARTITION pt1 COMMENT='srv "s_2_1"'
32+
);
33+
SELECT id, CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END FROM tbl_a;
34+
id CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END
35+
1 A
36+
2 B
37+
SELECT id, CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END FROM tbl_a;
38+
id CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END
39+
1 A
40+
2 B
41+
DROP DATABASE auto_test_local;
42+
connection child2_1;
43+
DROP DATABASE auto_test_remote;
44+
for master_1
45+
for child2
46+
child2_1
47+
child2_2
48+
child2_3
49+
for child3
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
!include include/default_mysqld.cnf
2+
!include ../my_1_1.cnf
3+
!include ../my_2_1.cnf
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--echo #
2+
--echo # MDEV-24760 SELECT..CASE statement syntax error at Spider Engine table
3+
--echo #
4+
5+
--disable_query_log
6+
--disable_result_log
7+
--source ../t/test_init.inc
8+
--enable_query_log
9+
--enable_result_log
10+
11+
--connection child2_1
12+
CREATE DATABASE auto_test_remote;
13+
USE auto_test_remote;
14+
15+
DROP TABLE IF EXISTS tbl_a;
16+
eval CREATE TABLE tbl_a (
17+
id int NOT NULL AUTO_INCREMENT,
18+
name varchar(255) DEFAULT NULL,
19+
PRIMARY KEY (id)
20+
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
21+
22+
INSERT INTO tbl_a (name) VALUES ('Alice'), ('Bob');
23+
24+
--connection master_1
25+
CREATE DATABASE auto_test_local;
26+
USE auto_test_local;
27+
28+
eval CREATE TABLE tbl_a (
29+
id int NOT NULL AUTO_INCREMENT,
30+
name varchar(255) DEFAULT NULL,
31+
PRIMARY KEY (id)
32+
) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a"'
33+
PARTITION BY HASH(id) (
34+
PARTITION pt1 COMMENT='srv "s_2_1"'
35+
);
36+
37+
SELECT id, CASE WHEN name='Alice' THEN "A" WHEN name='Bob' THEN "B" END FROM tbl_a;
38+
SELECT id, CASE name WHEN 'Alice' THEN "A" WHEN 'Bob' THEN "B" END FROM tbl_a;
39+
40+
DROP DATABASE auto_test_local;
41+
42+
--connection child2_1
43+
DROP DATABASE auto_test_remote;
44+
45+
--disable_query_log
46+
--disable_result_log
47+
--source ../t/test_deinit.inc
48+
--enable_query_log
49+
--enable_result_log

storage/spider/spd_db_mysql.cc

Lines changed: 75 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -4181,88 +4181,18 @@ int spider_db_mbase_util::open_item_func(
41814181
) {
41824182
/* no action */
41834183
break;
4184-
} else if (func_name_length == 4)
4185-
{
4186-
if (
4187-
!strncasecmp("rand", func_name, func_name_length) &&
4184+
} else if (func_name_length == 4 &&
4185+
!strncasecmp("rand", func_name, func_name_length) &&
41884186
#ifdef SPIDER_Item_args_arg_count_IS_PROTECTED
4189-
!item_func->argument_count()
4190-
#else
4191-
!item_func->arg_count
4192-
#endif
4193-
) {
4194-
if (str)
4195-
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
4196-
DBUG_RETURN(spider_db_open_item_int(item_func, NULL, spider, str,
4197-
alias, alias_length, dbton_id, use_fields, fields));
4198-
} else if (
4199-
!strncasecmp("case", func_name, func_name_length)
4200-
) {
4201-
#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
4202-
Item_func_case *item_func_case = (Item_func_case *) item_func;
4203-
if (str)
4204-
{
4205-
if (str->reserve(SPIDER_SQL_CASE_LEN))
4206-
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
4207-
str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN);
4208-
}
4209-
if (item_func_case->first_expr_num != -1)
4210-
{
4211-
if ((error_num = spider_db_print_item_type(
4212-
item_list[item_func_case->first_expr_num], NULL, spider, str,
4213-
alias, alias_length, dbton_id, use_fields, fields)))
4214-
DBUG_RETURN(error_num);
4215-
}
4216-
for (roop_count = 0; roop_count < item_func_case->ncases;
4217-
roop_count += 2)
4218-
{
4219-
if (str)
4220-
{
4221-
if (str->reserve(SPIDER_SQL_WHEN_LEN))
4222-
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
4223-
str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN);
4224-
}
4225-
if ((error_num = spider_db_print_item_type(
4226-
item_list[roop_count], NULL, spider, str,
4227-
alias, alias_length, dbton_id, use_fields, fields)))
4228-
DBUG_RETURN(error_num);
4229-
if (str)
4230-
{
4231-
if (str->reserve(SPIDER_SQL_THEN_LEN))
4232-
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
4233-
str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN);
4234-
}
4235-
if ((error_num = spider_db_print_item_type(
4236-
item_list[roop_count + 1], NULL, spider, str,
4237-
alias, alias_length, dbton_id, use_fields, fields)))
4238-
DBUG_RETURN(error_num);
4239-
}
4240-
if (item_func_case->else_expr_num != -1)
4241-
{
4242-
if (str)
4243-
{
4244-
if (str->reserve(SPIDER_SQL_ELSE_LEN))
4245-
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
4246-
str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN);
4247-
}
4248-
if ((error_num = spider_db_print_item_type(
4249-
item_list[item_func_case->else_expr_num], NULL, spider, str,
4250-
alias, alias_length, dbton_id, use_fields, fields)))
4251-
DBUG_RETURN(error_num);
4252-
}
4253-
if (str)
4254-
{
4255-
if (str->reserve(SPIDER_SQL_END_LEN + SPIDER_SQL_CLOSE_PAREN_LEN))
4256-
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
4257-
str->q_append(SPIDER_SQL_END_STR, SPIDER_SQL_END_LEN);
4258-
str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,
4259-
SPIDER_SQL_CLOSE_PAREN_LEN);
4260-
}
4261-
DBUG_RETURN(0);
4187+
!item_func->argument_count()
42624188
#else
4263-
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
4189+
!item_func->arg_count
42644190
#endif
4265-
}
4191+
) {
4192+
if (str)
4193+
str->length(str->length() - SPIDER_SQL_OPEN_PAREN_LEN);
4194+
DBUG_RETURN(spider_db_open_item_int(item_func, NULL, spider, str,
4195+
alias, alias_length, dbton_id, use_fields, fields));
42664196
} else if (func_name_length == 6 &&
42674197
!strncasecmp("istrue", func_name, func_name_length)
42684198
) {
@@ -5088,6 +5018,72 @@ int spider_db_mbase_util::open_item_func(
50885018
}
50895019
}
50905020
break;
5021+
case Item_func::CASE_SEARCHED_FUNC:
5022+
case Item_func::CASE_SIMPLE_FUNC:
5023+
#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
5024+
Item_func_case *item_func_case = (Item_func_case *) item_func;
5025+
if (str)
5026+
{
5027+
if (str->reserve(SPIDER_SQL_CASE_LEN))
5028+
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
5029+
str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN);
5030+
}
5031+
if (item_func_case->first_expr_num != -1)
5032+
{
5033+
if ((error_num = spider_db_print_item_type(
5034+
item_list[item_func_case->first_expr_num], NULL, spider, str,
5035+
alias, alias_length, dbton_id, use_fields, fields)))
5036+
DBUG_RETURN(error_num);
5037+
}
5038+
for (roop_count = 0; roop_count < item_func_case->ncases;
5039+
roop_count += 2)
5040+
{
5041+
if (str)
5042+
{
5043+
if (str->reserve(SPIDER_SQL_WHEN_LEN))
5044+
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
5045+
str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN);
5046+
}
5047+
if ((error_num = spider_db_print_item_type(
5048+
item_list[roop_count], NULL, spider, str,
5049+
alias, alias_length, dbton_id, use_fields, fields)))
5050+
DBUG_RETURN(error_num);
5051+
if (str)
5052+
{
5053+
if (str->reserve(SPIDER_SQL_THEN_LEN))
5054+
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
5055+
str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN);
5056+
}
5057+
if ((error_num = spider_db_print_item_type(
5058+
item_list[roop_count + 1], NULL, spider, str,
5059+
alias, alias_length, dbton_id, use_fields, fields)))
5060+
DBUG_RETURN(error_num);
5061+
}
5062+
if (item_func_case->else_expr_num != -1)
5063+
{
5064+
if (str)
5065+
{
5066+
if (str->reserve(SPIDER_SQL_ELSE_LEN))
5067+
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
5068+
str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN);
5069+
}
5070+
if ((error_num = spider_db_print_item_type(
5071+
item_list[item_func_case->else_expr_num], NULL, spider, str,
5072+
alias, alias_length, dbton_id, use_fields, fields)))
5073+
DBUG_RETURN(error_num);
5074+
}
5075+
if (str)
5076+
{
5077+
if (str->reserve(SPIDER_SQL_END_LEN + SPIDER_SQL_CLOSE_PAREN_LEN))
5078+
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
5079+
str->q_append(SPIDER_SQL_END_STR, SPIDER_SQL_END_LEN);
5080+
str->q_append(SPIDER_SQL_CLOSE_PAREN_STR,
5081+
SPIDER_SQL_CLOSE_PAREN_LEN);
5082+
}
5083+
DBUG_RETURN(0);
5084+
#else
5085+
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
5086+
#endif
50915087
default:
50925088
THD *thd = spider->trx->thd;
50935089
SPIDER_SHARE *share = spider->share;

0 commit comments

Comments
 (0)