mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
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".
This commit is contained in:
@ -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
|
||||
|
24
mysql-test/suite/vcol/r/func_regexp.result
Normal file
24
mysql-test/suite/vcol/r/func_regexp.result
Normal file
@ -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
mysql-test/suite/vcol/t/func_regexp.test
Normal file
30
mysql-test/suite/vcol/t/func_regexp.test
Normal file
@ -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 #
|
@ -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 @@ public:
|
||||
{}
|
||||
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)
|
||||
|
Reference in New Issue
Block a user