Skip to content

Commit

Permalink
MDEV-21058 CREATE TABLE with generated column and RLIKE results in si…
Browse files Browse the repository at this point in the history
…gabrt

Regexp_processor_pcre::fix_owner() called Regexp_processor_pcre::compile(),
which could fail on the regex syntax error in the pattern and put
an error into the diagnostics area. However, the callers:
  - Item_func_regex::fix_length_and_dec()
  - Item_func_regexp_instr::fix_length_and_dec()
still returned "false" in such cases, which made the code
crash later inside Diagnostics_area::set_ok_status().

Fix:

- Change the return type of fix_onwer() from "void" to "bool"
  and return "true" whenever an error is put to the DA
  (e.g. on the syntax error in the pattern).
- Fixing fix_length_and_dec() of the mentioned Item_func_xxx
  classes to return "true" if fix_onwer() returned "true".
  • Loading branch information
abarkov committed Apr 29, 2024
1 parent 267dd5a commit dc25d60
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 9 deletions.
16 changes: 16 additions & 0 deletions mysql-test/main/func_regexp.result
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,20 @@ SELECT SUM(a.t) FROM (SELECT (c1 RLIKE c1) = (c0 IS NULL) as t FROM t0) as a;
SUM(a.t)
0
DROP TABLE t0;
#
# MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt
#
CREATE TABLE t1 (c0 INT);
INSERT INTO t1 VALUES (1),(2),(3);
SELECT ('' RLIKE '[') AS c1 FROM t1;
ERROR 42000: Regex error 'missing terminating ] for character class at offset 1'
SELECT REGEXP_INSTR('','[') AS c1 FROM t1;
ERROR 42000: Regex error 'missing terminating ] for character class at offset 1'
SELECT c0, '' RLIKE NULL AS c1, REGEXP_INSTR('', NULL) AS c2
FROM t1 ORDER BY c0;
c0 c1 c2
1 NULL NULL
2 NULL NULL
3 NULL NULL
DROP TABLE t1;
# End of 10.5 tests
17 changes: 17 additions & 0 deletions mysql-test/main/func_regexp.test
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,22 @@ SELECT (c1 RLIKE c1), (c0 IS NULL) FROM t0;
SELECT SUM(a.t) FROM (SELECT (c1 RLIKE c1) = (c0 IS NULL) as t FROM t0) as a;
DROP TABLE t0;

--echo #
--echo # MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt
--echo #

CREATE TABLE t1 (c0 INT);
INSERT INTO t1 VALUES (1),(2),(3);

--error ER_REGEXP_ERROR
SELECT ('' RLIKE '[') AS c1 FROM t1;

--error ER_REGEXP_ERROR
SELECT REGEXP_INSTR('','[') AS c1 FROM t1;

SELECT c0, '' RLIKE NULL AS c1, REGEXP_INSTR('', NULL) AS c2
FROM t1 ORDER BY c0;

DROP TABLE t1;

--echo # End of 10.5 tests
24 changes: 24 additions & 0 deletions mysql-test/suite/vcol/r/func_regexp.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# Start of 10.5 tests
#
#
# MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt
#
CREATE TABLE t1 (c0 INT AS(('' RLIKE '[')));
ERROR 42000: Regex error 'missing terminating ] for character class at offset 1'
CREATE TABLE t1 (c0 INT AS(REGEXP_INSTR('','[')));
ERROR 42000: Regex error 'missing terminating ] for character class at offset 1'
CREATE TABLE t1
(
c0 INT,
c1 INT AS(('' RLIKE NULL)),
c2 INT AS(REGEXP_INSTR('',NULL))
);
INSERT INTO t1 (c0) VALUES (0);
SELECT * FROM t1;
c0 c1 c2
0 NULL NULL
DROP TABLE t1;
#
# End of 10.5 tests
#
30 changes: 30 additions & 0 deletions mysql-test/suite/vcol/t/func_regexp.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
--source inc/vcol_init_vars.pre
--source inc/vcol_cleanup.inc

--echo #
--echo # Start of 10.5 tests
--echo #

--echo #
--echo # MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt
--echo #

--error ER_REGEXP_ERROR
CREATE TABLE t1 (c0 INT AS(('' RLIKE '[')));

--error ER_REGEXP_ERROR
CREATE TABLE t1 (c0 INT AS(REGEXP_INSTR('','[')));

CREATE TABLE t1
(
c0 INT,
c1 INT AS(('' RLIKE NULL)),
c2 INT AS(REGEXP_INSTR('',NULL))
);
INSERT INTO t1 (c0) VALUES (0);
SELECT * FROM t1;
DROP TABLE t1;

--echo #
--echo # End of 10.5 tests
--echo #
38 changes: 30 additions & 8 deletions sql/item_cmpfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6215,24 +6215,48 @@ bool Regexp_processor_pcre::exec(Item *item, int offset,
}


void Regexp_processor_pcre::fix_owner(Item_func *owner,
/*
This method determines the owner's maybe_null flag.
Generally, the result is NULL-able. However, in case
of a constant pattern and a NOT NULL subject, the
result can also be NOT NULL.
@return true - in case if the constant regex compilation failed
(e.g. due to a wrong regex syntax in the pattern).
The compilation error message is put to the DA in this case.
false - otherwise.
*/
bool Regexp_processor_pcre::fix_owner(Item_func *owner,
Item *subject_arg,
Item *pattern_arg)
{
if (!is_compiled() &&
pattern_arg->const_item() &&
!pattern_arg->is_expensive())
{
if (compile(pattern_arg, true))
if (compile(pattern_arg, true/* raise errors to DA, e.g. on bad syntax */))
{
owner->maybe_null= 1; // Will always return NULL
return;
owner->maybe_null= 1;
if (pattern_arg->null_value)
{
/*
The pattern evaluated to NULL. Regex compilation did not happen.
No errors were put to DA. Continue with maybe_null==true.
The function will return NULL per row.
*/
return false;
}
/*
A syntax error in the pattern, an error was raised to the DA.
Let's abort the query. The caller will send the error to the client.
*/
return true;
}
set_const(true);
owner->maybe_null= subject_arg->maybe_null;
}
else
owner->maybe_null= 1;
return false;
}


Expand All @@ -6244,8 +6268,7 @@ Item_func_regex::fix_length_and_dec()
return TRUE;

re.init(cmp_collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
return FALSE;
return re.fix_owner(this, args[0], args[1]);
}


Expand All @@ -6269,9 +6292,8 @@ Item_func_regexp_instr::fix_length_and_dec()
return TRUE;

re.init(cmp_collation.collation, 0);
re.fix_owner(this, args[0], args[1]);
max_length= MY_INT32_NUM_DECIMAL_DIGITS; // See also Item_func_locate
return FALSE;
return re.fix_owner(this, args[0], args[1]);
}


Expand Down
2 changes: 1 addition & 1 deletion sql/item_cmpfunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2893,7 +2893,7 @@ class Regexp_processor_pcre
{}
int default_regex_flags();
void init(CHARSET_INFO *data_charset, int extra_flags);
void fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg);
bool fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg);
bool compile(String *pattern, bool send_error);
bool compile(Item *item, bool send_error);
bool recompile(Item *item)
Expand Down

0 comments on commit dc25d60

Please sign in to comment.