@@ -20,6 +20,7 @@ import (
2020 "gopkg.in/src-d/go-errors.v1"
2121
2222 "github.com/dolthub/go-mysql-server/sql"
23+ "github.com/dolthub/go-mysql-server/sql/transform"
2324)
2425
2526var ErrDeleteFromNotSupported = errors .NewKind ("table doesn't support DELETE FROM" )
@@ -33,6 +34,10 @@ type DeleteFrom struct {
3334 explicitTargets []sql.Node
3435 RefsSingleRel bool
3536 IsProcNested bool
37+
38+ // Returning is a list of expressions to return after the delete operation. This feature is not
39+ // supported in MySQL's syntax, but is exposed through PostgreSQL's syntax.
40+ Returning []sql.Expression
3641}
3742
3843var _ sql.Databaseable = (* DeleteFrom )(nil )
@@ -73,6 +78,24 @@ func (p *DeleteFrom) GetDeleteTargets() []sql.Node {
7378 }
7479}
7580
81+ // Schema implements the sql.Node interface.
82+ func (p * DeleteFrom ) Schema () sql.Schema {
83+ // Postgres allows the returned values of the delete statement to be controlled, so if returning
84+ // expressions were specified, then we return a different schema.
85+ if p .Returning != nil {
86+ // We know that returning exprs are resolved here, because you can't call Schema()
87+ // safely until Resolved() is true.
88+ returningSchema := sql.Schema {}
89+ for _ , expr := range p .Returning {
90+ returningSchema = append (returningSchema , transform .ExpressionToColumn (expr , "" ))
91+ }
92+
93+ return returningSchema
94+ }
95+
96+ return p .Child .Schema ()
97+ }
98+
7699// Resolved implements the sql.Resolvable interface.
77100func (p * DeleteFrom ) Resolved () bool {
78101 if p .Child .Resolved () == false {
@@ -85,9 +108,31 @@ func (p *DeleteFrom) Resolved() bool {
85108 }
86109 }
87110
111+ for _ , expr := range p .Returning {
112+ if expr .Resolved () == false {
113+ return false
114+ }
115+ }
116+
88117 return true
89118}
90119
120+ // Expressions implements the sql.Expressioner interface.
121+ func (p * DeleteFrom ) Expressions () []sql.Expression {
122+ return p .Returning
123+ }
124+
125+ // WithExpressions implements the sql.Expressioner interface.
126+ func (p * DeleteFrom ) WithExpressions (newExprs ... sql.Expression ) (sql.Node , error ) {
127+ if len (newExprs ) != len (p .Returning ) {
128+ return nil , sql .ErrInvalidChildrenNumber .New (p , len (newExprs ), len (p .Returning ))
129+ }
130+
131+ copy := * p
132+ copy .Returning = newExprs
133+ return & copy , nil
134+ }
135+
91136func (p * DeleteFrom ) IsReadOnly () bool {
92137 return false
93138}
@@ -111,7 +156,9 @@ func (p *DeleteFrom) WithChildren(children ...sql.Node) (sql.Node, error) {
111156 return nil , sql .ErrInvalidChildrenNumber .New (p , len (children ), 1 )
112157 }
113158
114- return NewDeleteFrom (children [0 ], p .explicitTargets ), nil
159+ deleteFrom := NewDeleteFrom (children [0 ], p .explicitTargets )
160+ deleteFrom .Returning = p .Returning
161+ return deleteFrom , nil
115162}
116163
117164func GetDeletable (node sql.Node ) (sql.DeletableTable , error ) {
0 commit comments