diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2022-11-01 10:42:22 +0100 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2022-11-01 11:55:28 +0100 |
commit | 49a22c5897823c528d52886f6048d5b4c91e221f (patch) | |
tree | 92eedca678276458a7c4e27f357acd12d4fdcbac /sql/sql_select.cc | |
parent | 8e6a64194b76a199b0bbf2edc9a4e9facda8da2c (diff) | |
parent | ebf2121529fcf06971b4c0fc28f40654ef8dd99f (diff) | |
download | mariadb-git-49a22c5897823c528d52886f6048d5b4c91e221f.tar.gz |
Merge branch '10.9' into 10.10
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b76ec6d14f3..9c89225d1e6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2248,6 +2248,9 @@ JOIN::optimize_inner() ignore_on_expr= true; break; } + + transform_in_predicates_into_equalities(thd); + conds= optimize_cond(this, conds, join_list, ignore_on_expr, &cond_value, &cond_equal, OPT_LINK_EQUAL_FIELDS); @@ -30949,6 +30952,95 @@ static bool process_direct_rownum_comparison(THD *thd, SELECT_LEX_UNIT *unit, DBUG_RETURN(false); } +/** + @brief + Transform IN predicates having equal constant elements to equalities + + @param thd The context of the statement + + @details + If all elements in an IN predicate are constant and equal to each other + then clause + - "a IN (e1,..,en)" can be transformed to "a = e1" + - "a NOT IN (e1,..,en)" can be transformed to "a != e1". + This means an object of Item_func_in can be replaced with an object of + Item_func_eq for IN (e1,..,en) clause or Item_func_ne for + NOT IN (e1,...,en). + Such a replacement allows the optimizer to choose a better execution plan. + + This methods applies such transformation for each IN predicate of the WHERE + condition and ON expressions of this join where possible + + @retval + false success + true failure +*/ +bool JOIN::transform_in_predicates_into_equalities(THD *thd) +{ + DBUG_ENTER("JOIN::transform_in_predicates_into_equalities"); + DBUG_RETURN(transform_all_conds_and_on_exprs( + thd, &Item::in_predicate_to_equality_transformer)); +} + + +/** + @brief + Transform all items in WHERE and ON expressions using a given transformer + + @param thd The context of the statement + transformer Pointer to the transformation function + + @details + For each item of the WHERE condition and ON expressions of the SELECT + for this join the method performs the intransformation using the given + transformation function + + @retval + false success + true failure +*/ +bool JOIN::transform_all_conds_and_on_exprs(THD *thd, + Item_transformer transformer) +{ + if (conds) + { + conds= conds->top_level_transform(thd, transformer, (uchar *) 0); + if (!conds) + return true; + } + if (join_list) + { + if (transform_all_conds_and_on_exprs_in_join_list(thd, join_list, + transformer)) + return true; + } + return false; +} + + +bool JOIN::transform_all_conds_and_on_exprs_in_join_list( + THD *thd, List<TABLE_LIST> *join_list, Item_transformer transformer) +{ + TABLE_LIST *table; + List_iterator<TABLE_LIST> li(*join_list); + + while ((table= li++)) + { + if (table->nested_join) + { + if (transform_all_conds_and_on_exprs_in_join_list( + thd, &table->nested_join->join_list, transformer)) + return true; + } + if (table->on_expr) + { + table->on_expr= table->on_expr->top_level_transform(thd, transformer, 0); + if (!table->on_expr) + return true; + } + } + return false; +} /** |