diff options
author | unknown <igor@rurik.mysql.com> | 2004-02-18 22:21:37 -0800 |
---|---|---|
committer | unknown <igor@rurik.mysql.com> | 2004-02-18 22:21:37 -0800 |
commit | c88e5213d4f8acbbba33d293a9573042818f0aec (patch) | |
tree | 930d3af069574ba2f718af7997089edaeb3b22fc /sql/opt_range.cc | |
parent | 4b058cba0d059ecb9dd2d69e911f0523e411b19d (diff) | |
download | mariadb-git-c88e5213d4f8acbbba33d293a9573042818f0aec.tar.gz |
Many files:
After review fixes for Item_equal.
sql/item.cc:
After review fixes for Item_equal.
sql/item.h:
After review fixes for Item_equal.
sql/item_cmpfunc.cc:
After review fixes for Item_equal.
sql/item_cmpfunc.h:
After review fixes for Item_equal.
sql/item_func.h:
After review fixes for Item_equal.
sql/item_func.cc:
After review fixes for Item_equal.
sql/item_row.cc:
After review fixes for Item_equal.
sql/item_row.h:
After review fixes for Item_equal.
sql/item_strfunc.h:
After review fixes for Item_equal.
sql/opt_range.cc:
After review fixes for Item_equal.
sql/sql_list.h:
After review fixes for Item_equal.
sql/sql_select.cc:
After review fixes for Item_equal.
mysql-test/r/select.result:
After review fixes for Item_equal.
mysql-test/r/subselect.result:
After review fixes for Item_equal.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 148 |
1 files changed, 86 insertions, 62 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 80d9bf92b45..67603eeeccd 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1494,6 +1494,21 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM *param, } +/* + Build a SEL_TREE for a simple predicate + + SYNOPSIS + get_func_mm_tree() + param PARAM from SQL_SELECT::test_quick_select + cond_func item for the predicate + field field in the predicate + value constant in the predicate + cmp_type compare type for the field + + RETURN + Pointer to thre built tree +*/ + static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, Field *field, Item *value, Item_result cmp_type) @@ -1501,21 +1516,18 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, SEL_TREE *tree= 0; DBUG_ENTER("get_func_mm_tree"); - if (cond_func->functype() == Item_func::NE_FUNC) - { - + switch (cond_func->functype()) { + case Item_func::NE_FUNC: tree= get_mm_parts(param, field, Item_func::LT_FUNC, value, cmp_type); if (tree) { tree= tree_or(param, tree, get_mm_parts(param, field, - Item_func::GT_FUNC, - value, cmp_type)); + Item_func::GT_FUNC, + value, cmp_type)); } - } - else if (cond_func->functype() == Item_func::BETWEEN) - { - + break; + case Item_func::BETWEEN: tree= get_mm_parts(param, field, Item_func::GE_FUNC, cond_func->arguments()[1],cmp_type); if (tree) @@ -1525,30 +1537,42 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func, cond_func->arguments()[2], cmp_type)); } - } - else if (cond_func->functype() == Item_func::IN_FUNC) + break; + case Item_func::IN_FUNC: { Item_func_in *func=(Item_func_in*) cond_func; tree= get_mm_parts(param, field, Item_func::EQ_FUNC, func->arguments()[1], cmp_type); if (tree) { - for (uint i =2 ; i < func->argument_count() ; i++) + Item **arg, **end; + for (arg= func->arguments()+2, end= arg+func->argument_count()-2; + arg < end ; arg++) { tree= tree_or(param, tree, get_mm_parts(param, field, Item_func::EQ_FUNC, - func->arguments()[i], + *arg, cmp_type)); } } + break; } - else + default: { + /* + Here the function for the following predicates are processed: + <, <=, =, >=, >, LIKE, IS NULL, IS NOT NULL. + If the predicate is of the form (value op field) it is handled + as the equivalent predicate (field rev_op value), e.g. + 2 <= a is handled as a >= 2. + */ Item_func::Functype func_type= (value != cond_func->arguments()[0]) ? cond_func->functype() : ((Item_bool_func2*) cond_func)->rev_functype(); tree= get_mm_parts(param, field, func_type, value, cmp_type); } + } + DBUG_RETURN(tree); } @@ -1625,71 +1649,71 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE) DBUG_RETURN(0); // Can't be calculated - if (cond_func->functype() == Item_func::BETWEEN) - { - if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM) - { - field_item= (Item_field*) (cond_func->arguments()[0]); - value= NULL; - } - else + switch (cond_func->functype()) { + case Item_func::BETWEEN: + if (cond_func->arguments()[0]->type() != Item::FIELD_ITEM) DBUG_RETURN(0); - } - else if (cond_func->functype() == Item_func::IN_FUNC) + field_item= (Item_field*) (cond_func->arguments()[0]); + value= NULL; + break; + case Item_func::IN_FUNC: { Item_func_in *func=(Item_func_in*) cond_func; - if (func->key_item()->type() == Item::FIELD_ITEM) - { - field_item= (Item_field*) (func->key_item()); - value= NULL; - } - else + if (func->key_item()->type() != Item::FIELD_ITEM) DBUG_RETURN(0); + field_item= (Item_field*) (func->key_item()); + value= NULL; + break; } - else if (cond_func->functype() == Item_func::MULT_EQUAL_FUNC) + case Item_func::MULT_EQUAL_FUNC: { Item_equal *item_equal= (Item_equal *) cond; - Item_equal_iterator it(*item_equal); if (!(value= item_equal->get_const())) - value= it++; - while (value) + DBUG_RETURN(0); + Item_equal_iterator it(*item_equal); + ref_tables= value->used_tables(); + while ((field_item= it++)) { - ref_tables= value->used_tables(); - Item_equal_iterator li(*item_equal); - while ((field_item= li++)) + Field *field= field_item->field; + Item_result cmp_type= field->cmp_type(); + if (!((ref_tables | field->table->map) & param_comp)) { - if (field_item != value) - { - Field *field= field_item->field; - Item_result cmp_type= field->cmp_type(); - if (!((ref_tables | field->table->map) & param_comp)) - { - tree= get_mm_parts(param, field, Item_func::EQ_FUNC, - value,cmp_type); - ftree= !ftree ? tree : tree_and(param, ftree, tree); - } - } + tree= get_mm_parts(param, field, Item_func::EQ_FUNC, + value,cmp_type); + ftree= !ftree ? tree : tree_and(param, ftree, tree); } - if (item_equal->get_const()) - break; - value= it++; } + DBUG_RETURN(ftree); } - else if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM) - { - field_item= (Item_field*) (cond_func->arguments()[0]); - value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0; - } - else if (cond_func->have_rev_func() && + default: + if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM) + { + field_item= (Item_field*) (cond_func->arguments()[0]); + value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0; + } + else if (cond_func->have_rev_func() && cond_func->arguments()[1]->type() == Item::FIELD_ITEM) - { - field_item= (Item_field*) (cond_func->arguments()[1]); - value= cond_func->arguments()[0]; + { + field_item= (Item_field*) (cond_func->arguments()[1]); + value= cond_func->arguments()[0]; + } + else + DBUG_RETURN(0); } - else - DBUG_RETURN(0); + /* + If the where condition contains a predicate (ti.field op const), + then not only SELL_TREE for this predicate is built, but + the trees for the results of substitution of ti.field for + each tj.field belonging to the same multiple equality as ti.field + are built as well. + E.g. for WHERE t1.a=t2.a AND t2.a > 10 + a SEL_TREE for t2.a > 10 will be built for quick select from t2 + and + a SEL_TREE for t1.a > 10 will be built for quick select from t1. + */ + for (uint i= 0; i < cond_func->arg_count; i++) { Item *arg= cond_func->arguments()[i]; |