Commit dc25d600 authored by Alexander Barkov's avatar Alexander Barkov

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

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".
parent 267dd5a9
......@@ -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
......@@ -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
#
# 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
#
--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 #
......@@ -6215,7 +6215,17 @@ 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)
{
......@@ -6223,16 +6233,30 @@ void Regexp_processor_pcre::fix_owner(Item_func *owner,
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;
}
......@@ -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]);
}
......@@ -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]);
}
......
......@@ -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)
......
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