Commit e8257c06 authored by Sergei Petrunia's avatar Sergei Petrunia

MDEV-31975: UCASE(varchar_col)=... not handled for partition tables

Enable sargable casefolding rewrite when the column is a part of
partitioning expression.
parent b1b7cfe1
set
@tmp_switch_sarg_casefold=@@optimizer_switch,
optimizer_switch='sargable_casefold=on';
create table t1 (
s1 varchar(15) collate utf8mb3_bin,
s2 varchar(15) collate utf8mb3_general_ci
) partition by key (s2) partitions 4;
insert into t1 values ('aa','aa'),('bb','bb');
explain format=json select * from t1 where upper(s2)='AA';
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "t1",
"partitions": ["p2"],
"access_type": "system",
"rows": 1,
"filtered": 100
}
}
}
explain format=json delete from t1 where upper(s2)='AA';
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"delete": 1,
"table_name": "t1",
"partitions": ["p2"],
"access_type": "ALL",
"rows": 1,
"attached_condition": "t1.s2 = 'AA'"
}
}
}
explain format=json update t1 set s1='aaa' where upper(s2)='AA';
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"update": 1,
"table_name": "t1",
"partitions": ["p2"],
"access_type": "ALL",
"rows": 1,
"attached_condition": "t1.s2 = 'AA'"
}
}
}
drop table t1;
set optimizer_switch=@tmp_switch_sarg_casefold;
--source include/have_partition.inc
#
# MDEV-31975: UCASE(varchar_col)=... not handled for partition tables
#
set
@tmp_switch_sarg_casefold=@@optimizer_switch,
optimizer_switch='sargable_casefold=on';
create table t1 (
s1 varchar(15) collate utf8mb3_bin,
s2 varchar(15) collate utf8mb3_general_ci
) partition by key (s2) partitions 4;
insert into t1 values ('aa','aa'),('bb','bb');
explain format=json select * from t1 where upper(s2)='AA';
explain format=json delete from t1 where upper(s2)='AA';
explain format=json update t1 set s1='aaa' where upper(s2)='AA';
drop table t1;
set optimizer_switch=@tmp_switch_sarg_casefold;
...@@ -5,13 +5,15 @@ ...@@ -5,13 +5,15 @@
#include "mariadb.h" #include "mariadb.h"
#include "sql_priv.h" #include "sql_priv.h"
#include <m_ctype.h> #include <m_ctype.h>
#include "sql_partition.h"
#include "sql_select.h" #include "sql_select.h"
#include "opt_trace.h" #include "opt_trace.h"
/* /*
@brief @brief
Check if passed item is "UCASE(table.key_part_col)" Check if passed item is "UCASE(table.colX)" where colX is either covered
by some index or is a part of partition expression.
@return @return
Argument of the UCASE if passed item matches Argument of the UCASE if passed item matches
...@@ -27,18 +29,30 @@ static Item* is_upper_key_col(Item *item) ...@@ -27,18 +29,30 @@ static Item* is_upper_key_col(Item *item)
Item *arg_real= arg->real_item(); Item *arg_real= arg->real_item();
if (arg_real->type() == Item::FIELD_ITEM) if (arg_real->type() == Item::FIELD_ITEM)
{ {
Item_field *item_field= (Item_field*)arg_real; if (dynamic_cast<const Type_handler_longstr*>(arg_real->type_handler()))
if ((item_field->field->flags & PART_KEY_FLAG) &&
dynamic_cast<const Type_handler_longstr*>(arg_real->type_handler()))
{ {
/* Field *field= ((Item_field*)arg_real)->field;
Make sure COERCIBILITY(UPPER(col))=COERCIBILITY(col) bool appl= (field->flags & PART_KEY_FLAG);
*/
DBUG_ASSERT(arg->collation.derivation == #ifdef WITH_PARTITION_STORAGE_ENGINE
item_func->collation.derivation); partition_info *part_info;
if (!appl && ((part_info= field->table->part_info)))
/* Return arg, not arg_real. Do not walk into Item_ref objects */ {
return arg; appl= bitmap_is_set(&part_info->full_part_field_set,
field->field_index);
}
#endif
if (appl)
{
/*
Make sure COERCIBILITY(UPPER(col))=COERCIBILITY(col)
*/
DBUG_ASSERT(arg->collation.derivation ==
item_func->collation.derivation);
/* Return arg, not arg_real. Do not walk into Item_ref objects */
return arg;
}
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment