Skip to content

Commit dc25d60

Browse files
committed
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".
1 parent 267dd5a commit dc25d60

File tree

6 files changed

+118
-9
lines changed

6 files changed

+118
-9
lines changed

mysql-test/main/func_regexp.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,4 +192,20 @@ SELECT SUM(a.t) FROM (SELECT (c1 RLIKE c1) = (c0 IS NULL) as t FROM t0) as a;
192192
SUM(a.t)
193193
0
194194
DROP TABLE t0;
195+
#
196+
# MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt
197+
#
198+
CREATE TABLE t1 (c0 INT);
199+
INSERT INTO t1 VALUES (1),(2),(3);
200+
SELECT ('' RLIKE '[') AS c1 FROM t1;
201+
ERROR 42000: Regex error 'missing terminating ] for character class at offset 1'
202+
SELECT REGEXP_INSTR('','[') AS c1 FROM t1;
203+
ERROR 42000: Regex error 'missing terminating ] for character class at offset 1'
204+
SELECT c0, '' RLIKE NULL AS c1, REGEXP_INSTR('', NULL) AS c2
205+
FROM t1 ORDER BY c0;
206+
c0 c1 c2
207+
1 NULL NULL
208+
2 NULL NULL
209+
3 NULL NULL
210+
DROP TABLE t1;
195211
# End of 10.5 tests

mysql-test/main/func_regexp.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,22 @@ SELECT (c1 RLIKE c1), (c0 IS NULL) FROM t0;
132132
SELECT SUM(a.t) FROM (SELECT (c1 RLIKE c1) = (c0 IS NULL) as t FROM t0) as a;
133133
DROP TABLE t0;
134134

135+
--echo #
136+
--echo # MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt
137+
--echo #
138+
139+
CREATE TABLE t1 (c0 INT);
140+
INSERT INTO t1 VALUES (1),(2),(3);
141+
142+
--error ER_REGEXP_ERROR
143+
SELECT ('' RLIKE '[') AS c1 FROM t1;
144+
145+
--error ER_REGEXP_ERROR
146+
SELECT REGEXP_INSTR('','[') AS c1 FROM t1;
147+
148+
SELECT c0, '' RLIKE NULL AS c1, REGEXP_INSTR('', NULL) AS c2
149+
FROM t1 ORDER BY c0;
150+
151+
DROP TABLE t1;
135152

136153
--echo # End of 10.5 tests
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#
2+
# Start of 10.5 tests
3+
#
4+
#
5+
# MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt
6+
#
7+
CREATE TABLE t1 (c0 INT AS(('' RLIKE '[')));
8+
ERROR 42000: Regex error 'missing terminating ] for character class at offset 1'
9+
CREATE TABLE t1 (c0 INT AS(REGEXP_INSTR('','[')));
10+
ERROR 42000: Regex error 'missing terminating ] for character class at offset 1'
11+
CREATE TABLE t1
12+
(
13+
c0 INT,
14+
c1 INT AS(('' RLIKE NULL)),
15+
c2 INT AS(REGEXP_INSTR('',NULL))
16+
);
17+
INSERT INTO t1 (c0) VALUES (0);
18+
SELECT * FROM t1;
19+
c0 c1 c2
20+
0 NULL NULL
21+
DROP TABLE t1;
22+
#
23+
# End of 10.5 tests
24+
#
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--source inc/vcol_init_vars.pre
2+
--source inc/vcol_cleanup.inc
3+
4+
--echo #
5+
--echo # Start of 10.5 tests
6+
--echo #
7+
8+
--echo #
9+
--echo # MDEV-21058 CREATE TABLE with generated column and RLIKE results in sigabrt
10+
--echo #
11+
12+
--error ER_REGEXP_ERROR
13+
CREATE TABLE t1 (c0 INT AS(('' RLIKE '[')));
14+
15+
--error ER_REGEXP_ERROR
16+
CREATE TABLE t1 (c0 INT AS(REGEXP_INSTR('','[')));
17+
18+
CREATE TABLE t1
19+
(
20+
c0 INT,
21+
c1 INT AS(('' RLIKE NULL)),
22+
c2 INT AS(REGEXP_INSTR('',NULL))
23+
);
24+
INSERT INTO t1 (c0) VALUES (0);
25+
SELECT * FROM t1;
26+
DROP TABLE t1;
27+
28+
--echo #
29+
--echo # End of 10.5 tests
30+
--echo #

sql/item_cmpfunc.cc

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6215,24 +6215,48 @@ bool Regexp_processor_pcre::exec(Item *item, int offset,
62156215
}
62166216

62176217

6218-
void Regexp_processor_pcre::fix_owner(Item_func *owner,
6218+
/*
6219+
This method determines the owner's maybe_null flag.
6220+
Generally, the result is NULL-able. However, in case
6221+
of a constant pattern and a NOT NULL subject, the
6222+
result can also be NOT NULL.
6223+
@return true - in case if the constant regex compilation failed
6224+
(e.g. due to a wrong regex syntax in the pattern).
6225+
The compilation error message is put to the DA in this case.
6226+
false - otherwise.
6227+
*/
6228+
bool Regexp_processor_pcre::fix_owner(Item_func *owner,
62196229
Item *subject_arg,
62206230
Item *pattern_arg)
62216231
{
62226232
if (!is_compiled() &&
62236233
pattern_arg->const_item() &&
62246234
!pattern_arg->is_expensive())
62256235
{
6226-
if (compile(pattern_arg, true))
6236+
if (compile(pattern_arg, true/* raise errors to DA, e.g. on bad syntax */))
62276237
{
6228-
owner->maybe_null= 1; // Will always return NULL
6229-
return;
6238+
owner->maybe_null= 1;
6239+
if (pattern_arg->null_value)
6240+
{
6241+
/*
6242+
The pattern evaluated to NULL. Regex compilation did not happen.
6243+
No errors were put to DA. Continue with maybe_null==true.
6244+
The function will return NULL per row.
6245+
*/
6246+
return false;
6247+
}
6248+
/*
6249+
A syntax error in the pattern, an error was raised to the DA.
6250+
Let's abort the query. The caller will send the error to the client.
6251+
*/
6252+
return true;
62306253
}
62316254
set_const(true);
62326255
owner->maybe_null= subject_arg->maybe_null;
62336256
}
62346257
else
62356258
owner->maybe_null= 1;
6259+
return false;
62366260
}
62376261

62386262

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

62466270
re.init(cmp_collation.collation, 0);
6247-
re.fix_owner(this, args[0], args[1]);
6248-
return FALSE;
6271+
return re.fix_owner(this, args[0], args[1]);
62496272
}
62506273

62516274

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

62716294
re.init(cmp_collation.collation, 0);
6272-
re.fix_owner(this, args[0], args[1]);
62736295
max_length= MY_INT32_NUM_DECIMAL_DIGITS; // See also Item_func_locate
6274-
return FALSE;
6296+
return re.fix_owner(this, args[0], args[1]);
62756297
}
62766298

62776299

sql/item_cmpfunc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2893,7 +2893,7 @@ class Regexp_processor_pcre
28932893
{}
28942894
int default_regex_flags();
28952895
void init(CHARSET_INFO *data_charset, int extra_flags);
2896-
void fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg);
2896+
bool fix_owner(Item_func *owner, Item *subject_arg, Item *pattern_arg);
28972897
bool compile(String *pattern, bool send_error);
28982898
bool compile(Item *item, bool send_error);
28992899
bool recompile(Item *item)

0 commit comments

Comments
 (0)