-
-
Notifications
You must be signed in to change notification settings - Fork 231
Apply foreign key constraints to UPDATE JOIN
#3037
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
Changes from 11 commits
7e253ea
336c07a
e6d019a
f831e00
591449b
e03b11a
4cf9d24
c30dd34
71b6191
07818e9
d319c72
0146174
222fa00
84dbdc8
5b03b88
bd4ba29
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,15 +21,15 @@ import ( | |
) | ||
|
||
type UpdateJoin struct { | ||
Updaters map[string]sql.RowUpdater | ||
UpdateTargets map[string]sql.Node | ||
angelamayxie marked this conversation as resolved.
Show resolved
Hide resolved
|
||
UnaryNode | ||
} | ||
|
||
// NewUpdateJoin returns an *UpdateJoin node. | ||
func NewUpdateJoin(editorMap map[string]sql.RowUpdater, child sql.Node) *UpdateJoin { | ||
// NewUpdateJoin returns a new *UpdateJoin node. | ||
func NewUpdateJoin(updateTargets map[string]sql.Node, child sql.Node) *UpdateJoin { | ||
return &UpdateJoin{ | ||
Updaters: editorMap, | ||
UnaryNode: UnaryNode{Child: child}, | ||
UpdateTargets: updateTargets, | ||
UnaryNode: UnaryNode{Child: child}, | ||
} | ||
} | ||
|
||
|
@@ -54,14 +54,9 @@ func (u *UpdateJoin) DebugString() string { | |
|
||
// GetUpdatable returns an updateJoinTable which implements sql.UpdatableTable. | ||
func (u *UpdateJoin) GetUpdatable() sql.UpdatableTable { | ||
// TODO: UpdateJoin can update multiple tables, but this interface only allows for a single table. | ||
// Additionally, updatableJoinTable doesn't implement interfaces that other parts of the code | ||
// expect, so UpdateJoins don't always work correctly. For example, because updatableJoinTable | ||
// doesn't implement ForeignKeyTable, UpdateJoin statements don't enforce foreign key checks. | ||
// We should revamp this function so that we can communicate multiple tables being updated. | ||
return &updatableJoinTable{ | ||
updaters: u.Updaters, | ||
joinNode: u.Child.(*UpdateSource).Child, | ||
return &UpdatableJoinTable{ | ||
UpdateTargets: u.UpdateTargets, | ||
joinNode: u.Child.(*UpdateSource).Child, | ||
} | ||
} | ||
|
||
|
@@ -71,7 +66,7 @@ func (u *UpdateJoin) WithChildren(children ...sql.Node) (sql.Node, error) { | |
return nil, sql.ErrInvalidChildrenNumber.New(u, len(children), 1) | ||
} | ||
|
||
return NewUpdateJoin(u.Updaters, children[0]), nil | ||
return NewUpdateJoin(u.UpdateTargets, children[0]), nil | ||
} | ||
|
||
func (u *UpdateJoin) IsReadOnly() bool { | ||
|
@@ -83,48 +78,65 @@ func (u *UpdateJoin) CollationCoercibility(ctx *sql.Context) (collation sql.Coll | |
return sql.GetCoercibility(ctx, u.Child) | ||
} | ||
|
||
// updatableJoinTable manages the update of multiple tables. | ||
type updatableJoinTable struct { | ||
updaters map[string]sql.RowUpdater | ||
joinNode sql.Node | ||
func (u *UpdateJoin) GetUpdaters(ctx *sql.Context) (map[string]sql.RowUpdater, error) { | ||
return getUpdaters(u.UpdateTargets, ctx) | ||
} | ||
|
||
var _ sql.UpdatableTable = (*updatableJoinTable)(nil) | ||
func getUpdaters(updateTargets map[string]sql.Node, ctx *sql.Context) (map[string]sql.RowUpdater, error) { | ||
updaterMap := make(map[string]sql.RowUpdater) | ||
for tableName, updateTarget := range updateTargets { | ||
updatable, err := GetUpdatable(updateTarget) | ||
if err != nil { | ||
return nil, err | ||
} | ||
updaterMap[tableName] = updatable.Updater(ctx) | ||
} | ||
return updaterMap, nil | ||
} | ||
|
||
// UpdatableJoinTable manages the update of multiple tables. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is fine for fixing foreign keys, but as we look at making triggers work correctly, it's worth thinking about if this is the right type here... No need to change this now, but I'd dig into cleaning this incongruence when we look at getting triggers to work across all tables. |
||
type UpdatableJoinTable struct { | ||
UpdateTargets map[string]sql.Node | ||
joinNode sql.Node | ||
} | ||
|
||
var _ sql.UpdatableTable = (*UpdatableJoinTable)(nil) | ||
|
||
// Partitions implements the sql.UpdatableTable interface. | ||
func (u *updatableJoinTable) Partitions(context *sql.Context) (sql.PartitionIter, error) { | ||
func (u *UpdatableJoinTable) Partitions(context *sql.Context) (sql.PartitionIter, error) { | ||
panic("this method should not be called") | ||
} | ||
|
||
// PartitionsRows implements the sql.UpdatableTable interface. | ||
func (u *updatableJoinTable) PartitionRows(context *sql.Context, partition sql.Partition) (sql.RowIter, error) { | ||
func (u *UpdatableJoinTable) PartitionRows(context *sql.Context, partition sql.Partition) (sql.RowIter, error) { | ||
panic("this method should not be called") | ||
} | ||
|
||
// Name implements the sql.UpdatableTable interface. | ||
func (u *updatableJoinTable) Name() string { | ||
func (u *UpdatableJoinTable) Name() string { | ||
panic("this method should not be called") | ||
} | ||
|
||
// String implements the sql.UpdatableTable interface. | ||
func (u *updatableJoinTable) String() string { | ||
func (u *UpdatableJoinTable) String() string { | ||
panic("this method should not be called") | ||
} | ||
|
||
// Schema implements the sql.UpdatableTable interface. | ||
func (u *updatableJoinTable) Schema() sql.Schema { | ||
func (u *UpdatableJoinTable) Schema() sql.Schema { | ||
return u.joinNode.Schema() | ||
} | ||
|
||
// Collation implements the sql.Table interface. | ||
func (u *updatableJoinTable) Collation() sql.CollationID { | ||
func (u *UpdatableJoinTable) Collation() sql.CollationID { | ||
return sql.Collation_Default | ||
} | ||
|
||
// Updater implements the sql.UpdatableTable interface. | ||
func (u *updatableJoinTable) Updater(ctx *sql.Context) sql.RowUpdater { | ||
func (u *UpdatableJoinTable) Updater(ctx *sql.Context) sql.RowUpdater { | ||
updaters, _ := getUpdaters(u.UpdateTargets, ctx) | ||
return &updatableJoinUpdater{ | ||
updaterMap: u.updaters, | ||
updaterMap: updaters, | ||
schemaMap: RecreateTableSchemaFromJoinSchema(u.joinNode.Schema()), | ||
joinSchema: u.joinNode.Schema(), | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.