Commit aea54a11 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-12716 Change Value_source::Context to operate Type_handler rather than Item_result

parent c898de84
...@@ -365,24 +365,25 @@ class Value_source ...@@ -365,24 +365,25 @@ class Value_source
Subst_constraint m_subst_constraint; Subst_constraint m_subst_constraint;
/* /*
Comparison type. Comparison type.
Impostant only when ANY_SUBSTS. Important only when ANY_SUBSTS.
*/ */
Item_result m_compare_type; const Type_handler *m_compare_handler;
/* /*
Collation of the comparison operation. Collation of the comparison operation.
Important only when ANY_SUBST. Important only when ANY_SUBST.
*/ */
CHARSET_INFO *m_compare_collation; CHARSET_INFO *m_compare_collation;
public: public:
Context(Subst_constraint subst, Item_result type, CHARSET_INFO *cs) Context(Subst_constraint subst, const Type_handler *h, CHARSET_INFO *cs)
:m_subst_constraint(subst), :m_subst_constraint(subst),
m_compare_type(type), m_compare_handler(h),
m_compare_collation(cs) { } m_compare_collation(cs)
{ DBUG_ASSERT(h == h->type_handler_for_comparison()); }
Subst_constraint subst_constraint() const { return m_subst_constraint; } Subst_constraint subst_constraint() const { return m_subst_constraint; }
Item_result compare_type() const Item_result compare_type() const
{ {
DBUG_ASSERT(m_subst_constraint == ANY_SUBST); DBUG_ASSERT(m_subst_constraint == ANY_SUBST);
return m_compare_type; return m_compare_handler->cmp_type();
} }
CHARSET_INFO *compare_collation() const CHARSET_INFO *compare_collation() const
{ {
...@@ -394,12 +395,13 @@ class Value_source ...@@ -394,12 +395,13 @@ class Value_source
{ // Use this to request only exact value, no invariants. { // Use this to request only exact value, no invariants.
public: public:
Context_identity() Context_identity()
:Context(IDENTITY_SUBST, STRING_RESULT, &my_charset_bin) { } :Context(IDENTITY_SUBST, &type_handler_long_blob, &my_charset_bin) { }
}; };
class Context_boolean: public Context class Context_boolean: public Context
{ // Use this when an item is [a part of] a boolean expression { // Use this when an item is [a part of] a boolean expression
public: public:
Context_boolean() :Context(ANY_SUBST, INT_RESULT, &my_charset_bin) { } Context_boolean()
:Context(ANY_SUBST, &type_handler_longlong, &my_charset_bin) { }
}; };
}; };
......
...@@ -2791,7 +2791,7 @@ Item_func_case::Item_func_case(THD *thd, List<Item> &list, ...@@ -2791,7 +2791,7 @@ Item_func_case::Item_func_case(THD *thd, List<Item> &list,
Item_func_case_expression(thd), Item_func_case_expression(thd),
Predicant_to_list_comparator(thd, list.elements/*QQ*/), Predicant_to_list_comparator(thd, list.elements/*QQ*/),
first_expr_num(-1), else_expr_num(-1), first_expr_num(-1), else_expr_num(-1),
left_cmp_type(INT_RESULT), m_found_types(0) m_found_types(0)
{ {
ncases= list.elements; ncases= list.elements;
if (first_expr_arg) if (first_expr_arg)
...@@ -3057,7 +3057,6 @@ void Item_func_case::fix_length_and_dec() ...@@ -3057,7 +3057,6 @@ void Item_func_case::fix_length_and_dec()
} }
agg[0]= args[first_expr_num]; agg[0]= args[first_expr_num];
left_cmp_type= agg[0]->cmp_type();
/* /*
As the first expression and WHEN expressions As the first expression and WHEN expressions
...@@ -3119,6 +3118,7 @@ void Item_func_case::fix_length_and_dec() ...@@ -3119,6 +3118,7 @@ void Item_func_case::fix_length_and_dec()
Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{ {
const Type_handler *first_expr_cmp_handler;
if (first_expr_num == -1) if (first_expr_num == -1)
{ {
// None of the arguments are in a comparison context // None of the arguments are in a comparison context
...@@ -3126,6 +3126,7 @@ Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_ ...@@ -3126,6 +3126,7 @@ Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_
return this; return this;
} }
first_expr_cmp_handler= args[first_expr_num]->type_handler_for_comparison();
for (uint i= 0; i < arg_count; i++) for (uint i= 0; i < arg_count; i++)
{ {
/* /*
...@@ -3164,11 +3165,11 @@ Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_ ...@@ -3164,11 +3165,11 @@ Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_
WHEN 'str2' THEN TRUE WHEN 'str2' THEN TRUE
ELSE FALSE END; ELSE FALSE END;
*/ */
if (m_found_types == (1UL << left_cmp_type)) if (m_found_types == (1UL << first_expr_cmp_handler->cmp_type()))
new_item= args[i]->propagate_equal_fields(thd, new_item= args[i]->propagate_equal_fields(thd,
Context( Context(
ANY_SUBST, ANY_SUBST,
left_cmp_type, first_expr_cmp_handler,
cmp_collation.collation), cmp_collation.collation),
cond); cond);
} }
...@@ -3181,13 +3182,14 @@ Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_ ...@@ -3181,13 +3182,14 @@ Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_
replaced to zero-filled constants (only IDENTITY_SUBST allows this). replaced to zero-filled constants (only IDENTITY_SUBST allows this).
Such a change for WHEN arguments would require rebuilding cmp_items. Such a change for WHEN arguments would require rebuilding cmp_items.
*/ */
Item_result tmp_cmp_type= item_cmp_type(args[first_expr_num], args[i]); Type_handler_hybrid_field_type tmp(first_expr_cmp_handler);
new_item= args[i]->propagate_equal_fields(thd, if (!tmp.aggregate_for_comparison(args[i]->type_handler_for_comparison()))
Context( new_item= args[i]->propagate_equal_fields(thd,
ANY_SUBST, Context(
tmp_cmp_type, ANY_SUBST,
cmp_collation.collation), tmp.type_handler(),
cond); cmp_collation.collation),
cond);
} }
else // THEN and ELSE arguments (they are not in comparison) else // THEN and ELSE arguments (they are not in comparison)
{ {
......
...@@ -497,7 +497,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2_with_rev ...@@ -497,7 +497,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2_with_rev
{ {
Item_args::propagate_equal_fields(thd, Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST, Context(ANY_SUBST,
cmp.compare_type(), cmp.compare_type_handler(),
compare_collation()), compare_collation()),
cond); cond);
return this; return this;
...@@ -903,7 +903,7 @@ class Item_func_between :public Item_func_opt_neg ...@@ -903,7 +903,7 @@ class Item_func_between :public Item_func_opt_neg
{ {
Item_args::propagate_equal_fields(thd, Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST, Context(ANY_SUBST,
m_comparator.cmp_type(), m_comparator.type_handler(),
compare_collation()), compare_collation()),
cond); cond);
return this; return this;
...@@ -1229,7 +1229,8 @@ class Item_func_nullif :public Item_func_case_expression ...@@ -1229,7 +1229,8 @@ class Item_func_nullif :public Item_func_case_expression
bool is_null(); bool is_null();
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond) Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
{ {
Context cmpctx(ANY_SUBST, cmp.compare_type(), cmp.compare_collation()); Context cmpctx(ANY_SUBST, cmp.compare_type_handler(),
cmp.compare_collation());
const Item *old0= args[0]; const Item *old0= args[0];
args[0]->propagate_equal_fields_and_change_item_tree(thd, cmpctx, args[0]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
cond, &args[0]); cond, &args[0]);
...@@ -2039,7 +2040,6 @@ class Item_func_case :public Item_func_case_expression, ...@@ -2039,7 +2040,6 @@ class Item_func_case :public Item_func_case_expression,
public Predicant_to_list_comparator public Predicant_to_list_comparator
{ {
int first_expr_num, else_expr_num; int first_expr_num, else_expr_num;
enum Item_result left_cmp_type;
String tmp_value; String tmp_value;
uint ncases; uint ncases;
DTCollation cmp_collation; DTCollation cmp_collation;
...@@ -2216,14 +2216,14 @@ class Item_func_in :public Item_func_opt_neg, ...@@ -2216,14 +2216,14 @@ class Item_func_in :public Item_func_opt_neg,
*/ */
if (arg_types_compatible) if (arg_types_compatible)
{ {
Context cmpctx(ANY_SUBST, m_comparator.cmp_type(), Context cmpctx(ANY_SUBST, m_comparator.type_handler(),
Item_func_in::compare_collation()); Item_func_in::compare_collation());
args[0]->propagate_equal_fields_and_change_item_tree(thd, cmpctx, args[0]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
cond, &args[0]); cond, &args[0]);
} }
for (uint i= 0; i < comparator_count(); i++) for (uint i= 0; i < comparator_count(); i++)
{ {
Context cmpctx(ANY_SUBST, get_comparator_type_handler(i)->cmp_type(), Context cmpctx(ANY_SUBST, get_comparator_type_handler(i),
Item_func_in::compare_collation()); Item_func_in::compare_collation());
uint idx= get_comparator_arg_index(i); uint idx= get_comparator_arg_index(i);
args[idx]->propagate_equal_fields_and_change_item_tree(thd, cmpctx, args[idx]->propagate_equal_fields_and_change_item_tree(thd, cmpctx,
...@@ -2533,7 +2533,7 @@ class Item_func_like :public Item_bool_func2 ...@@ -2533,7 +2533,7 @@ class Item_func_like :public Item_bool_func2
if ((flags & MY_CS_NOPAD) && !(flags & MY_CS_NON1TO1)) if ((flags & MY_CS_NOPAD) && !(flags & MY_CS_NON1TO1))
Item_args::propagate_equal_fields(thd, Item_args::propagate_equal_fields(thd,
Context(ANY_SUBST, Context(ANY_SUBST,
STRING_RESULT, &type_handler_long_blob,
compare_collation()), compare_collation()),
cond); cond);
return this; return this;
......
...@@ -12987,7 +12987,7 @@ static bool check_row_equality(THD *thd, const Arg_comparator *comparators, ...@@ -12987,7 +12987,7 @@ static bool check_row_equality(THD *thd, const Arg_comparator *comparators,
const Arg_comparator *tmp= &comparators[i]; const Arg_comparator *tmp= &comparators[i];
is_converted= check_simple_equality(thd, is_converted= check_simple_equality(thd,
Item::Context(Item::ANY_SUBST, Item::Context(Item::ANY_SUBST,
tmp->compare_type(), tmp->compare_type_handler(),
tmp->compare_collation()), tmp->compare_collation()),
left_item, right_item, left_item, right_item,
cond_equal); cond_equal);
...@@ -13063,7 +13063,7 @@ bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal, ...@@ -13063,7 +13063,7 @@ bool Item_func_eq::check_equality(THD *thd, COND_EQUAL *cond_equal,
} }
return check_simple_equality(thd, return check_simple_equality(thd,
Context(ANY_SUBST, Context(ANY_SUBST,
compare_type_handler()->cmp_type(), compare_type_handler(),
compare_collation()), compare_collation()),
left_item, right_item, cond_equal); left_item, right_item, cond_equal);
} }
......
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