diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-06-28 14:29:51 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-06-28 14:29:51 +0400 |
commit | ee0237fe89c64b995e7979c315de5a006fe2951a (patch) | |
tree | 83fd9b718435154adfd6c79bb8b0cbc541194af7 | |
parent | 55d8ee5f707bab41068d79144e6cf4a01c6eea76 (diff) | |
download | mariadb-git-ee0237fe89c64b995e7979c315de5a006fe2951a.tar.gz |
MDEV-8330 Get rid of Item_func::select_optimize() and Item_func::optimize_type
-rw-r--r-- | sql/item_cmpfunc.cc | 11 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 19 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/opt_range.cc | 28 | ||||
-rw-r--r-- | sql/sql_select.cc | 3 |
5 files changed, 41 insertions, 24 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 9920aa40542..e61c05edc25 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4831,22 +4831,21 @@ longlong Item_func_like::val_int() We can optimize a where if first character isn't a wildcard */ -Item_func::optimize_type Item_func_like::select_optimize() const +bool Item_func_like::with_sargable_pattern() const { if (!args[1]->const_item() || args[1]->is_expensive()) - return OPTIMIZE_NONE; + return false; String* res2= args[1]->val_str((String *) &cmp_value2); if (!res2) - return OPTIMIZE_NONE; + return false; if (!res2->length()) // Can optimize empty wildcard: column LIKE '' - return OPTIMIZE_OP; + return true; DBUG_ASSERT(res2->ptr()); char first= res2->ptr()[0]; - return (first == wild_many || first == wild_one) ? - OPTIMIZE_NONE : OPTIMIZE_OP; + return first != wild_many && first != wild_one; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 35310219c45..e2c4334585f 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -290,14 +290,14 @@ public: */ class Item_bool_func2 :public Item_bool_func { /* Bool with 2 string args */ + bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } public: Item_bool_func2(Item *a,Item *b) :Item_bool_func(a,b) { } - optimize_type select_optimize() const { return OPTIMIZE_OP; } virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; } - bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } bool is_null() { return MY_TEST(args[0]->is_null() || args[1]->is_null()); } + SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr); COND *remove_eq_conds(THD *thd, Item::cond_result *cond_value, bool top_level); bool count_sargable_conds(uchar *arg); @@ -592,7 +592,6 @@ public: longlong val_int(); enum Functype functype() const { return NE_FUNC; } cond_result eq_cmp_result() const { return COND_FALSE; } - optimize_type select_optimize() const { return OPTIMIZE_KEY; } const char *func_name() const { return "<>"; } Item *negated_item(); void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, @@ -643,7 +642,6 @@ public: Item_func_between(Item *a, Item *b, Item *c) :Item_func_opt_neg(a, b, c), compare_as_dates(FALSE) { } longlong val_int(); - optimize_type select_optimize() const { return OPTIMIZE_KEY; } enum Functype functype() const { return BETWEEN; } const char *func_name() const { return "between"; } bool fix_fields(THD *, Item **); @@ -1334,8 +1332,6 @@ public: } DBUG_VOID_RETURN; } - optimize_type select_optimize() const - { return OPTIMIZE_KEY; } void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables); SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr); @@ -1383,9 +1379,9 @@ class Item_func_null_predicate :public Item_bool_func { public: Item_func_null_predicate(Item *a) :Item_bool_func(a) { } - optimize_type select_optimize() const { return OPTIMIZE_NULL; } void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables); + SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr); CHARSET_INFO *compare_collation() const { return args[0]->collation.collation; } void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; } @@ -1495,6 +1491,7 @@ class Item_func_like :public Item_bool_func2 DTCollation cmp_collation; String cmp_value1, cmp_value2; + bool with_sargable_pattern() const; public: int escape; @@ -1508,7 +1505,6 @@ public: { Item_func::print_op(str, query_type); } - optimize_type select_optimize() const; CHARSET_INFO *compare_collation() const { return cmp_collation.collation; } cond_result eq_cmp_result() const @@ -1548,6 +1544,12 @@ public: } void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables); + SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr) + { + return with_sargable_pattern() ? + Item_bool_func2::get_mm_tree(param, cond_ptr) : + Item_func::get_mm_tree(param, cond_ptr); + } const char *func_name() const { return "like"; } bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec() @@ -1930,7 +1932,6 @@ public: enum Functype functype() const { return MULT_EQUAL_FUNC; } longlong val_int(); const char *func_name() const { return "multiple equal"; } - optimize_type select_optimize() const { return OPTIMIZE_EQUAL; } void sort(Item_field_cmpfunc compare, void *arg); void fix_length_and_dec(); bool fix_fields(THD *thd, Item **ref); diff --git a/sql/item_func.h b/sql/item_func.h index 21813960bb0..97138cf52a5 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -60,8 +60,6 @@ public: SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC, EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC, NEG_FUNC, GSYSVAR_FUNC, DYNCOL_FUNC }; - enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL, - OPTIMIZE_EQUAL }; enum Type type() const { return FUNC_ITEM; } virtual enum Functype functype() const { return UNKNOWN_FUNC; } Item_func(void): @@ -136,8 +134,6 @@ public: COND_EQUAL **cond_equal_ref); SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr); bool eq(const Item *item, bool binary_cmp) const; - virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; } - virtual bool have_rev_func() const { return 0; } virtual Item *key_item() const { return args[0]; } virtual bool const_item() const { return const_item_cache; } void set_arguments(List<Item> &list) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 57a08e33b90..261b95d2948 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -8203,19 +8203,41 @@ SEL_TREE *Item_equal::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr) SEL_TREE *Item_func::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr) { DBUG_ENTER("Item_func::get_mm_tree"); + DBUG_RETURN(const_item() ? get_mm_tree_for_const(param, this) : NULL); +} + + +SEL_TREE *Item_func_null_predicate::get_mm_tree(RANGE_OPT_PARAM *param, + Item **cond_ptr) +{ + DBUG_ENTER("Item_func_null_predicate::get_mm_tree"); if (const_item()) DBUG_RETURN(get_mm_tree_for_const(param, this)); + param->cond= this; + if (args[0]->real_item()->type() == Item::FIELD_ITEM) + { + Item_field *field_item= (Item_field*) args[0]->real_item(); + if (!field_item->const_item()) + DBUG_RETURN(get_full_func_mm_tree(param, this, field_item, NULL, false)); + } + DBUG_RETURN(NULL); +} - if (select_optimize() == Item_func::OPTIMIZE_NONE) - DBUG_RETURN(0); + +SEL_TREE *Item_bool_func2::get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr) +{ + DBUG_ENTER("Item_bool_func2::get_mm_tree"); + if (const_item()) + DBUG_RETURN(get_mm_tree_for_const(param, this)); param->cond= this; SEL_TREE *ftree= 0; + DBUG_ASSERT(arg_count == 2); if (arguments()[0]->real_item()->type() == Item::FIELD_ITEM) { Item_field *field_item= (Item_field*) (arguments()[0]->real_item()); - Item *value= arg_count > 1 ? arguments()[1] : NULL; + Item *value= arguments()[1]; if (value && value->is_expensive()) DBUG_RETURN(0); if (!arguments()[0]->real_item()->const_item()) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 02335ddf0f7..656c54353ca 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4759,8 +4759,7 @@ Item_func_like::add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level, table_map usable_tables, SARGABLE_PARAM **sargables) { - if (is_local_field(args[0]) && - Item_func_like::select_optimize() == OPTIMIZE_OP) + if (is_local_field(args[0]) && with_sargable_pattern()) { /* SELECT * FROM t1 WHERE field LIKE const_pattern |