Skip to content

Commit bcd456b

Browse files
committed
add explicit targets flag to distinguish stored target
1 parent 8a0b70f commit bcd456b

File tree

3 files changed

+24
-24
lines changed

3 files changed

+24
-24
lines changed

sql/plan/delete.go

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ var ErrDeleteFromNotSupported = errors.NewKind("table doesn't support DELETE FRO
2828
// DeleteFrom is a node describing a deletion from some table.
2929
type DeleteFrom struct {
3030
UnaryNode
31-
// targets are the explicitly specified table nodes from which rows should be deleted. For simple DELETES against a
32-
// single source table, targets do NOT need to be explicitly specified and will not be set here. For DELETE FROM JOIN
33-
// statements, targets MUST be explicitly specified by the user and will be populated here.
34-
explicitTargets []sql.Node
31+
// targets contains the table nodes from which rows should be deleted. For simple DELETEs, this contains the single
32+
// inferred table. For DELETE FROM JOIN, this contains the explicitly specified tables.
33+
targets []sql.Node
34+
// hasExplicitTargets indicates whether the targets were explicitly specified in SQL (e.g., "DELETE t1, t2 FROM ...
35+
// ") vs inferred (e.g., "DELETE FROM table WHERE ...").
36+
hasExplicitTargets bool
3537
// Returning is a list of expressions to return after the delete operation. This feature is not
3638
// supported in MySQL's syntax, but is exposed through PostgreSQL's syntax.
3739
Returning []sql.Expression
@@ -44,37 +46,33 @@ var _ sql.Node = (*DeleteFrom)(nil)
4446
var _ sql.CollationCoercible = (*DeleteFrom)(nil)
4547

4648
// NewDeleteFrom creates a DeleteFrom node.
47-
func NewDeleteFrom(n sql.Node, targets []sql.Node) *DeleteFrom {
49+
func NewDeleteFrom(n sql.Node, targets []sql.Node, hasExplicitTargets bool) *DeleteFrom {
4850
return &DeleteFrom{
49-
UnaryNode: UnaryNode{n},
50-
explicitTargets: targets,
51+
UnaryNode: UnaryNode{n},
52+
targets: targets,
53+
hasExplicitTargets: hasExplicitTargets,
5154
}
5255
}
5356

54-
// HasExplicitTargets returns true if the target delete tables were explicitly specified. This can only happen with
55-
// DELETE FROM JOIN statements – for DELETE FROM statements using a single source table, the target is NOT explicitly
56-
// specified and is assumed to be the single source table.
57+
// HasExplicitTargets returns true if the target delete tables were explicitly specified in SQL. This can only happen
58+
// with DELETE FROM JOIN statements. For DELETE FROM statements using a single source table, the target is NOT
59+
// explicitly specified and is assumed to be the single source table.
5760
func (p *DeleteFrom) HasExplicitTargets() bool {
58-
return len(p.explicitTargets) > 0
61+
return p.hasExplicitTargets
5962
}
6063

6164
// WithExplicitTargets returns a new DeleteFrom node instance with the specified |targets| set as the explicitly
6265
// specified targets of the delete operation.
6366
func (p *DeleteFrom) WithExplicitTargets(targets []sql.Node) *DeleteFrom {
6467
copy := *p
65-
copy.explicitTargets = targets
68+
copy.targets = targets
69+
copy.hasExplicitTargets = true
6670
return &copy
6771
}
6872

69-
// GetDeleteTargets returns the sql.Nodes representing the tables from which rows should be deleted. For a DELETE FROM
70-
// JOIN statement, this will return the tables explicitly specified by the caller. For a DELETE FROM statement this will
71-
// return the single table in the DELETE FROM source that is implicitly assumed to be the target of the delete operation.
73+
// GetDeleteTargets returns the sql.Nodes representing the tables from which rows should be deleted.
7274
func (p *DeleteFrom) GetDeleteTargets() []sql.Node {
73-
if len(p.explicitTargets) == 0 {
74-
return []sql.Node{p.Child}
75-
} else {
76-
return p.explicitTargets
77-
}
75+
return p.targets
7876
}
7977

8078
// Schema implements the sql.Node interface.
@@ -101,7 +99,7 @@ func (p *DeleteFrom) Resolved() bool {
10199
return false
102100
}
103101

104-
for _, target := range p.explicitTargets {
102+
for _, target := range p.targets {
105103
if target.Resolved() == false {
106104
return false
107105
}
@@ -155,7 +153,7 @@ func (p *DeleteFrom) WithChildren(children ...sql.Node) (sql.Node, error) {
155153
return nil, sql.ErrInvalidChildrenNumber.New(p, len(children), 1)
156154
}
157155

158-
deleteFrom := NewDeleteFrom(children[0], p.explicitTargets)
156+
deleteFrom := NewDeleteFrom(children[0], p.targets, p.hasExplicitTargets)
159157
deleteFrom.Returning = p.Returning
160158
return deleteFrom, nil
161159
}

sql/planbuilder/dml.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ func (b *Builder) buildDelete(inScope *scope, d *ast.Delete) (outScope *scope) {
450450

451451
// Capture the table node for simple DELETEs before buildWhere wraps it
452452
var targets []sql.Node
453+
var hasExplicitTargets bool
453454
if len(d.Targets) == 0 {
454455
targets = []sql.Node{outScope.node}
455456
}
@@ -467,6 +468,7 @@ func (b *Builder) buildDelete(inScope *scope, d *ast.Delete) (outScope *scope) {
467468
}
468469

469470
if len(d.Targets) > 0 {
471+
hasExplicitTargets = true
470472
targets = make([]sql.Node, len(d.Targets))
471473
for i, tableName := range d.Targets {
472474
tabName := tableName.Name.String()
@@ -494,7 +496,7 @@ func (b *Builder) buildDelete(inScope *scope, d *ast.Delete) (outScope *scope) {
494496
}
495497
}
496498

497-
del := plan.NewDeleteFrom(outScope.node, targets)
499+
del := plan.NewDeleteFrom(outScope.node, targets, hasExplicitTargets)
498500
del.RefsSingleRel = !outScope.refsSubquery
499501
del.IsProcNested = b.ProcCtx().DbName != ""
500502
outScope.node = del

sql/planbuilder/parse_old_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5082,7 +5082,7 @@ func TestParseCreateTrigger(t *testing.T) {
50825082
plan.NewFilter(
50835083
expression.NewEquals(expression.NewUnresolvedColumn("a"), expression.NewUnresolvedQualifiedColumn("old", "b")),
50845084
plan.NewUnresolvedTable("baz", ""),
5085-
), nil),
5085+
), nil, false),
50865086
plan.NewInsertInto(sql.UnresolvedDatabase(""), plan.NewUnresolvedTable("zzz", ""), plan.NewValues([][]sql.Expression{{
50875087
expression.NewUnresolvedQualifiedColumn("old", "a"),
50885088
expression.NewUnresolvedQualifiedColumn("old", "b"),

0 commit comments

Comments
 (0)