Skip to content

Commit

Permalink
Merge pull request #1059 from capcom6/mariadb/delete-returning
Browse files Browse the repository at this point in the history
MariaDB: add support for RETURNING clause in DELETE statements
  • Loading branch information
vmihailenco authored Nov 16, 2024
2 parents abcd779 + 7f90a15 commit 4fcf18a
Show file tree
Hide file tree
Showing 16 changed files with 35 additions and 10 deletions.
1 change: 1 addition & 0 deletions dialect/feature/feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ const (
CompositeIn // ... WHERE (A,B) IN ((N, NN), (N, NN)...)
UpdateOrderLimit // UPDATE ... ORDER BY ... LIMIT ...
DeleteOrderLimit // DELETE ... ORDER BY ... LIMIT ...
DeleteReturning
)
3 changes: 3 additions & 0 deletions dialect/mysqldialect/dialect.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ func (d *Dialect) Init(db *sql.DB) {

if strings.Contains(version, "MariaDB") {
version = semver.MajorMinor("v" + cleanupVersion(version))
if semver.Compare(version, "v10.0.5") >= 0 {
d.features |= feature.DeleteReturning
}
if semver.Compare(version, "v10.5.0") >= 0 {
d.features |= feature.InsertReturning
}
Expand Down
3 changes: 2 additions & 1 deletion dialect/oracledialect/dialect.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ func New() *Dialect {
feature.TableNotExists |
feature.SelectExists |
feature.AutoIncrement |
feature.CompositeIn
feature.CompositeIn |
feature.DeleteReturning
return d
}

Expand Down
6 changes: 3 additions & 3 deletions dialect/oracledialect/go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/uptrace/bun/dialect/oracledialect

go 1.22.0
go 1.23

toolchain go1.22.6
toolchain go1.23.2

replace github.com/uptrace/bun => ../..

Expand All @@ -14,5 +14,5 @@ require (
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
golang.org/x/sys v0.26.0 // indirect
golang.org/x/sys v0.27.0 // indirect
)
4 changes: 2 additions & 2 deletions dialect/oracledialect/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
3 changes: 2 additions & 1 deletion dialect/pgdialect/dialect.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ func New() *Dialect {
feature.InsertOnConflict |
feature.SelectExists |
feature.GeneratedIdentity |
feature.CompositeIn
feature.CompositeIn |
feature.DeleteReturning
return d
}

Expand Down
3 changes: 2 additions & 1 deletion dialect/sqlitedialect/dialect.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ func New() *Dialect {
feature.TableNotExists |
feature.SelectExists |
feature.AutoIncrement |
feature.CompositeIn
feature.CompositeIn |
feature.DeleteReturning
return d
}

Expand Down
6 changes: 6 additions & 0 deletions internal/dbtest/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1590,6 +1590,12 @@ func TestQuery(t *testing.T) {
return db.NewUpdate().Model(new(Story)).Set("name = ?", "new-name").WherePK().Order("id").Limit(1)
},
},
{
id: 172,
query: func(db *bun.DB) schema.QueryAppender {
return db.NewDelete().Model(&Model{}).WherePK().Returning("*")
},
},
}

timeRE := regexp.MustCompile(`'2\d{3}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d+)?(\+\d{2}:\d{2})?'`)
Expand Down
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mariadb-172
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM `models` WHERE (`id` = NULL) RETURNING *
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mssql2019-172
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bun: returning is not supported for current dialect
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql5-172
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bun: returning is not supported for current dialect
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-mysql8-172
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bun: returning is not supported for current dialect
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pg-172
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM "models" AS "model" WHERE ("model"."id" = NULL) RETURNING *
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-pgx-172
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM "models" AS "model" WHERE ("model"."id" = NULL) RETURNING *
1 change: 1 addition & 0 deletions internal/dbtest/testdata/snapshots/TestQuery-sqlite-172
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM "models" AS "model" WHERE ("model"."id" = NULL) RETURNING *
9 changes: 7 additions & 2 deletions query_delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ func (q *DeleteQuery) Limit(n int) *DeleteQuery {
//
// To suppress the auto-generated RETURNING clause, use `Returning("NULL")`.
func (q *DeleteQuery) Returning(query string, args ...interface{}) *DeleteQuery {
if !q.hasFeature(feature.DeleteReturning) {
q.err = errors.New("bun: returning is not supported for current dialect")
return q
}

q.addReturning(schema.SafeQuery(query, args))
return q
}
Expand Down Expand Up @@ -249,7 +254,7 @@ func (q *DeleteQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte, e
return nil, err
}

if q.hasFeature(feature.Returning) && q.hasReturning() {
if q.hasFeature(feature.DeleteReturning) && q.hasReturning() {
b = append(b, " RETURNING "...)
b, err = q.appendReturning(fmter, b)
if err != nil {
Expand Down Expand Up @@ -311,7 +316,7 @@ func (q *DeleteQuery) scanOrExec(
return nil, err
}

useScan := hasDest || (q.hasReturning() && q.hasFeature(feature.Returning|feature.Output))
useScan := hasDest || (q.hasReturning() && q.hasFeature(feature.DeleteReturning|feature.Output))
var model Model

if useScan {
Expand Down

0 comments on commit 4fcf18a

Please sign in to comment.