-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Subqueries in SET condition of UPDATE statement in presence of foreign keys #15163
Conversation
Signed-off-by: Manan Gupta <manan@planetscale.com>
Signed-off-by: Manan Gupta <manan@planetscale.com>
Review ChecklistHello reviewers! 👋 Please follow this checklist when reviewing this Pull Request. General
Tests
Documentation
New flags
If a workflow is added or modified:
Backward compatibility
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #15163 +/- ##
==========================================
+ Coverage 70.60% 70.63% +0.02%
==========================================
Files 1376 1377 +1
Lines 182302 182800 +498
==========================================
+ Hits 128721 129123 +402
- Misses 53581 53677 +96 ☔ View full report in Codecov by Sentry. |
// updClone is used in foreign key planning to create the selection statements to be used for verification and selection. | ||
// If we encounter subqueries, we want to fix the updClone to use the replaced expression, so that the pulled out subquery's | ||
// result is used everywhere instead of running the subquery multiple times, which is wasteful. | ||
updClone := sqlparser.CloneRefOfUpdate(updStmt) | ||
for idx, updExpr := range updStmt.Exprs { | ||
expr, subqs := sqc.pullOutValueSubqueries(ctx, updExpr.Expr, qt.ID, true) | ||
if len(subqs) == 0 { | ||
expr = updExpr.Expr | ||
} else { | ||
updClone.Exprs[idx].Expr = sqlparser.CloneExpr(expr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about the case when the subquery gets merged with the outer query?
can we have a test for that as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't merge the subquery with the outer query any more. Because the subquery result has to be shared by the select and the update queries, we cannot run the subquery twice, for the reason that it might return different results.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this ensured that the subquery is not merged with the outer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
subquery is only merged with outer, if the outer is a Join or a Route. For foreign key planning, it will always either be a FkCascade or FkVerify, so it will never merge it. The merging logic is in pushOrMerge
in subquery_planning
.
Description
This PR adds the support requested in #15162.
With the changes in this PR, we support having a subquery in a SET clause of an UPDATE statement even if the column is related by foreign keys.
The changes proposed in the PR, are to use a modified clone statement of
UPDATE
statement for foreign key planning that has the subquery replaced by an argument, and to do the foreign key planning underneath the subquery containers so that the inner subqueries run first and their results can be used for the remainder of the update planning.Related Issue(s)
Checklist
Deployment Notes