Skip to content

Commit 94d1105

Browse files
fix(cascade): ignore backquoted identifiers in the subquery check; assert the matched row
Review follow-up. The subquery check strips quoted text before looking for SELECT; it now strips MySQL's backquoted identifiers too, as it already did PostgreSQL's double-quoted ones, so a column named `select` no longer makes a seed look like a subquery (that case was safe, since the seed's keys select the same rows). The percent-sign test now checks which row each seed selects, not only how many. The seed helper's docstring notes that replacing a seed by its keys reads them all into one condition.
1 parent 05335d1 commit 94d1105

2 files changed

Lines changed: 6 additions & 2 deletions

File tree

‎src/datajoint/diagram.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def _has_subquery(condition):
160160
if not isinstance(condition, str):
161161
return False
162162
text = re.sub(r"(\\\")|(\\\')", "", condition) # escaped quotes
163-
text = re.sub(r"'[^']*'|\"[^\"]*\"", "", text) # quoted text and identifiers
163+
text = re.sub(r"'[^']*'|\"[^\"]*\"|`[^`]*`", "", text) # quoted text and identifiers
164164
return re.search(r"\bselect\b", text, re.IGNORECASE) is not None
165165

166166

@@ -178,6 +178,10 @@ def _seed_restriction(table_expr):
178178
to a fresh copy of the table, which rejects a subquery that names other
179179
tables' columns. A delete would also remove the rows the subquery reads,
180180
when they are downstream, before it deletes the seed itself.
181+
182+
Replacing a seed by its keys reads every selected primary key into Python
183+
and sends them back as one condition, so a very large seed makes a large
184+
query; restrict by the keys in batches if that becomes a problem.
181185
"""
182186
if table_expr._top is not None or any(_has_subquery(c) for c in table_expr.restriction):
183187
return AndList([table_expr.keys()]), set(table_expr.primary_key)

‎tests/integration/test_cascade_overdelete.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ class Use(dj.Manual):
319319
(Label & {"name": "50%"}, 1),
320320
(Label & "name = '5%%'", 3),
321321
]:
322-
assert len(seed) == 1
322+
assert seed.to_arrays("label_id").tolist() == [label]
323323
assert dj.Diagram.cascade(seed).counts()[Use.full_table_name] == 1
324324

325325
(Label & "name LIKE '50%'").delete(prompt=False)

0 commit comments

Comments
 (0)