From 25db55f14a2a3f8bca07f1ad2a2cba61a50c3c81 Mon Sep 17 00:00:00 2001 From: lijiachen Date: Thu, 14 Nov 2024 18:01:52 +0800 Subject: [PATCH] cond push --- .../suite/ctc/r/ctc_cond_pushdown.result | 131 ++++++++++++++++++ mysql-test/suite/ctc/t/ctc_cond_pushdown.test | 79 ++++++++++- storage/ctc/ctc_srv.h | 16 +++ storage/ctc/ctc_util.cc | 50 +++++-- storage/ctc/ctc_util.h | 10 +- storage/ctc/ha_ctc.cc | 113 ++++++++++++--- 6 files changed, 363 insertions(+), 36 deletions(-) diff --git a/mysql-test/suite/ctc/r/ctc_cond_pushdown.result b/mysql-test/suite/ctc/r/ctc_cond_pushdown.result index 22397f7..5183250 100644 --- a/mysql-test/suite/ctc/r/ctc_cond_pushdown.result +++ b/mysql-test/suite/ctc/r/ctc_cond_pushdown.result @@ -663,6 +663,137 @@ a,d a,d a,d drop table if exists myset; +drop table if exists t1; +CREATE TABLE t1(c1 tinyint, c2 tinyint not null, c3 tinyint signed, c4 tinyint unsigned, c5 int, c6 long, c7 bigint); +INSERT INTO t1 VALUES (1,1,1,1,1,1,1), (2,2,2,2,2,2,2); +INSERT INTO t1 VALUES (null, 5, null, null, null, null, null); +INSERT INTO t1 VALUES (3,3,3,3,3,3,3), (4,4,4,4,4,4,4); +INSERT INTO t1 VALUES (null, 7, null, null, null, null, null); +INSERT INTO t1 VALUES (8,8,127,255,8,8,8); +select * from t1; +c1 c2 c3 c4 c5 c6 c7 +1 1 1 1 1 1 1 +2 2 2 2 2 2 2 +NULL 5 NULL NULL NULL NULL NULL +3 3 3 3 3 3 3 +4 4 4 4 4 4 4 +NULL 7 NULL NULL NULL NULL NULL +8 8 127 255 8 8 8 +select * from t1 where c1 % 2 = 0; +c1 c2 c3 c4 c5 c6 c7 +2 2 2 2 2 2 2 +4 4 4 4 4 4 4 +8 8 127 255 8 8 8 +select * from t1 where c2 % 2 = 0; +c1 c2 c3 c4 c5 c6 c7 +2 2 2 2 2 2 2 +4 4 4 4 4 4 4 +8 8 127 255 8 8 8 +select * from t1 where c3 % 2 = 0; +c1 c2 c3 c4 c5 c6 c7 +2 2 2 2 2 2 2 +4 4 4 4 4 4 4 +select * from t1 where c4 % 2 = 0; +c1 c2 c3 c4 c5 c6 c7 +2 2 2 2 2 2 2 +4 4 4 4 4 4 4 +select * from t1 where c5 % 2 = 0; +c1 c2 c3 c4 c5 c6 c7 +2 2 2 2 2 2 2 +4 4 4 4 4 4 4 +8 8 127 255 8 8 8 +select * from t1 where c6 % 2 = 0; +c1 c2 c3 c4 c5 c6 c7 +2 2 2 2 2 2 2 +4 4 4 4 4 4 4 +8 8 127 255 8 8 8 +select * from t1 where c7 % 2 = 0; +c1 c2 c3 c4 c5 c6 c7 +2 2 2 2 2 2 2 +4 4 4 4 4 4 4 +8 8 127 255 8 8 8 +select * from t1 where c1 / 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c2 / 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c3 / 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c4 / 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c5 / 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c6 / 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +2 2 2 2 2 2 2 +select * from t1 where c7 / 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c1 * 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c2 * 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c3 * 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c4 * 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c5 * 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c6 * 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c7 * 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c1 + 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c2 + 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c3 + 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c4 + 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c5 + 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c6 + 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c7 + 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c1 - 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c2 - 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c3 - 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c4 - 2 = 1; +ERROR 22003: BIGINT UNSIGNED value is out of range in '(`test`.`t1`.`c4` - 2)' +select * from t1 where c4 - 1 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c5 - 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +select * from t1 where c6 - 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +3 3 3 3 3 3 3 +select * from t1 where c7 - 2 = 1; +c1 c2 c3 c4 c5 c6 c7 +3 3 3 3 3 3 3 +create table tb_cache(a int); +insert into tb_cache values(null); +prepare stmt1 from 'select a from tb_cache where a <=> ?'; +set @arg1 = null; +execute stmt1 using @arg1; +a +NULL +insert into tb_cache values(1); +set @arg2 = 1; +execute stmt1 using @arg2; +a +1 +insert into tb_cache values(0); +set @arg3 = 'a'; +execute stmt1 using @arg3; +a +0 +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'a' +Warning 1292 Truncated incorrect INTEGER value: 'a' +drop table tb_cache; drop table t1; drop table t2; drop table t3; diff --git a/mysql-test/suite/ctc/t/ctc_cond_pushdown.test b/mysql-test/suite/ctc/t/ctc_cond_pushdown.test index d882afe..352c8ca 100644 --- a/mysql-test/suite/ctc/t/ctc_cond_pushdown.test +++ b/mysql-test/suite/ctc/t/ctc_cond_pushdown.test @@ -271,6 +271,83 @@ select * from myset where col = 'a,d'; select * from myset where col like 'a,d'; drop table if exists myset; + +# push math +drop table if exists t1; +CREATE TABLE t1(c1 tinyint, c2 tinyint not null, c3 tinyint signed, c4 tinyint unsigned, c5 int, c6 long, c7 bigint); +INSERT INTO t1 VALUES (1,1,1,1,1,1,1), (2,2,2,2,2,2,2); +INSERT INTO t1 VALUES (null, 5, null, null, null, null, null); +INSERT INTO t1 VALUES (3,3,3,3,3,3,3), (4,4,4,4,4,4,4); +INSERT INTO t1 VALUES (null, 7, null, null, null, null, null); +INSERT INTO t1 VALUES (8,8,127,255,8,8,8); +select * from t1; + +## mod +select * from t1 where c1 % 2 = 0; +select * from t1 where c2 % 2 = 0; +select * from t1 where c3 % 2 = 0; +select * from t1 where c4 % 2 = 0; +select * from t1 where c5 % 2 = 0; +select * from t1 where c6 % 2 = 0; +select * from t1 where c7 % 2 = 0; + +## div +select * from t1 where c1 / 2 = 1; +select * from t1 where c2 / 2 = 1; +select * from t1 where c3 / 2 = 1; +select * from t1 where c4 / 2 = 1; +select * from t1 where c5 / 2 = 1; +select * from t1 where c6 / 2 = 1; +select * from t1 where c7 / 2 = 1; + +## mul +select * from t1 where c1 * 2 = 1; +select * from t1 where c2 * 2 = 1; +select * from t1 where c3 * 2 = 1; +select * from t1 where c4 * 2 = 1; +select * from t1 where c5 * 2 = 1; +select * from t1 where c6 * 2 = 1; +select * from t1 where c7 * 2 = 1; + +## add +select * from t1 where c1 + 2 = 1; +select * from t1 where c2 + 2 = 1; +select * from t1 where c3 + 2 = 1; +select * from t1 where c4 + 2 = 1; +select * from t1 where c5 + 2 = 1; +select * from t1 where c6 + 2 = 1; +select * from t1 where c7 + 2 = 1; + +## sub +select * from t1 where c1 - 2 = 1; +select * from t1 where c2 - 2 = 1; +select * from t1 where c3 - 2 = 1; +--error 1690 +select * from t1 where c4 - 2 = 1; +select * from t1 where c4 - 1 = 1; +select * from t1 where c5 - 2 = 1; +select * from t1 where c6 - 2 = 1; +select * from t1 where c7 - 2 = 1; + + +## cache item +create table tb_cache(a int); + +insert into tb_cache values(null); +prepare stmt1 from 'select a from tb_cache where a <=> ?'; + +set @arg1 = null; +execute stmt1 using @arg1; + +insert into tb_cache values(1); +set @arg2 = 1; +execute stmt1 using @arg2; + +insert into tb_cache values(0); +set @arg3 = 'a'; +execute stmt1 using @arg3; +drop table tb_cache; + drop table t1; drop table t2; drop table t3; @@ -285,4 +362,4 @@ drop table t11; drop table t12; drop table t13; drop table t14; -drop table t15; \ No newline at end of file +drop table t15; diff --git a/storage/ctc/ctc_srv.h b/storage/ctc/ctc_srv.h index 7a4de58..b816d81 100644 --- a/storage/ctc/ctc_srv.h +++ b/storage/ctc/ctc_srv.h @@ -462,6 +462,21 @@ typedef enum en_ctc_func_type_t { CTC_XOR_FUNC } ctc_func_type_t; +typedef enum en_ctc_math_type_t { + CTC_UNKNOWN_MATH, + CTC_MOD_FUNC, + CTC_PLUS_FUNC, + CTC_MINUS_FUNC, + CTC_MUL_FUNC, + CTC_DIV_FUNC +} ctc_math_type_t; + +typedef struct en_ctc_cond_math_t { + ctc_math_type_t type; + void *field_value; + uint16_t field_size; +} ctc_cond_math_info; + typedef struct en_ctc_cond_field_t { uint16_t field_no; enum_ctc_ddl_field_types field_type; @@ -472,6 +487,7 @@ typedef struct en_ctc_cond_field_t { bool col_updated; bool index_only_invalid_col; // col in cond but not in index while select with index_only bool no_backslash; + ctc_cond_math_info math_info; } ctc_cond_field; struct en_ctc_cond_list_t; diff --git a/storage/ctc/ctc_util.cc b/storage/ctc/ctc_util.cc index 6cde6e5..7621a58 100644 --- a/storage/ctc/ctc_util.cc +++ b/storage/ctc/ctc_util.cc @@ -164,12 +164,12 @@ int ctc_set_cond_field_size(const field_cnvrt_aux_t *mysql_info, ctc_conds *cond } int ctc_fill_cond_field_data_num(ctc_handler_t m_tch, Item *items, Field *mysql_field, - const field_cnvrt_aux_t *mysql_info, ctc_conds *cond) { + const field_cnvrt_aux_t *mysql_info, void **field_value, uint16_t *field_size) { int ret = CT_SUCCESS; void *data = nullptr; bool is_alloc_data = CT_FALSE; - Item_func_comparison *item_func_comparison = dynamic_cast(items); - CTC_RET_ERR_IF_NULL(item_func_comparison); + Item_func *item_func = dynamic_cast(items); + CTC_RET_ERR_IF_NULL(item_func); switch (mysql_info->ddl_field_type) { case CTC_DDL_TYPE_LONG: case CTC_DDL_TYPE_LONGLONG: { @@ -177,11 +177,11 @@ int ctc_fill_cond_field_data_num(ctc_handler_t m_tch, Item *items, Field *mysql_ CTC_RET_ERR_IF_NULL(item_func); longlong val; if ((item_func->arguments()[1])->type() == Item::CACHE_ITEM) { - Item_cache_int *item_cache_int = dynamic_cast(item_func_comparison->arguments()[1]); + Item_cache_int *item_cache_int = dynamic_cast(item_func->arguments()[1]); CTC_RET_ERR_IF_NULL(item_cache_int); val = item_cache_int->val_int(); } else { - Item_int *item_int = dynamic_cast(item_func_comparison->arguments()[1]); + Item_int *item_int = dynamic_cast(item_func->arguments()[1]); CTC_RET_ERR_IF_NULL(item_int); val = item_int->val_int(); } @@ -196,7 +196,7 @@ int ctc_fill_cond_field_data_num(ctc_handler_t m_tch, Item *items, Field *mysql_ break; } case CTC_DDL_TYPE_DOUBLE: { - Item_float *item_float = dynamic_cast(item_func_comparison->arguments()[1]); + Item_float *item_float = dynamic_cast(item_func->arguments()[1]); CTC_RET_ERR_IF_NULL(item_float); data = &item_float->value; break; @@ -208,7 +208,7 @@ int ctc_fill_cond_field_data_num(ctc_handler_t m_tch, Item *items, Field *mysql_ const int prec = field_new_decimal->precision; int binary_size = my_decimal_get_binary_size(prec, scale); uchar *buff = new uchar[binary_size]; - Item_decimal *item_decimal = dynamic_cast(item_func_comparison->arguments()[1]); + Item_decimal *item_decimal = dynamic_cast(item_func->arguments()[1]); CTC_RET_ERR_IF_NULL(item_decimal); my_decimal *d = item_decimal->val_decimal(nullptr); my_decimal2binary(E_DEC_FATAL_ERROR, d, buff, prec, scale); @@ -230,14 +230,14 @@ int ctc_fill_cond_field_data_num(ctc_handler_t m_tch, Item *items, Field *mysql_ } uchar cantian_ptr[DECIMAL_MAX_STR_LENGTH + 1]; ret = convert_numeric_to_cantian(mysql_info, (const uchar *)data, cantian_ptr, mysql_field, - (uint32_t *)(&cond->field_info.field_size)); - cond->field_info.field_value = ctc_alloc_buf(&m_tch, cond->field_info.field_size); - if (cond->field_info.field_size > 0 && cond->field_info.field_value == nullptr) { - ctc_log_error("ctc_fill_cond_field: alloc field_data error, size(%u).", cond->field_info.field_size); + (uint32_t *)(field_size)); + *field_value = ctc_alloc_buf(&m_tch, *field_size); + if (*field_size > 0 && *field_value == nullptr) { + ctc_log_error("ctc_fill_cond_field: alloc field_data error, size(%u).", *field_size); return CT_ERROR; } - memcpy(cond->field_info.field_value, cantian_ptr, cond->field_info.field_size); + memcpy(*field_value, cantian_ptr, *field_size); if (is_alloc_data) { my_free(data); is_alloc_data = CT_FALSE; @@ -392,7 +392,8 @@ int ctc_fill_cond_field_data(ctc_handler_t m_tch, Item *items, Field *mysql_fiel switch (mysql_info->sql_data_type) { case NUMERIC_DATA: - ret = ctc_fill_cond_field_data_num(m_tch, items, mysql_field, mysql_info, cond); + ret = ctc_fill_cond_field_data_num(m_tch, items, mysql_field, mysql_info, + &cond->field_info.field_value, &cond->field_info.field_size); break; case DATETIME_DATA:{ MYSQL_TIME ltime; @@ -436,10 +437,23 @@ int ctc_fill_cond_field_data(ctc_handler_t m_tch, Item *items, Field *mysql_fiel return ret; } +ctc_math_type_t ctc_fill_cond_math_type(Item_func *item_func) { + auto it = MATH_TYPE_MAP.find(item_func->functype()); + return it != MATH_TYPE_MAP.end() ? it->second : CTC_UNKNOWN_MATH; +} + int ctc_fill_cond_field(ctc_handler_t m_tch, Item *items, Field **field, ctc_conds *cond, bool no_backslash) { Item_func *item_func = dynamic_cast(items); + Item *field_item = item_func->arguments()[0]; CTC_RET_ERR_IF_NULL(item_func); - const char *field_name = item_func->arguments()[0]->item_name.ptr(); + Item *left_item = item_func->arguments()[0]; + cond->field_info.math_info.type = CTC_UNKNOWN_MATH; + if (left_item->type() == Item::FUNC_ITEM) { + Item_func *left_item_func = dynamic_cast(left_item); + field_item = left_item_func->arguments()[0]; + cond->field_info.math_info.type = ctc_fill_cond_math_type(left_item_func); + } + const char *field_name = field_item->item_name.ptr(); cond->field_info.field_no = ctc_get_column_by_field(field, field_name); if (cond->field_info.field_no == INVALID_MAX_COLUMN) { return CT_ERROR; @@ -467,7 +481,15 @@ int ctc_fill_cond_field(ctc_handler_t m_tch, Item *items, Field **field, ctc_con if (ctc_set_cond_field_size(mysql_info, cond) != CT_SUCCESS) { return CT_ERROR; } + cond->field_info.math_info.field_size = cond->field_info.field_size; + if (left_item->type() == Item::FUNC_ITEM) { + if (ctc_fill_cond_field_data_num(m_tch, left_item, mysql_field, mysql_info, + &cond->field_info.math_info.field_value, + &cond->field_info.math_info.field_size)) { + return CT_ERROR; + } + } return ctc_fill_cond_field_data(m_tch, items, mysql_field, mysql_info, cond); } diff --git a/storage/ctc/ctc_util.h b/storage/ctc/ctc_util.h index 7885910..e523c1f 100644 --- a/storage/ctc/ctc_util.h +++ b/storage/ctc/ctc_util.h @@ -32,6 +32,14 @@ using namespace std; static unordered_set mysql_system_db{"information_schema", "mysql", "performance_schema", "sys"}; +static const std::unordered_map MATH_TYPE_MAP = { + {Item_func::MOD_FUNC, CTC_MOD_FUNC}, + {Item_func::PLUS_FUNC, CTC_PLUS_FUNC}, + {Item_func::MINUS_FUNC, CTC_MINUS_FUNC}, + {Item_func::MUL_FUNC, CTC_MUL_FUNC}, + {Item_func::DIV_FUNC, CTC_DIV_FUNC} +}; + #define CM_IS_EMPTY_STR(str) (((str) == NULL) || ((str)[0] == 0)) #define CTC_GET_THD_DB_NAME(thd) (thd->db().str == NULL) ? nullptr : const_cast(thd->db().str) @@ -55,7 +63,7 @@ int ctc_set_cond_field_size(const field_cnvrt_aux_t *mysql_info, ctc_conds *cond int ctc_fill_cond_field_data(ctc_handler_t m_tch, Item *items, Field *mysql_field, const field_cnvrt_aux_t *mysql_info, ctc_conds *cond); int ctc_fill_cond_field_data_num(ctc_handler_t m_tch, Item *items, Field *mysql_field, - const field_cnvrt_aux_t *mysql_info, ctc_conds *cond); + const field_cnvrt_aux_t *mysql_info, void **field_value, uint16_t *field_size); int ctc_fill_cond_field_data_date(ctc_handler_t m_tch, const field_cnvrt_aux_t *mysql_info, MYSQL_TIME ltime, date_detail_t *date_detail, ctc_conds *cond); int ctc_fill_cond_field_data_string(ctc_handler_t m_tch, Item_func *item_func, ctc_conds *cond, bool no_backslash); diff --git a/storage/ctc/ha_ctc.cc b/storage/ctc/ha_ctc.cc index c4dfb3d..8ed899f 100644 --- a/storage/ctc/ha_ctc.cc +++ b/storage/ctc/ha_ctc.cc @@ -600,32 +600,71 @@ static bool is_supported_datatype_cond(enum_field_types datatype) { } } -static bool is_supported_func_item(Item *term) { +static bool is_supported_datatype_math(enum_field_types datatype) { + switch (datatype) { + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_LONGLONG: { + return true; + } + default: + return false; + } +} + +static bool is_supported_field_for_math(Item_func *item_func) { + Item_field *item_field = dynamic_cast(item_func->arguments()[0]); + if (!item_field) { + return false; + } + + return is_supported_datatype_math(item_field->data_type()) + && !item_field->field->is_gcol() + && item_field->field->part_of_prefixkey.is_clear_all(); +} + +static bool is_supported_math(Item *term) { Item_func *item_func = dynamic_cast(term); - if (item_func == nullptr) { + if (!item_func || item_func->argument_count() < 2) { return false; } - Item_func::Functype functype = item_func->functype(); - // filter unspported func - if (functype != Item_func::EQ_FUNC && - functype != Item_func::EQUAL_FUNC && - functype != Item_func::NE_FUNC && - functype != Item_func::LT_FUNC && - functype != Item_func::LE_FUNC && - functype != Item_func::GE_FUNC && - functype != Item_func::GT_FUNC && - functype != Item_func::LIKE_FUNC && - functype != Item_func::ISNULL_FUNC && - functype != Item_func::ISNOTNULL_FUNC) { - return false; + + Item *left_item = item_func->arguments()[0]; + Item *right_item = item_func->arguments()[1]; + + if (left_item->type() != Item::FUNC_ITEM) { + return false; } - Item::Type type = (item_func->arguments()[0])->type(); - // filter expressions - if (type != Item::FIELD_ITEM) { + if (right_item->type() != Item::INT_ITEM) { return false; } + Item_func *left_item_func = dynamic_cast(left_item); + auto it = MATH_TYPE_MAP.find(left_item_func->functype()); + if(!left_item_func || + it == MATH_TYPE_MAP.end() || + left_item_func->argument_count() < 2) { + return false; + } + + if ((left_item_func->arguments()[1])->type() == Item::INT_ITEM && + (left_item_func->arguments()[0])->type() == Item::FIELD_ITEM && + is_supported_field_for_math(left_item_func)) { + return true; + } + + return false; +} + +static bool is_supported_field(Item *term) { + Item_func *item_func = dynamic_cast(term); + if (item_func == nullptr) { + return false; + } + Item_field *item_field = dynamic_cast(item_func->arguments()[0]); if (item_field == nullptr) { return false; @@ -648,15 +687,17 @@ static bool is_supported_func_item(Item *term) { } } + Item_func::Functype functype = item_func->functype(); if (functype == Item_func::ISNULL_FUNC || functype == Item_func::ISNOTNULL_FUNC) { return true; } if (functype == Item_func::LIKE_FUNC) { - Item_func_like *like_func = dynamic_cast(item_func); - if (like_func == nullptr || like_func->escape_was_used_in_parsing() || !is_string_type(item_field->data_type())) { + if (!is_string_type(item_field->data_type())) { return false; } + Item_func_like *like_func = dynamic_cast(item_func); + return (like_func != nullptr && !like_func->escape_was_used_in_parsing()); } if (item_field->cmp_context == INVALID_RESULT) { @@ -666,6 +707,38 @@ static bool is_supported_func_item(Item *term) { return check_cmp_result(term); } +static bool is_supported_func_item(Item *term) { + Item_func *item_func = dynamic_cast(term); + if (item_func == nullptr) { + return false; + } + Item_func::Functype functype = item_func->functype(); + // filter unspported func + if (functype != Item_func::EQ_FUNC && + functype != Item_func::EQUAL_FUNC && + functype != Item_func::NE_FUNC && + functype != Item_func::LT_FUNC && + functype != Item_func::LE_FUNC && + functype != Item_func::GE_FUNC && + functype != Item_func::GT_FUNC && + functype != Item_func::LIKE_FUNC && + functype != Item_func::ISNULL_FUNC && + functype != Item_func::ISNOTNULL_FUNC) { + return false; + } + + Item::Type type = (item_func->arguments()[0])->type(); + // filter expressions + if (type == Item::FIELD_ITEM) { + return is_supported_field(term); + } + + if (type == Item::FUNC_ITEM) { + return is_supported_math(term); + } + return false; +} + int create_and_conditions(Item_cond *cond, List pushed_list, List remainder_list, Item *&pushed_cond, Item *&remainder_cond) { -- Gitee