Fix partial left join update when columns have default values or join table is in where clause#2207
Conversation
|
@max-hoffman will look at this today. |
|
@BarakatX2 I've spent a few hours looking into this to understand how update joins work and I'm seeing a variety of problems with the underlying code, not caused your PR:
I think this PR does fix some queries, we could probably expand the whitelist to Limit/Offset/Sort/Distinct/Having/Grouping/Window if we wanted to be safe. I'm more worried about all of the related problems with how update joins are executed though. This would be a good one to be on @jycor 's radar just because of how many problems I'm seeing. I'm going to get someone else to take a look, see if I am missing anything. Otherwise my suggested edits would be 1) expand whitelist, 2) more queries that touch the whitelist, and then 3) probably put the tests in |
| } | ||
| } | ||
|
|
||
| func toJoinNode(node sql.Node) *plan.JoinNode { |
There was a problem hiding this comment.
Could use switch n := node.(type) instead of having to recast every time
Example:
func toJoinNode(node sql.Node) *plan.JoinNode {
switch n := node.(type) {
case *plan.JoinNode:
return n
case *plan.Filter:
return toJoinNode(n.Child)
case *plan.Project:
return toJoinNode(n.Child)
default:
return nil
}
}There was a problem hiding this comment.
Yup, this is what I've changed it to with all the other node types mentioned above added. I will hopefully be able to push the updates sometime this week.
* An update query contains a left join where only some rows join * The update query contains a where clause on the join table and/or joins a table with default values
…plan.JoinNode` is wrapped by other nodes
45f8981 to
e7e0a1a
Compare
|
I've pushed the updated test and the additional node traversal. Of the nodes handled by
I was able to hit |
|
Thank you for taking the time to test and contribute to GMS @BarakatX2! We appreciate your help. |
I ran into an issue where I was getting a panic when in update queries using left joins with at least some rows being null. The cases where I could confirm this happens is when the query planner wraps the
JoinNodeinProjectorFilteror both. The logic that is supposed to skip null rows for update fails to skip when the node is not directly aJoinNode. I don't know if there are other node types that should be handled the same way in thetoJoinNodefunction I added. This fix resolved the issues I was having.Side note:
Another related issue I ran into while working on the tests for this was the same type of error happening when the join table is backed by
IndexedTableAccess. It seems to set the root join filter totrue, with a nested node that has the actual filter. Thetruefilter causes the update skip logic to allow updates on every attempted join, even when null. This was happening for a bit but it stopped while I was messing with the test data so I couldn't keep diagnosing it.