Skip to content

Commit 07818e9

Browse files
committed
cleanup
1 parent 71b6191 commit 07818e9

File tree

4 files changed

+38
-50
lines changed

4 files changed

+38
-50
lines changed

enginetest/queries/update_queries.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -482,8 +482,6 @@ var UpdateScriptTests = []ScriptTest{
482482
},
483483
Assertions: []ScriptTestAssertion{
484484
{
485-
// TODO: Foreign key constraints are not honored for UDPATE ... JOIN statements
486-
Skip: true,
487485
Query: "UPDATE orders o JOIN customers c ON o.customer_id = c.id SET o.customer_id = 123 where o.customer_id != 1;",
488486
ExpectedErr: sql.ErrForeignKeyChildViolation,
489487
},
@@ -510,16 +508,12 @@ var UpdateScriptTests = []ScriptTest{
510508
},
511509
Assertions: []ScriptTestAssertion{
512510
{
513-
// TODO: Foreign key constraints are not honored for UDPATE ... JOIN statements
514-
Skip: true,
515511
Query: `UPDATE child1 c1
516512
JOIN child2 c2 ON c1.id = 10 AND c2.id = 20
517513
SET c1.p1_id = 999, c2.p2_id = 3;`,
518514
ExpectedErr: sql.ErrForeignKeyChildViolation,
519515
},
520516
{
521-
// TODO: Foreign key constraints are not honored for UDPATE ... JOIN statements
522-
Skip: true,
523517
Query: `UPDATE child1 c1
524518
JOIN child2 c2 ON c1.id = 10 AND c2.id = 20
525519
SET c1.p1_id = 3, c2.p2_id = 999;`,

sql/analyzer/apply_foreign_keys.go

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -138,50 +138,29 @@ func applyForeignKeysToNodes(ctx *sql.Context, a *Analyzer, n sql.Node, cache *f
138138
if err != nil {
139139
return nil, transform.SameTree, err
140140
}
141-
142-
fkTbl, ok := updateDest.(sql.ForeignKeyTable)
143-
if !ok {
144-
continue
145-
}
146-
fkEditor, err := getForeignKeyEditor(ctx, a, fkTbl, cache, fkChain, false)
141+
fkHandler, err :=
142+
getForeignKeyHandlerFromUpdateDestination(updateDest, ctx, a, cache, fkChain, updateTarget)
147143
if err != nil {
148144
return nil, transform.SameTree, err
149145
}
150-
if fkEditor == nil {
151-
continue
152-
}
153-
fkHandlerMap[tableName] = &plan.ForeignKeyHandler{
154-
Table: fkTbl,
155-
Sch: updateDest.Schema(),
156-
OriginalNode: updateTarget,
157-
Editor: fkEditor,
158-
AllUpdaters: fkChain.GetUpdaters(),
146+
if fkHandler == nil {
147+
fkHandlerMap[tableName] = updateTarget
148+
} else {
149+
fkHandlerMap[tableName] = fkHandler
159150
}
160151
}
161152
uj := plan.NewUpdateJoin(fkHandlerMap, n.Child.(*plan.UpdateJoin).Child)
162153
nn, err := n.WithChildren(uj)
163154
return nn, transform.NewTree, err
164155
default:
165-
fkTbl, ok := updateDest.(sql.ForeignKeyTable)
166-
// If foreign keys aren't supported then we return
167-
if !ok {
168-
return n, transform.SameTree, nil
169-
}
170-
171-
fkEditor, err := getForeignKeyEditor(ctx, a, fkTbl, cache, fkChain, false)
156+
fkHandler, err := getForeignKeyHandlerFromUpdateDestination(updateDest, ctx, a, cache, fkChain, n.Child)
172157
if err != nil {
173158
return nil, transform.SameTree, err
174159
}
175-
if fkEditor == nil {
160+
if fkHandler == nil {
176161
return n, transform.SameTree, nil
177162
}
178-
nn, err := n.WithChildren(&plan.ForeignKeyHandler{
179-
Table: fkTbl,
180-
Sch: updateDest.Schema(),
181-
OriginalNode: n.Child,
182-
Editor: fkEditor,
183-
AllUpdaters: fkChain.GetUpdaters(),
184-
})
163+
nn, err := n.WithChildren(fkHandler)
185164
return nn, transform.NewTree, err
186165
}
187166
case *plan.DeleteFrom:
@@ -480,6 +459,30 @@ func getForeignKeyRefActions(ctx *sql.Context, a *Analyzer, tbl sql.ForeignKeyTa
480459
return fkEditor, nil
481460
}
482461

462+
func getForeignKeyHandlerFromUpdateDestination(updateDest sql.UpdatableTable, ctx *sql.Context, a *Analyzer,
463+
cache *foreignKeyCache, fkChain foreignKeyChain, originalNode sql.Node) (*plan.ForeignKeyHandler, error) {
464+
fkTbl, ok := updateDest.(sql.ForeignKeyTable)
465+
if !ok {
466+
return nil, nil
467+
}
468+
469+
fkEditor, err := getForeignKeyEditor(ctx, a, fkTbl, cache, fkChain, false)
470+
if err != nil {
471+
return nil, err
472+
}
473+
if fkEditor == nil {
474+
return nil, nil
475+
}
476+
477+
return &plan.ForeignKeyHandler{
478+
Table: fkTbl,
479+
Sch: updateDest.Schema(),
480+
OriginalNode: originalNode,
481+
Editor: fkEditor,
482+
AllUpdaters: fkChain.GetUpdaters(),
483+
}, nil
484+
}
485+
483486
// resolveSchemaDefaults resolves the default values for the schema of |table|. This is primarily needed for column
484487
// default value expressions, since those don't get resolved during the planbuilder phase and assignExecIndexes
485488
// doesn't traverse through the ForeignKeyEditors and referential actions to find all of them. In addition to resolving

sql/analyzer/assign_update_join.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func modifyUpdateExprsForJoin(ctx *sql.Context, a *Analyzer, n sql.Node, scope *
3434
return n, transform.SameTree, nil
3535
}
3636

37-
updateTargets, err := updateTargetsByTable(us, jn)
37+
updateTargets, err := targetsByTable(us, jn)
3838
if err != nil {
3939
return nil, transform.SameTree, err
4040
}
@@ -51,8 +51,8 @@ func modifyUpdateExprsForJoin(ctx *sql.Context, a *Analyzer, n sql.Node, scope *
5151
return n, transform.SameTree, nil
5252
}
5353

54-
// rowUpdatersByTable maps a set of tables to their RowUpdater objects.
55-
func updateTargetsByTable(node sql.Node, ij sql.Node) (map[string]sql.Node, error) {
54+
// targetsByTable maps a set of table names to their corresponding Node
55+
func targetsByTable(node sql.Node, ij sql.Node) (map[string]sql.Node, error) {
5656
namesOfTableToBeUpdated := getTablesToBeUpdated(node)
5757
resolvedTables := getTablesByName(ij)
5858

sql/plan/update_join.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type UpdateJoin struct {
2525
UnaryNode
2626
}
2727

28-
// NewUpdateJoin returns an *UpdateJoin node.
28+
// NewUpdateJoin returns a new *UpdateJoin node.
2929
func NewUpdateJoin(updateTargets map[string]sql.Node, child sql.Node) *UpdateJoin {
3030
return &UpdateJoin{
3131
UpdateTargets: updateTargets,
@@ -54,11 +54,6 @@ func (u *UpdateJoin) DebugString() string {
5454

5555
// GetUpdatable returns an updateJoinTable which implements sql.UpdatableTable.
5656
func (u *UpdateJoin) GetUpdatable() sql.UpdatableTable {
57-
// TODO: UpdateJoin can update multiple tables, but this interface only allows for a single table.
58-
// Additionally, updatableJoinTable doesn't implement interfaces that other parts of the code
59-
// expect, so UpdateJoins don't always work correctly. For example, because updatableJoinTable
60-
// doesn't implement ForeignKeyTable, UpdateJoin statements don't enforce foreign key checks.
61-
// We should revamp this function so that we can communicate multiple tables being updated.
6257
return &UpdatableJoinTable{
6358
UpdateTargets: u.UpdateTargets,
6459
joinNode: u.Child.(*UpdateSource).Child,
@@ -74,10 +69,6 @@ func (u *UpdateJoin) WithChildren(children ...sql.Node) (sql.Node, error) {
7469
return NewUpdateJoin(u.UpdateTargets, children[0]), nil
7570
}
7671

77-
func (u *UpdateJoin) WithUpdateTargets(updateTargets map[string]sql.Node) *UpdateJoin {
78-
return NewUpdateJoin(updateTargets, u.Child)
79-
}
80-
8172
func (u *UpdateJoin) IsReadOnly() bool {
8273
return false
8374
}
@@ -103,7 +94,7 @@ func getUpdaters(updateTargets map[string]sql.Node, ctx *sql.Context) (map[strin
10394
return updaterMap, nil
10495
}
10596

106-
// updatableJoinTable manages the update of multiple tables.
97+
// UpdatableJoinTable manages the update of multiple tables.
10798
type UpdatableJoinTable struct {
10899
UpdateTargets map[string]sql.Node
109100
joinNode sql.Node

0 commit comments

Comments
 (0)