fix: Update regex for capturing touched tables from query (#7588)
Previous regex used to yield false positives and false negatives for queries like UPDATE tabToDo SET description = "something" Instead of yielding "tabToDo" it used to yield "tabToDo SET". Now two separate regexes handle single word and multi-word names In case of multi-word surrounding quotes are a must
This commit is contained in:
parent
9053a4374d
commit
2c93dc74fe
2 changed files with 23 additions and 3 deletions
|
|
@ -930,12 +930,26 @@ class Database(object):
|
|||
if values:
|
||||
query = frappe.safe_decode(self._cursor.mogrify(query, values))
|
||||
if query.strip().lower().split()[0] in ('insert', 'delete', 'update', 'alter'):
|
||||
# ([`\"']?) Captures ', " or ` at the begining of the table name (if provided)
|
||||
# single_word_regex is designed to match following patterns
|
||||
# `tabXxx`, tabXxx and "tabXxx"
|
||||
|
||||
# multi_word_regex is designed to match following patterns
|
||||
# `tabXxx Xxx` and "tabXxx Xxx"
|
||||
|
||||
# ([`"]?) Captures " or ` at the begining of the table name (if provided)
|
||||
# \1 matches the first captured group (quote character) at the end of the table name
|
||||
# multi word table name must have surrounding quotes.
|
||||
|
||||
# (tab([A-Z]\w+)( [A-Z]\w+)*) Captures table names that start with "tab"
|
||||
# and are continued with multiple words that start with a captital letter
|
||||
# e.g. 'tabXxx' or 'tabXxx Xxx' or 'tabXxx Xxx Xxx' and so on
|
||||
# \1 matches the first captured group (quote character) at the end of the table name
|
||||
tables = [groups[1] for groups in re.findall(r'([`"\']?)(tab([A-Z]\w+)( [A-Z]\w+)*)\1', query)]
|
||||
|
||||
single_word_regex = r'([`"]?)(tab([A-Z]\w+))\1'
|
||||
multi_word_regex = r'([`"])(tab([A-Z]\w+)( [A-Z]\w+)+)\1'
|
||||
tables = []
|
||||
for regex in (single_word_regex, multi_word_regex):
|
||||
tables += [groups[1] for groups in re.findall(regex, query)]
|
||||
|
||||
if frappe.flags.touched_tables is None:
|
||||
frappe.flags.touched_tables = set()
|
||||
frappe.flags.touched_tables.update(tables)
|
||||
|
|
|
|||
|
|
@ -48,6 +48,12 @@ class TestDB(unittest.TestCase):
|
|||
todo.save()
|
||||
self.assertIn('tabToDo', frappe.flags.touched_tables)
|
||||
|
||||
if frappe.db.db_type != "postgres":
|
||||
frappe.flags.touched_tables = set()
|
||||
frappe.db.sql("UPDATE tabToDo SET description = 'Updated Description'")
|
||||
self.assertNotIn('tabToDo SET', frappe.flags.touched_tables)
|
||||
self.assertIn('tabToDo', frappe.flags.touched_tables)
|
||||
|
||||
frappe.flags.touched_tables = set()
|
||||
todo.delete()
|
||||
self.assertIn('tabToDo', frappe.flags.touched_tables)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue