maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #13065
Re: 99e2a49acfc: MDEV-27018 IF and COALESCE lose "json" property
Hi, Alexander!
On Jan 17, Alexander Barkov wrote:
> >> diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
> >> index ddf5fc32ea4..81003be4656 100644
> >> --- a/sql/item_jsonfunc.cc
> >> +++ b/sql/item_jsonfunc.cc
> >> @@ -1441,6 +1441,32 @@ longlong Item_func_json_contains_path::val_int()
...
> >> +static bool is_json_type(const Item *item)
> >> +{
> >> + for ( ; ; )
> >> + {
> >> + if (Type_handler_json_common::is_json_type_handler(item->type_handler()))
> >> + return true;
> >> + const Item_func_conv_charset *func;
> >> + if (!(func= dynamic_cast<const Item_func_conv_charset*>(item)))
> >> + return false;
> >> + item= func->arguments()[0];
> >
> > can you have nested CONVERT()'s ?
>
> We cannot have auto-generated nested CONVERT().
>
> The new code just reproduces the old behavior:
> Item_func_conv_charset::is_json_type() traversed
> through all Item_func_conv_charset's recursively.
>
> As the comment says, this is probably not correct.
> Let's fix it under terms of a separate MDEV.
> I can file an MDEV about this.
please, do
> >> diff --git a/sql/sql_type.cc b/sql/sql_type.cc
> >> index c1801c1ae3e..3b2753d80a6 100644
> >> --- a/sql/sql_type.cc
> >> +++ b/sql/sql_type.cc
> >> @@ -1755,19 +1755,110 @@ const Type_handler *Type_handler_typelib::cast_to_int_type_handler() const
> >>
> >> /***************************************************************************/
> >>
> >> +class Recursive_type_pair_iterator
> >> +{
> >> + const Type_handler *m_a;
> >> + const Type_handler *m_b;
> >> + uint m_switched_to_base_count;
> >> +public:
> >> + Recursive_type_pair_iterator(const Type_handler *a,
> >> + const Type_handler *b,
> >> + uint switched_to_base_count= 0)
> >> + :m_a(a), m_b(b), m_switched_to_base_count(switched_to_base_count)
> >> + { }
> >> + const Type_handler *a() const { return m_a; }
> >> + const Type_handler *b() const { return m_b; }
> >> + Recursive_type_pair_iterator base() const
> >> + {
> >> + Recursive_type_pair_iterator res(m_a->type_handler_base(),
> >> + m_b->type_handler_base());
> >> + res.m_switched_to_base_count= (res.m_a != NULL) + (res.m_b != NULL);
> >> + if (res.m_a == NULL)
> >> + res.m_a= m_a;
> >> + if (res.m_b == NULL)
> >> + res.m_b= m_b;
> >> + return res;
> >
> > that's an unusual semantics, not what I would expect from an iterator.
> > It'd expect it to iterare with it++; or it.next(); but not it = it.base();
>
> I agree it did not look nice.
>
> I replaced Recursive_type_pair_iterator to a more
> generic new class:
>
> class Type_handler_pair
> {
> const Type_handler *m_a;
> const Type_handler *m_b;
> ...
> };
why did you do it this way? You create an object. Then in the loop you
create a new object, copying the old one. Then you conditionally assign
m_a->type_handler_base(). Then you diff then to see if any condition
from the previous step has succeeded.
Why not, like
class Type_handler_pair {
bool up() {
bool r=false;
n_a=m_a->type_handler_base();
n_b=m_b->type_handler_base();
if (n_a) { m_a=n_a; r=true; }
if (n_b) { m_a=n_b; r=true; }
return r;
}
and later
do {
...
} while (tp.up());
also don't forget to update the commit comment, it still says
"Recursive_type_pair_iterator".
> >> + }
Regards,
Sergei
VP of MariaDB Server Engineering
and security@xxxxxxxxxxx
Follow ups
References