Hi, Alexander,

On Jan 10, Alexander Barkov wrote:
> revision-id: 9d6de9212d5 (mariadb-10.4.32-45-g9d6de9212d5)
> parent(s): bdfd93d30c1
> author: Alexander Barkov
> committer: Alexander Barkov
> timestamp: 2023-11-24 13:23:56 +0400
> message:
> 
> MDEV-29095 REGEXP_REPLACE treats empty strings different than REPLACE in 
> ORACLE mode
> 
> Turning REGEXP_REPLACE into two schema-qualified functions:
> - mariadb_schema.regexp_replace()
> - oracle_schema.regexp_replace()
> 
> Fixing oracle_schema.regexp_replace(subj,pattern,replacement) to treat
> NULL in "replacement" as an empty string.
> 
> Adding new classes implementing oracle_schema.regexp_replace():
> - Item_func_regexp_replace_oracle
> - Create_func_regexp_replace_oracle
> 
> diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
> index 92d5e196da4..b688ba97d3e 100644
> --- a/sql/item_strfunc.cc
> +++ b/sql/item_strfunc.cc
> @@ -1385,20 +1385,22 @@ bool 
> Item_func_regexp_replace::append_replacement(String *str,
>  }
>  
>  
> -String *Item_func_regexp_replace::val_str(String *str)
> +String *Item_func_regexp_replace::val_str_internal(String *str,
> +                                                   bool null_to_empty)
>  {
>    DBUG_ASSERT(fixed == 1);
>    char buff0[MAX_FIELD_WIDTH];
>    char buff2[MAX_FIELD_WIDTH];
>    String tmp0(buff0,sizeof(buff0),&my_charset_bin);
>    String tmp2(buff2,sizeof(buff2),&my_charset_bin);
> -  String *source= args[0]->val_str(&tmp0);
> -  String *replace= args[2]->val_str(&tmp2);
> +  String *source, *replace;
>    LEX_CSTRING src, rpl;
>    int startoffset= 0;
>  
> -  if ((null_value= (args[0]->null_value || args[2]->null_value ||
> -                    re.recompile(args[1]))))
> +  if ((null_value=
> +        (!(source= args[0]->val_str(&tmp0)) ||
> +         !(replace= args[2]->val_str_null_to_empty(&tmp2, null_to_empty)) ||

why are you fixing it differently from Item_func_replace?

If you think this approach is better then, please, change
Item_func_replace to use it too, in a followup commit.

> +         re.recompile(args[1]))))
>      return (String *) 0;
>  
>    if (!(source= re.convert_if_needed(source, &re.subject_converter)) ||
> diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
> index 826c7f784af..e014cc5fcbc 100644
> --- a/sql/item_strfunc.h
> +++ b/sql/item_strfunc.h
> @@ -412,11 +420,34 @@ class Item_func_regexp_replace :public Item_str_func
>      re.cleanup();
>      DBUG_VOID_RETURN;
>    }
> -  String *val_str(String *str);
> +  String *val_str(String *str)
> +  {
> +    return val_str_internal(str, false);
> +  }
>    bool fix_fields(THD *thd, Item **ref);
>    bool fix_length_and_dec();
>    const char *func_name() const { return "regexp_replace"; }
> -  Item *get_copy(THD *thd) { return 0;}
> +  Item *get_copy(THD *thd) { return 0;} // QQ: why?

you could've checked the history in git.
it was

  commit 343bcb152f8
  Author: Igor Babaev <i...@askmonty.org>
  Date:   Sun Nov 5 22:52:41 2017 -0800

      Fixed mdev-14237 Server crash on query with regexp_substr

      It's better to prohibit pushdown of conditions that involve
      regexp_substr() and regexp_replace() into materialized derived
      tables / views until proper implementations of the get_copy()
      virtual method are provided for those functions.

and I suspect the reason is Regexp_processor_pcre inside regexp Items.

> +};
> +
> +
> +class Item_func_regexp_replace_oracle: public Item_func_regexp_replace
> +{
> +public:
> +  Item_func_regexp_replace_oracle(THD *thd, Item *a, Item *b, Item *c)
> +   :Item_func_regexp_replace(thd, a, b, c)
> +  {}
> +  const Schema *schema() const { return &oracle_schema_ref; }
> +  bool fix_length_and_dec()
> +  {
> +    bool rc= Item_func_regexp_replace::fix_length_and_dec();
> +    maybe_null= true; // Empty result is converted to NULL
> +    return rc;
> +  }
> +  String *val_str(String *str)
> +  {
> +    return val_str_internal(str, true);
> +  }
>  };

Regards,
Sergei
Chief Architect, MariaDB Server
and secur...@mariadb.org
_______________________________________________
developers mailing list -- developers@lists.mariadb.org
To unsubscribe send an email to developers-le...@lists.mariadb.org

Reply via email to