Skip to content

Commit 8203931

Browse files
committed
BUG#35140271: Regex split hanging in cursor.execute(..., multi=True) for complex queries.
Performance degradation was induced while fixing `BUG#34655520: Wrong MySQLCursor.statement values in the results of cursor.execute(..., multi=True)`. With this patch, the performance issue is fixed. Change-Id: Ib8a35fb768ab5ecce8779de72bc720ffea47f7d8
1 parent e7a07be commit 8203931

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ v8.1.0
1919
- BUG#35338384: PIP installs incompatible Connector/Python packages
2020
- BUG#35318413: Fix charset mapping for MySQL 8.1.0
2121
- BUG#35212199: Check for identifier quotes in the database name
22+
- BUG#35140271: Regex split hanging in cursor.execute(..., multi=True) for complex queries
2223
- BUG#29115406: CONTRIBUTION - FIX RECV COMPRESS BUG
2324

2425
v8.0.33

lib/mysql/connector/cursor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@
9999
""",
100100
re.X,
101101
)
102-
RE_SQL_SPLIT_STMTS = re.compile(b""";(?=(?:[^"'`]*["'`].*["'`])*[^"'`]*$)""")
102+
RE_SQL_SPLIT_STMTS = re.compile(
103+
b""";(?=(?:[^"'`]*(?:"[^"]*"|'[^']*'|`[^`]*`))*[^"'`]*$)"""
104+
)
103105
RE_SQL_FIND_PARAM = re.compile(b"""%s(?=(?:[^"'`]*["'`][^"'`]*["'`])*[^"'`]*$)""")
104106
RE_SQL_PYTHON_REPLACE_PARAM = re.compile(r"%\(.*?\)s")
105107
RE_SQL_PYTHON_CAPTURE_PARAM_NAME = re.compile(r"%\((.*?)\)s")

tests/cext/test_cext_cursor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,8 @@ def test_execute_multi(self):
627627

628628
cur.close()
629629

630-
# test statement property
630+
# Bug#34655520: Wrong MySQLCursor.statement values in the results of
631+
# cursor.execute(..., multi=True)
631632
operations = [
632633
'select 1; SELECT "`";',
633634
"SELECT '\"'; SELECT 2; select '```';",

tests/test_cursor.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,9 @@ def test_execute(self):
630630

631631
def test_execute_multi(self):
632632
# Tests when execute(..., multi=True)
633+
634+
# Bug#34655520: Wrong MySQLCursor.statement values in the results of
635+
# cursor.execute(..., multi=True)
633636
operations = [
634637
'select 1; SELECT "`";',
635638
"SELECT '\"'; SELECT 2; select '```';",
@@ -647,6 +650,31 @@ def test_execute_multi(self):
647650
self.assertEqual(exp, res_cur.statement)
648651
_ = res_cur.fetchall()
649652

653+
# Bug#35140271: Regex split hanging in cursor.execute(..., multi=True)
654+
# for complex queries
655+
operations.append("SELECT `';`; select 3; SELECT '`;`;`';")
656+
control.append(["SELECT `';`", "select 3", "SELECT '`;`;`'"])
657+
for operation, exps in zip(operations, control):
658+
executed_list = cursor.RE_SQL_SPLIT_STMTS.split(operation.encode())
659+
self.assertEqual(len(executed_list), len(exps) + 1)
660+
661+
# the bug reports that execution hangs with the following statement;
662+
# let's run it and check it does not hang.
663+
RE_SQL_SPLIT_STMTS_OLD = re.compile(
664+
b""";(?=(?:[^"'`]*["'`][^"'`]*["'`])*[^"'`]*$)"""
665+
)
666+
operation = """
667+
create database test;\n create table
668+
test.test(pk INT PRIMARY KEY AUTO_INCREMENT, t CHAR(6));\n INSERT INTO
669+
test.test(t) VALUES ('h'), ('e'), ('l'), ('l'), ('o'), (' '), ('w'), ('o'),
670+
('r'), ('l'), ('d'), ('!'), (' '), ('h'), ('e'), ('l'), ('l'), ('o'), (' '),
671+
('w'), ('o'), ('r'), ('l'), ('d'), ('!'); \n -- insert db's elements
672+
"""
673+
self.assertListEqual(
674+
cursor.RE_SQL_SPLIT_STMTS.split(operation.encode()),
675+
RE_SQL_SPLIT_STMTS_OLD.split(operation.encode()),
676+
)
677+
650678
def test_executemany(self):
651679
"""MySQLCursor object executemany()-method"""
652680
self.check_method(self.cur, "executemany")

0 commit comments

Comments
 (0)