mirror of
https://github.com/MariaDB/server.git
synced 2025-01-28 17:54:16 +01:00
MDEV-28993 Spider: Push down CASE statement
This commit is contained in:
parent
99dc0f030f
commit
18b93d6eb0
5 changed files with 143 additions and 30 deletions
|
@ -66,9 +66,9 @@ id greeting
|
|||
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 t0.`id` `id`,t0.`greeting` `greeting` from `auto_test_remote`.`tbl_a` t0 where ((t0.`greeting` = 'Aloha!') and ((case t0.`greeting` when 'Aloha!' then _latin1'one' else _latin1'more' end) = _latin1'one'))
|
||||
select t0.`id` `id`,t0.`greeting` `greeting` from `auto_test_remote`.`tbl_b` t0 where ((t0.`greeting` = 'Aloha!') and ((case t0.`greeting` when 'Aloha!' then _latin1'one' else _latin1'more' end) = _latin1'one'))
|
||||
select t0.`id` `id`,t0.`greeting` `greeting` from `auto_test_remote`.`tbl_c` t0 where ((t0.`greeting` = 'Aloha!') and ((case t0.`greeting` when 'Aloha!' then _latin1'one' else _latin1'more' end) = _latin1'one'))
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %'
|
||||
connection child2_1;
|
||||
SET @@global.general_log = @general_log_backup;
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# MDEV-28993 Spider: Push down CASE statement
|
||||
#
|
||||
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 int);
|
||||
create table t1 (c int) ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t1 values (42), (3), (848), (100);
|
||||
explain select case c when 3 then "three" when 42 then "answer" else "other" end from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY
|
||||
select case c when 3 then "three" when 42 then "answer" else "other" end from t1;
|
||||
case c when 3 then "three" when 42 then "answer" else "other" end
|
||||
answer
|
||||
three
|
||||
other
|
||||
other
|
||||
explain select case c when 3 then "three" when 42 then "answer" end from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY
|
||||
select case c when 3 then "three" when 42 then "answer" end from t1;
|
||||
case c when 3 then "three" when 42 then "answer" end
|
||||
answer
|
||||
three
|
||||
NULL
|
||||
NULL
|
||||
explain select case when c = 3 then "three" when c = 42 then "answer" else "other" end from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY
|
||||
select case when c = 3 then "three" when c = 42 then "answer" else "other" end from t1;
|
||||
case when c = 3 then "three" when c = 42 then "answer" else "other" end
|
||||
answer
|
||||
three
|
||||
other
|
||||
other
|
||||
explain select case when c = 3 then "three" when c = 42 then "answer" end from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Storage engine handles GROUP BY
|
||||
select case when c = 3 then "three" when c = 42 then "answer" end from t1;
|
||||
case when c = 3 then "three" when c = 42 then "answer" end
|
||||
answer
|
||||
three
|
||||
NULL
|
||||
NULL
|
||||
drop table t1, t2;
|
||||
drop server srv;
|
||||
for master_1
|
||||
for child2
|
||||
for child3
|
||||
#
|
||||
# end of test pushdown_case
|
||||
#
|
|
@ -0,0 +1,50 @@
|
|||
--echo #
|
||||
--echo # MDEV-28993 Spider: Push down CASE statement
|
||||
--echo #
|
||||
--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 int);
|
||||
create table t1 (c int) ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t1 values (42), (3), (848), (100);
|
||||
|
||||
# everything
|
||||
let $query=
|
||||
select case c when 3 then "three" when 42 then "answer" else "other" end from t1;
|
||||
eval explain $query;
|
||||
eval $query;
|
||||
|
||||
# no else
|
||||
let $query=
|
||||
select case c when 3 then "three" when 42 then "answer" end from t1;
|
||||
eval explain $query;
|
||||
eval $query;
|
||||
|
||||
# no value
|
||||
let $query=
|
||||
select case when c = 3 then "three" when c = 42 then "answer" else "other" end from t1;
|
||||
eval explain $query;
|
||||
eval $query;
|
||||
|
||||
# neither
|
||||
let $query=
|
||||
select case when c = 3 then "three" when c = 42 then "answer" end from t1;
|
||||
eval explain $query;
|
||||
eval $query;
|
||||
|
||||
drop table t1, t2;
|
||||
drop server srv;
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../../t/test_deinit.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
--echo #
|
||||
--echo # end of test pushdown_case
|
||||
--echo #
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#define PLUGIN_VAR_CAN_MEMALLOC
|
||||
/*
|
||||
#define ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
|
||||
#define HASH_UPDATE_WITH_HASH_VALUE
|
||||
*/
|
||||
|
||||
|
@ -106,7 +105,6 @@ typedef st_spider_result SPIDER_RESULT;
|
|||
#define SPIDER_SQL_HS_LTEQUAL_STR "<="
|
||||
#define SPIDER_SQL_HS_LTEQUAL_LEN (sizeof(SPIDER_SQL_HS_LTEQUAL_STR) - 1)
|
||||
|
||||
#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
|
||||
#define SPIDER_SQL_CASE_STR "case "
|
||||
#define SPIDER_SQL_CASE_LEN (sizeof(SPIDER_SQL_CASE_STR) - 1)
|
||||
#define SPIDER_SQL_WHEN_STR " when "
|
||||
|
@ -117,7 +115,6 @@ typedef st_spider_result SPIDER_RESULT;
|
|||
#define SPIDER_SQL_ELSE_LEN (sizeof(SPIDER_SQL_ELSE_STR) - 1)
|
||||
#define SPIDER_SQL_END_STR " end"
|
||||
#define SPIDER_SQL_END_LEN (sizeof(SPIDER_SQL_END_STR) - 1)
|
||||
#endif
|
||||
|
||||
#define SPIDER_SQL_USING_STR " using "
|
||||
#define SPIDER_SQL_USING_LEN (sizeof(SPIDER_SQL_USING_STR) - 1)
|
||||
|
|
|
@ -5547,10 +5547,6 @@ int spider_db_mbase_util::check_item_func(
|
|||
switch (func_type)
|
||||
{
|
||||
case Item_func::TRIG_COND_FUNC:
|
||||
case Item_func::CASE_SEARCHED_FUNC:
|
||||
#ifndef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
|
||||
case Item_func::CASE_SIMPLE_FUNC:
|
||||
#endif
|
||||
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
|
||||
case Item_func::NOT_FUNC:
|
||||
/* Why the following check is necessary? */
|
||||
|
@ -5620,15 +5616,15 @@ int spider_db_mbase_util::print_item_func(
|
|||
Item *item, **item_list = item_func->arguments();
|
||||
Field *field;
|
||||
spider_string tmp_str;
|
||||
uint roop_count, item_count = item_func->argument_count(), start_item = 0;
|
||||
uint i, item_count = item_func->argument_count(), start_item = 0;
|
||||
const char *func_name = SPIDER_SQL_NULL_CHAR_STR,
|
||||
*separator_str = SPIDER_SQL_NULL_CHAR_STR,
|
||||
*last_str = SPIDER_SQL_NULL_CHAR_STR;
|
||||
int func_name_length = SPIDER_SQL_NULL_CHAR_LEN,
|
||||
separator_str_length = SPIDER_SQL_NULL_CHAR_LEN,
|
||||
last_str_length = SPIDER_SQL_NULL_CHAR_LEN;
|
||||
int use_pushdown_udf;
|
||||
bool merge_func = FALSE;
|
||||
int use_pushdown_udf, case_when_start, case_when_count;
|
||||
bool merge_func = FALSE, case_with_else;
|
||||
DBUG_ENTER("spider_db_mbase_util::print_item_func");
|
||||
DBUG_ASSERT(!check_item_func(item_func, spider, alias, alias_length,
|
||||
use_fields, fields));
|
||||
|
@ -6490,23 +6486,39 @@ int spider_db_mbase_util::print_item_func(
|
|||
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
|
||||
case Item_func::CASE_SEARCHED_FUNC:
|
||||
case Item_func::CASE_SIMPLE_FUNC:
|
||||
#ifdef ITEM_FUNC_CASE_PARAMS_ARE_PUBLIC
|
||||
Item_func_case *item_func_case = (Item_func_case *) item_func;
|
||||
/*
|
||||
Arrangement of arguments:
|
||||
- Item_func_case_searched:
|
||||
when1 when2 ... whenk then1 then2 .. thenk [else]
|
||||
- Item_func_case_simple:
|
||||
value when1 when2 ... whenk then1 then2 .. thenk [else]
|
||||
*/
|
||||
if (item_func->functype() == Item_func::CASE_SEARCHED_FUNC)
|
||||
{
|
||||
case_when_start= 0;
|
||||
case_when_count= item_count / 2;
|
||||
case_with_else= item_count % 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
case_when_start= 1;
|
||||
case_when_count= (item_count - 1) / 2;
|
||||
case_with_else= item_count % 2 == 0;
|
||||
}
|
||||
if (str)
|
||||
{
|
||||
if (str->reserve(SPIDER_SQL_CASE_LEN))
|
||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||
str->q_append(SPIDER_SQL_CASE_STR, SPIDER_SQL_CASE_LEN);
|
||||
}
|
||||
if (item_func_case->first_expr_num != -1)
|
||||
if (case_when_start > 0)
|
||||
{
|
||||
if ((error_num = spider_db_print_item_type(
|
||||
item_list[item_func_case->first_expr_num], NULL, spider, str,
|
||||
item_list[0], NULL, spider, str,
|
||||
alias, alias_length, dbton_id, use_fields, fields)))
|
||||
DBUG_RETURN(error_num);
|
||||
}
|
||||
for (roop_count = 0; roop_count < item_func_case->ncases;
|
||||
roop_count += 2)
|
||||
for (i = 0; i < (uint) case_when_count; i++)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
|
@ -6515,7 +6527,7 @@ int spider_db_mbase_util::print_item_func(
|
|||
str->q_append(SPIDER_SQL_WHEN_STR, SPIDER_SQL_WHEN_LEN);
|
||||
}
|
||||
if ((error_num = spider_db_print_item_type(
|
||||
item_list[roop_count], NULL, spider, str,
|
||||
item_list[i + case_when_start], NULL, spider, str,
|
||||
alias, alias_length, dbton_id, use_fields, fields)))
|
||||
DBUG_RETURN(error_num);
|
||||
if (str)
|
||||
|
@ -6525,11 +6537,11 @@ int spider_db_mbase_util::print_item_func(
|
|||
str->q_append(SPIDER_SQL_THEN_STR, SPIDER_SQL_THEN_LEN);
|
||||
}
|
||||
if ((error_num = spider_db_print_item_type(
|
||||
item_list[roop_count + 1], NULL, spider, str,
|
||||
item_list[i + case_when_start + case_when_count], NULL, spider, str,
|
||||
alias, alias_length, dbton_id, use_fields, fields)))
|
||||
DBUG_RETURN(error_num);
|
||||
}
|
||||
if (item_func_case->else_expr_num != -1)
|
||||
if (case_with_else)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
|
@ -6538,7 +6550,7 @@ int spider_db_mbase_util::print_item_func(
|
|||
str->q_append(SPIDER_SQL_ELSE_STR, SPIDER_SQL_ELSE_LEN);
|
||||
}
|
||||
if ((error_num = spider_db_print_item_type(
|
||||
item_list[item_func_case->else_expr_num], NULL, spider, str,
|
||||
item_list[item_count - 1], NULL, spider, str,
|
||||
alias, alias_length, dbton_id, use_fields, fields)))
|
||||
DBUG_RETURN(error_num);
|
||||
}
|
||||
|
@ -6551,9 +6563,6 @@ int spider_db_mbase_util::print_item_func(
|
|||
SPIDER_SQL_CLOSE_PAREN_LEN);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
#else
|
||||
DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM);
|
||||
#endif
|
||||
case Item_func::JSON_EXTRACT_FUNC:
|
||||
func_name = (char*) item_func->func_name();
|
||||
func_name_length = strlen(func_name);
|
||||
|
@ -6607,13 +6616,13 @@ int spider_db_mbase_util::print_item_func(
|
|||
Loop through the items of the current function expression to
|
||||
print its portion of the statement
|
||||
*/
|
||||
for (roop_count = start_item; roop_count < item_count; roop_count++)
|
||||
for (i = start_item; i < item_count; i++)
|
||||
{
|
||||
item = item_list[roop_count];
|
||||
item = item_list[i];
|
||||
if ((error_num = spider_db_print_item_type(item, field, spider, str,
|
||||
alias, alias_length, dbton_id, use_fields, fields)))
|
||||
DBUG_RETURN(error_num);
|
||||
if (roop_count == 1)
|
||||
if (i == 1)
|
||||
{
|
||||
/* Remaining operands need to be preceded by the separator */
|
||||
func_name = separator_str;
|
||||
|
@ -6627,7 +6636,7 @@ int spider_db_mbase_util::print_item_func(
|
|||
}
|
||||
|
||||
/* Print the last operand value */
|
||||
item = item_list[roop_count];
|
||||
item = item_list[i];
|
||||
if ((error_num = spider_db_print_item_type(item, field, spider, str,
|
||||
alias, alias_length, dbton_id, use_fields, fields)))
|
||||
DBUG_RETURN(error_num);
|
||||
|
|
Loading…
Add table
Reference in a new issue