mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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 Adding helper methods: - String *Item::val_str_null_to_empty(String *to) - String *Item::val_str_null_to_empty(String *to, bool null_to_empty) and reusing these methods in both Item_func_replace and Item_func_regexp_replace.
This commit is contained in:
@ -1772,6 +1772,85 @@ Level Code Message
|
|||||||
Note 1003 select trim(both ' ' from 'a') AS "oracle_schema.TRIM(BOTH ' ' FROM 'a')"
|
Note 1003 select trim(both ' ' from 'a') AS "oracle_schema.TRIM(BOTH ' ' FROM 'a')"
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1003 select trim(both ' ' from 'a') AS "oracle_schema.TRIM(BOTH ' ' FROM 'a')"
|
Note 1003 select trim(both ' ' from 'a') AS "oracle_schema.TRIM(BOTH ' ' FROM 'a')"
|
||||||
|
CALL p3('REGEXP_REPLACE(''test'',''t'','''')');
|
||||||
|
----------
|
||||||
|
sql_mode='' qualifier=''
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT REGEXP_REPLACE('test','t','')
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 select regexp_replace('test','t','') AS `REGEXP_REPLACE('test','t','')`
|
||||||
|
----------
|
||||||
|
sql_mode='' qualifier='unknown_schema.'
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT unknown_schema.REGEXP_REPLACE('test','t','')
|
||||||
|
errmsg
|
||||||
|
ERROR: FUNCTION unknown_schema.REGEXP_REPLACE does not exist
|
||||||
|
----------
|
||||||
|
sql_mode='' qualifier='mariadb_schema.'
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT mariadb_schema.REGEXP_REPLACE('test','t','')
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 select regexp_replace('test','t','') AS `mariadb_schema.REGEXP_REPLACE('test','t','')`
|
||||||
|
----------
|
||||||
|
sql_mode='' qualifier='maxdb_schema.'
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT maxdb_schema.REGEXP_REPLACE('test','t','')
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 select regexp_replace('test','t','') AS `maxdb_schema.REGEXP_REPLACE('test','t','')`
|
||||||
|
----------
|
||||||
|
sql_mode='' qualifier='oracle_schema.'
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT oracle_schema.REGEXP_REPLACE('test','t','')
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 select oracle_schema.regexp_replace('test','t','') AS `oracle_schema.REGEXP_REPLACE('test','t','')`
|
||||||
|
----------
|
||||||
|
sql_mode='ORACLE' qualifier=''
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT REGEXP_REPLACE('test','t','')
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 select regexp_replace('test','t','') AS "REGEXP_REPLACE('test','t','')"
|
||||||
|
----------
|
||||||
|
sql_mode='ORACLE' qualifier='unknown_schema.'
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT unknown_schema.REGEXP_REPLACE('test','t','')
|
||||||
|
errmsg
|
||||||
|
ERROR: FUNCTION unknown_schema.REGEXP_REPLACE does not exist
|
||||||
|
----------
|
||||||
|
sql_mode='ORACLE' qualifier='mariadb_schema.'
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT mariadb_schema.REGEXP_REPLACE('test','t','')
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 select mariadb_schema.regexp_replace('test','t','') AS "mariadb_schema.REGEXP_REPLACE('test','t','')"
|
||||||
|
----------
|
||||||
|
sql_mode='ORACLE' qualifier='maxdb_schema.'
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT maxdb_schema.REGEXP_REPLACE('test','t','')
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 select mariadb_schema.regexp_replace('test','t','') AS "maxdb_schema.REGEXP_REPLACE('test','t','')"
|
||||||
|
----------
|
||||||
|
sql_mode='ORACLE' qualifier='oracle_schema.'
|
||||||
|
query
|
||||||
|
EXPLAIN EXTENDED SELECT oracle_schema.REGEXP_REPLACE('test','t','')
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Level Code Message
|
||||||
|
Note 1003 select regexp_replace('test','t','') AS "oracle_schema.REGEXP_REPLACE('test','t','')"
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select regexp_replace('test','t','') AS "oracle_schema.REGEXP_REPLACE('test','t','')"
|
||||||
CALL p3('CONCAT_OPERATOR_ORACLE(''a'')');
|
CALL p3('CONCAT_OPERATOR_ORACLE(''a'')');
|
||||||
----------
|
----------
|
||||||
sql_mode='' qualifier=''
|
sql_mode='' qualifier=''
|
||||||
|
34
mysql-test/suite/compat/oracle/r/func_regexp_replace.result
Normal file
34
mysql-test/suite/compat/oracle/r/func_regexp_replace.result
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
SET sql_mode=ORACLE;
|
||||||
|
#
|
||||||
|
# MDEV-29095 REGEXP_REPLACE treats empty strings different than REPLACE in ORACLE mode
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (replacement VARCHAR(10));
|
||||||
|
INSERT INTO t1 VALUES (NULL), ('');
|
||||||
|
SELECT replacement, REGEXP_REPLACE('abba','a',replacement) FROM t1 ORDER BY replacement;
|
||||||
|
replacement REGEXP_REPLACE('abba','a',replacement)
|
||||||
|
NULL bb
|
||||||
|
bb
|
||||||
|
DROP TABLE t1;
|
||||||
|
SELECT REGEXP_REPLACE('abba','a',null);
|
||||||
|
REGEXP_REPLACE('abba','a',null)
|
||||||
|
bb
|
||||||
|
EXPLAIN EXTENDED SELECT REPLACE('abba','a',null) ;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select replace('abba','a',NULL) AS "REPLACE('abba','a',null)"
|
||||||
|
CREATE VIEW v1 AS SELECT REPLACE('abba','a',null) ;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v1 CREATE VIEW "v1" AS select replace('abba','a',NULL) AS "REPLACE('abba','a',null)" latin1 latin1_swedish_ci
|
||||||
|
SELECT * FROM v1;
|
||||||
|
REPLACE('abba','a',null)
|
||||||
|
bb
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
View Create View character_set_client collation_connection
|
||||||
|
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select oracle_schema.replace('abba','a',NULL) AS `REPLACE('abba','a',null)` latin1 latin1_swedish_ci
|
||||||
|
SELECT * FROM v1;
|
||||||
|
REPLACE('abba','a',null)
|
||||||
|
bb
|
||||||
|
DROP VIEW v1;
|
@ -165,6 +165,7 @@ CALL p3('TRIM(1,2)');
|
|||||||
CALL p3('TRIM(''a'')');
|
CALL p3('TRIM(''a'')');
|
||||||
CALL p3('TRIM(BOTH '' '' FROM ''a'')');
|
CALL p3('TRIM(BOTH '' '' FROM ''a'')');
|
||||||
|
|
||||||
|
CALL p3('REGEXP_REPLACE(''test'',''t'','''')');
|
||||||
|
|
||||||
# Deprecated compatibility XXX_ORACLE functions.
|
# Deprecated compatibility XXX_ORACLE functions.
|
||||||
# These functions are implemented as simple native functions
|
# These functions are implemented as simple native functions
|
||||||
|
26
mysql-test/suite/compat/oracle/t/func_regexp_replace.test
Normal file
26
mysql-test/suite/compat/oracle/t/func_regexp_replace.test
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
SET sql_mode=ORACLE;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-29095 REGEXP_REPLACE treats empty strings different than REPLACE in ORACLE mode
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
#SELECT REGEXP_REPLACE(null,'a','b') ;
|
||||||
|
#SELECT REGEXP_REPLACE('ab',null,'b') ;
|
||||||
|
#SELECT REGEXP_REPLACE('ab','a',null) ;
|
||||||
|
#SELECT REGEXP_REPLACE('ab',null,null) ;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (replacement VARCHAR(10));
|
||||||
|
INSERT INTO t1 VALUES (NULL), ('');
|
||||||
|
SELECT replacement, REGEXP_REPLACE('abba','a',replacement) FROM t1 ORDER BY replacement;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
SELECT REGEXP_REPLACE('abba','a',null);
|
||||||
|
EXPLAIN EXTENDED SELECT REPLACE('abba','a',null) ;
|
||||||
|
|
||||||
|
CREATE VIEW v1 AS SELECT REPLACE('abba','a',null) ;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
SET sql_mode=DEFAULT;
|
||||||
|
SHOW CREATE VIEW v1;
|
||||||
|
SELECT * FROM v1;
|
||||||
|
DROP VIEW v1;
|
13
sql/item.h
13
sql/item.h
@ -904,6 +904,19 @@ public:
|
|||||||
expressions with subqueries in the ORDER/GROUP clauses.
|
expressions with subqueries in the ORDER/GROUP clauses.
|
||||||
*/
|
*/
|
||||||
String *val_str() { return val_str(&str_value); }
|
String *val_str() { return val_str(&str_value); }
|
||||||
|
String *val_str_null_to_empty(String *to)
|
||||||
|
{
|
||||||
|
String *res= val_str(to);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
to->set_charset(collation.collation);
|
||||||
|
to->length(0);
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
String *val_str_null_to_empty(String *to, bool null_to_empty)
|
||||||
|
{
|
||||||
|
return null_to_empty ? val_str_null_to_empty(to) : val_str(to);
|
||||||
|
}
|
||||||
virtual Item_func *get_item_func() { return NULL; }
|
virtual Item_func *get_item_func() { return NULL; }
|
||||||
|
|
||||||
const MY_LOCALE *locale_from_val_str();
|
const MY_LOCALE *locale_from_val_str();
|
||||||
|
@ -2666,7 +2666,10 @@ protected:
|
|||||||
class Create_func_regexp_replace : public Create_func_arg3
|
class Create_func_regexp_replace : public Create_func_arg3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
|
Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) override
|
||||||
|
{
|
||||||
|
return new (thd->mem_root) Item_func_regexp_replace(thd, arg1, arg2, arg3);
|
||||||
|
}
|
||||||
|
|
||||||
static Create_func_regexp_replace s_singleton;
|
static Create_func_regexp_replace s_singleton;
|
||||||
|
|
||||||
@ -2675,6 +2678,28 @@ protected:
|
|||||||
virtual ~Create_func_regexp_replace() = default;
|
virtual ~Create_func_regexp_replace() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Create_func_regexp_replace Create_func_regexp_replace::s_singleton;
|
||||||
|
|
||||||
|
|
||||||
|
class Create_func_regexp_replace_oracle : public Create_func_arg3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3) override
|
||||||
|
{
|
||||||
|
return new (thd->mem_root) Item_func_regexp_replace_oracle(thd, arg1,
|
||||||
|
arg2, arg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Create_func_regexp_replace_oracle s_singleton;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Create_func_regexp_replace_oracle() = default;
|
||||||
|
virtual ~Create_func_regexp_replace_oracle() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
Create_func_regexp_replace_oracle
|
||||||
|
Create_func_regexp_replace_oracle::s_singleton;
|
||||||
|
|
||||||
|
|
||||||
class Create_func_regexp_substr : public Create_func_arg2
|
class Create_func_regexp_substr : public Create_func_arg2
|
||||||
{
|
{
|
||||||
@ -6464,15 +6489,6 @@ Create_func_regexp_instr::create_2_arg(THD *thd, Item *arg1, Item *arg2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Create_func_regexp_replace Create_func_regexp_replace::s_singleton;
|
|
||||||
|
|
||||||
Item*
|
|
||||||
Create_func_regexp_replace::create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3)
|
|
||||||
{
|
|
||||||
return new (thd->mem_root) Item_func_regexp_replace(thd, arg1, arg2, arg3);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Create_func_regexp_substr Create_func_regexp_substr::s_singleton;
|
Create_func_regexp_substr Create_func_regexp_substr::s_singleton;
|
||||||
|
|
||||||
Item*
|
Item*
|
||||||
@ -7616,6 +7632,8 @@ const Native_func_registry func_array_oracle_overrides[] =
|
|||||||
{ { STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_char_length)},
|
{ { STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_char_length)},
|
||||||
{ { STRING_WITH_LEN("LPAD") }, BUILDER(Create_func_lpad_oracle)},
|
{ { STRING_WITH_LEN("LPAD") }, BUILDER(Create_func_lpad_oracle)},
|
||||||
{ { STRING_WITH_LEN("LTRIM") }, BUILDER(Create_func_ltrim_oracle)},
|
{ { STRING_WITH_LEN("LTRIM") }, BUILDER(Create_func_ltrim_oracle)},
|
||||||
|
{ { STRING_WITH_LEN("REGEXP_REPLACE") },
|
||||||
|
BUILDER(Create_func_regexp_replace_oracle)},
|
||||||
{ { STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad_oracle)},
|
{ { STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad_oracle)},
|
||||||
{ { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim_oracle)},
|
{ { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim_oracle)},
|
||||||
|
|
||||||
|
@ -1149,8 +1149,7 @@ bool Item_func_reverse::fix_length_and_dec()
|
|||||||
Fix that this works with binary strings when using USE_MB
|
Fix that this works with binary strings when using USE_MB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String *Item_func_replace::val_str_internal(String *str,
|
String *Item_func_replace::val_str_internal(String *str, bool null_to_empty)
|
||||||
String *empty_string_for_null)
|
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
String *res,*res2,*res3;
|
String *res,*res2,*res3;
|
||||||
@ -1168,13 +1167,8 @@ String *Item_func_replace::val_str_internal(String *str,
|
|||||||
res=args[0]->val_str(str);
|
res=args[0]->val_str(str);
|
||||||
if (args[0]->null_value)
|
if (args[0]->null_value)
|
||||||
goto null;
|
goto null;
|
||||||
res2=args[1]->val_str(&tmp_value);
|
if (!(res2= args[1]->val_str_null_to_empty(&tmp_value, null_to_empty)))
|
||||||
if (args[1]->null_value)
|
goto null;
|
||||||
{
|
|
||||||
if (!empty_string_for_null)
|
|
||||||
goto null;
|
|
||||||
res2= empty_string_for_null;
|
|
||||||
}
|
|
||||||
res->set_charset(collation.collation);
|
res->set_charset(collation.collation);
|
||||||
|
|
||||||
#ifdef USE_MB
|
#ifdef USE_MB
|
||||||
@ -1191,12 +1185,8 @@ String *Item_func_replace::val_str_internal(String *str,
|
|||||||
if (binary_cmp && (offset=res->strstr(*res2)) < 0)
|
if (binary_cmp && (offset=res->strstr(*res2)) < 0)
|
||||||
return res;
|
return res;
|
||||||
#endif
|
#endif
|
||||||
if (!(res3=args[2]->val_str(&tmp_value2)))
|
if (!(res3= args[2]->val_str_null_to_empty(&tmp_value2, null_to_empty)))
|
||||||
{
|
goto null;
|
||||||
if (!empty_string_for_null)
|
|
||||||
goto null;
|
|
||||||
res3= empty_string_for_null;
|
|
||||||
}
|
|
||||||
from_length= res2->length();
|
from_length= res2->length();
|
||||||
to_length= res3->length();
|
to_length= res3->length();
|
||||||
|
|
||||||
@ -1279,7 +1269,7 @@ redo:
|
|||||||
}
|
}
|
||||||
while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
|
while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
|
||||||
}
|
}
|
||||||
if (empty_string_for_null && !res->length())
|
if (null_to_empty && !res->length())
|
||||||
goto null;
|
goto null;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -1385,20 +1375,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);
|
DBUG_ASSERT(fixed == 1);
|
||||||
char buff0[MAX_FIELD_WIDTH];
|
char buff0[MAX_FIELD_WIDTH];
|
||||||
char buff2[MAX_FIELD_WIDTH];
|
char buff2[MAX_FIELD_WIDTH];
|
||||||
String tmp0(buff0,sizeof(buff0),&my_charset_bin);
|
String tmp0(buff0,sizeof(buff0),&my_charset_bin);
|
||||||
String tmp2(buff2,sizeof(buff2),&my_charset_bin);
|
String tmp2(buff2,sizeof(buff2),&my_charset_bin);
|
||||||
String *source= args[0]->val_str(&tmp0);
|
String *source, *replace;
|
||||||
String *replace= args[2]->val_str(&tmp2);
|
|
||||||
LEX_CSTRING src, rpl;
|
LEX_CSTRING src, rpl;
|
||||||
int startoffset= 0;
|
int startoffset= 0;
|
||||||
|
|
||||||
if ((null_value= (args[0]->null_value || args[2]->null_value ||
|
if ((null_value=
|
||||||
re.recompile(args[1]))))
|
(!(source= args[0]->val_str(&tmp0)) ||
|
||||||
|
!(replace= args[2]->val_str_null_to_empty(&tmp2, null_to_empty)) ||
|
||||||
|
re.recompile(args[1]))))
|
||||||
return (String *) 0;
|
return (String *) 0;
|
||||||
|
|
||||||
if (!(source= re.convert_if_needed(source, &re.subject_converter)) ||
|
if (!(source= re.convert_if_needed(source, &re.subject_converter)) ||
|
||||||
|
@ -353,12 +353,13 @@ public:
|
|||||||
class Item_func_replace :public Item_str_func
|
class Item_func_replace :public Item_str_func
|
||||||
{
|
{
|
||||||
String tmp_value,tmp_value2;
|
String tmp_value,tmp_value2;
|
||||||
|
protected:
|
||||||
|
String *val_str_internal(String *str, bool null_to_empty);
|
||||||
public:
|
public:
|
||||||
Item_func_replace(THD *thd, Item *org, Item *find, Item *replace):
|
Item_func_replace(THD *thd, Item *org, Item *find, Item *replace):
|
||||||
Item_str_func(thd, org, find, replace) {}
|
Item_str_func(thd, org, find, replace) {}
|
||||||
String *val_str(String *to) { return val_str_internal(to, NULL); };
|
String *val_str(String *to) { return val_str_internal(to, false); };
|
||||||
bool fix_length_and_dec();
|
bool fix_length_and_dec();
|
||||||
String *val_str_internal(String *str, String *empty_string_for_null);
|
|
||||||
const Schema *schema() const { return &mariadb_schema; }
|
const Schema *schema() const { return &mariadb_schema; }
|
||||||
void print(String *str, enum_query_type query_type)
|
void print(String *str, enum_query_type query_type)
|
||||||
{
|
{
|
||||||
@ -377,7 +378,7 @@ class Item_func_replace_oracle :public Item_func_replace
|
|||||||
public:
|
public:
|
||||||
Item_func_replace_oracle(THD *thd, Item *org, Item *find, Item *replace):
|
Item_func_replace_oracle(THD *thd, Item *org, Item *find, Item *replace):
|
||||||
Item_func_replace(thd, org, find, replace) {}
|
Item_func_replace(thd, org, find, replace) {}
|
||||||
String *val_str(String *to) { return val_str_internal(to, &tmp_emtpystr); };
|
String *val_str(String *to) { return val_str_internal(to, true); };
|
||||||
const Schema *schema() const { return &oracle_schema_ref; }
|
const Schema *schema() const { return &oracle_schema_ref; }
|
||||||
void print(String *str, enum_query_type query_type)
|
void print(String *str, enum_query_type query_type)
|
||||||
{
|
{
|
||||||
@ -401,10 +402,18 @@ class Item_func_regexp_replace :public Item_str_func
|
|||||||
bool append_replacement(String *str,
|
bool append_replacement(String *str,
|
||||||
const LEX_CSTRING *source,
|
const LEX_CSTRING *source,
|
||||||
const LEX_CSTRING *replace);
|
const LEX_CSTRING *replace);
|
||||||
|
protected:
|
||||||
|
String *val_str_internal(String *str, bool null_to_empty);
|
||||||
public:
|
public:
|
||||||
Item_func_regexp_replace(THD *thd, Item *a, Item *b, Item *c):
|
Item_func_regexp_replace(THD *thd, Item *a, Item *b, Item *c):
|
||||||
Item_str_func(thd, a, b, c)
|
Item_str_func(thd, a, b, c)
|
||||||
{}
|
{}
|
||||||
|
const Schema *schema() const { return &mariadb_schema; }
|
||||||
|
void print(String *str, enum_query_type query_type)
|
||||||
|
{
|
||||||
|
print_sql_mode_qualified_name(str, query_type);
|
||||||
|
print_args_parenthesized(str, query_type);
|
||||||
|
}
|
||||||
void cleanup()
|
void cleanup()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_func_regex::cleanup");
|
DBUG_ENTER("Item_func_regex::cleanup");
|
||||||
@ -412,7 +421,10 @@ public:
|
|||||||
re.cleanup();
|
re.cleanup();
|
||||||
DBUG_VOID_RETURN;
|
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_fields(THD *thd, Item **ref);
|
||||||
bool fix_length_and_dec();
|
bool fix_length_and_dec();
|
||||||
const char *func_name() const { return "regexp_replace"; }
|
const char *func_name() const { return "regexp_replace"; }
|
||||||
@ -420,6 +432,26 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Item_func_regexp_substr :public Item_str_func
|
class Item_func_regexp_substr :public Item_str_func
|
||||||
{
|
{
|
||||||
Regexp_processor_pcre re;
|
Regexp_processor_pcre re;
|
||||||
|
Reference in New Issue
Block a user