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)
|
SUM(a.t)
|
||||||
0
|
0
|
||||||
DROP TABLE t0;
|
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
|
# 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;
|
SELECT SUM(a.t) FROM (SELECT (c1 RLIKE c1) = (c0 IS NULL) as t FROM t0) as a;
|
||||||
DROP TABLE t0;
|
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
|
--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 *subject_arg,
|
||||||
Item *pattern_arg)
|
Item *pattern_arg)
|
||||||
{
|
{
|
||||||
@ -6223,16 +6233,30 @@ void Regexp_processor_pcre::fix_owner(Item_func *owner,
|
|||||||
pattern_arg->const_item() &&
|
pattern_arg->const_item() &&
|
||||||
!pattern_arg->is_expensive())
|
!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
|
owner->maybe_null= 1;
|
||||||
return;
|
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);
|
set_const(true);
|
||||||
owner->maybe_null= subject_arg->maybe_null;
|
owner->maybe_null= subject_arg->maybe_null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
owner->maybe_null= 1;
|
owner->maybe_null= 1;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6244,8 +6268,7 @@ Item_func_regex::fix_length_and_dec()
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
re.init(cmp_collation.collation, 0);
|
re.init(cmp_collation.collation, 0);
|
||||||
re.fix_owner(this, args[0], args[1]);
|
return re.fix_owner(this, args[0], args[1]);
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6269,9 +6292,8 @@ Item_func_regexp_instr::fix_length_and_dec()
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
re.init(cmp_collation.collation, 0);
|
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
|
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();
|
int default_regex_flags();
|
||||||
void init(CHARSET_INFO *data_charset, int extra_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(String *pattern, bool send_error);
|
||||||
bool compile(Item *item, bool send_error);
|
bool compile(Item *item, bool send_error);
|
||||||
bool recompile(Item *item)
|
bool recompile(Item *item)
|
||||||
|
Reference in New Issue
Block a user