From fc35e1222242b3d581f0b7496a9021aadfc50b07 Mon Sep 17 00:00:00 2001 From: j2gg0s Date: Mon, 13 Jan 2025 14:17:36 +0800 Subject: [PATCH] feat: add feature flag AlterColumnExists With #704 --- dialect/feature/feature.go | 58 ++++++++++++++++++- dialect/pgdialect/dialect.go | 3 +- .../snapshots/TestQuery-mssql2019-168 | 2 +- .../snapshots/TestQuery-mssql2019-169 | 2 +- .../snapshots/TestQuery-mssql2019-170 | 2 +- .../snapshots/TestQuery-mssql2019-171 | 2 +- .../snapshots/TestQuery-mssql2019-172 | 2 +- .../testdata/snapshots/TestQuery-mysql5-172 | 2 +- .../testdata/snapshots/TestQuery-mysql8-172 | 2 +- .../testdata/snapshots/TestQuery-pg-168 | 2 +- .../testdata/snapshots/TestQuery-pg-169 | 2 +- .../testdata/snapshots/TestQuery-pg-170 | 2 +- .../testdata/snapshots/TestQuery-pg-171 | 2 +- .../testdata/snapshots/TestQuery-pgx-168 | 2 +- .../testdata/snapshots/TestQuery-pgx-169 | 2 +- .../testdata/snapshots/TestQuery-pgx-170 | 2 +- .../testdata/snapshots/TestQuery-pgx-171 | 2 +- .../testdata/snapshots/TestQuery-sqlite-168 | 2 +- .../testdata/snapshots/TestQuery-sqlite-169 | 2 +- .../testdata/snapshots/TestQuery-sqlite-170 | 2 +- .../testdata/snapshots/TestQuery-sqlite-171 | 2 +- query_column_add.go | 5 ++ query_delete.go | 8 +-- query_update.go | 6 +- 24 files changed, 90 insertions(+), 28 deletions(-) diff --git a/dialect/feature/feature.go b/dialect/feature/feature.go index 0707c6f88..89693fc21 100644 --- a/dialect/feature/feature.go +++ b/dialect/feature/feature.go @@ -1,6 +1,11 @@ package feature -import "github.com/uptrace/bun/internal" +import ( + "fmt" + "strconv" + + "github.com/uptrace/bun/internal" +) type Feature = internal.Flag @@ -35,4 +40,55 @@ const ( UpdateOrderLimit // UPDATE ... ORDER BY ... LIMIT ... DeleteOrderLimit // DELETE ... ORDER BY ... LIMIT ... DeleteReturning + AlterColumnExists // ADD/DROP COLUMN IF NOT EXISTS/IF EXISTS ) + +type NotSupportError struct { + Flag Feature +} + +func (err *NotSupportError) Error() string { + name, ok := flag2str[err.Flag] + if !ok { + name = strconv.FormatInt(int64(err.Flag), 10) + } + return fmt.Sprintf("bun: feature %s is not supported by current dialect", name) +} + +func NewNotSupportError(flag Feature) *NotSupportError { + return &NotSupportError{Flag: flag} +} + +var flag2str = map[Feature]string{ + CTE: "CTE", + WithValues: "WithValues", + Returning: "Returning", + InsertReturning: "InsertReturning", + Output: "Output", + DefaultPlaceholder: "DefaultPlaceholder", + DoubleColonCast: "DoubleColonCast", + ValuesRow: "ValuesRow", + UpdateMultiTable: "UpdateMultiTable", + InsertTableAlias: "InsertTableAlias", + UpdateTableAlias: "UpdateTableAlias", + DeleteTableAlias: "DeleteTableAlias", + AutoIncrement: "AutoIncrement", + Identity: "Identity", + TableCascade: "TableCascade", + TableIdentity: "TableIdentity", + TableTruncate: "TableTruncate", + InsertOnConflict: "InsertOnConflict", + InsertOnDuplicateKey: "InsertOnDuplicateKey", + InsertIgnore: "InsertIgnore", + TableNotExists: "TableNotExists", + OffsetFetch: "OffsetFetch", + SelectExists: "SelectExists", + UpdateFromTable: "UpdateFromTable", + MSSavepoint: "MSSavepoint", + GeneratedIdentity: "GeneratedIdentity", + CompositeIn: "CompositeIn", + UpdateOrderLimit: "UpdateOrderLimit", + DeleteOrderLimit: "DeleteOrderLimit", + DeleteReturning: "DeleteReturning", + AlterColumnExists: "AlterColumnExists", +} diff --git a/dialect/pgdialect/dialect.go b/dialect/pgdialect/dialect.go index 2180e6ab7..f718e30c1 100644 --- a/dialect/pgdialect/dialect.go +++ b/dialect/pgdialect/dialect.go @@ -53,7 +53,8 @@ func New(opts ...DialectOption) *Dialect { feature.SelectExists | feature.GeneratedIdentity | feature.CompositeIn | - feature.DeleteReturning + feature.DeleteReturning | + feature.AlterColumnExists for _, opt := range opts { opt(d) diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-168 b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-168 index 99ac97add..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-168 +++ b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-168 @@ -1 +1 @@ -bun: order is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-169 b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-169 index 673a81e73..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-169 +++ b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-169 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-170 b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-170 index 673a81e73..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-170 +++ b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-170 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-171 b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-171 index 673a81e73..5c110df5a 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-171 +++ b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-171 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature UpdateOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-172 b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-172 index dcc567f12..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-172 +++ b/internal/dbtest/testdata/snapshots/TestQuery-mssql2019-172 @@ -1 +1 @@ -bun: returning is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mysql5-172 b/internal/dbtest/testdata/snapshots/TestQuery-mysql5-172 index dcc567f12..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-mysql5-172 +++ b/internal/dbtest/testdata/snapshots/TestQuery-mysql5-172 @@ -1 +1 @@ -bun: returning is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-mysql8-172 b/internal/dbtest/testdata/snapshots/TestQuery-mysql8-172 index dcc567f12..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-mysql8-172 +++ b/internal/dbtest/testdata/snapshots/TestQuery-mysql8-172 @@ -1 +1 @@ -bun: returning is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pg-168 b/internal/dbtest/testdata/snapshots/TestQuery-pg-168 index 99ac97add..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-pg-168 +++ b/internal/dbtest/testdata/snapshots/TestQuery-pg-168 @@ -1 +1 @@ -bun: order is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pg-169 b/internal/dbtest/testdata/snapshots/TestQuery-pg-169 index 673a81e73..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-pg-169 +++ b/internal/dbtest/testdata/snapshots/TestQuery-pg-169 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pg-170 b/internal/dbtest/testdata/snapshots/TestQuery-pg-170 index 673a81e73..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-pg-170 +++ b/internal/dbtest/testdata/snapshots/TestQuery-pg-170 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pg-171 b/internal/dbtest/testdata/snapshots/TestQuery-pg-171 index 673a81e73..5c110df5a 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-pg-171 +++ b/internal/dbtest/testdata/snapshots/TestQuery-pg-171 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature UpdateOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pgx-168 b/internal/dbtest/testdata/snapshots/TestQuery-pgx-168 index 99ac97add..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-pgx-168 +++ b/internal/dbtest/testdata/snapshots/TestQuery-pgx-168 @@ -1 +1 @@ -bun: order is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pgx-169 b/internal/dbtest/testdata/snapshots/TestQuery-pgx-169 index 673a81e73..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-pgx-169 +++ b/internal/dbtest/testdata/snapshots/TestQuery-pgx-169 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pgx-170 b/internal/dbtest/testdata/snapshots/TestQuery-pgx-170 index 673a81e73..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-pgx-170 +++ b/internal/dbtest/testdata/snapshots/TestQuery-pgx-170 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-pgx-171 b/internal/dbtest/testdata/snapshots/TestQuery-pgx-171 index 673a81e73..5c110df5a 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-pgx-171 +++ b/internal/dbtest/testdata/snapshots/TestQuery-pgx-171 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature UpdateOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-168 b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-168 index 99ac97add..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-168 +++ b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-168 @@ -1 +1 @@ -bun: order is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-169 b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-169 index 673a81e73..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-169 +++ b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-169 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-170 b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-170 index 673a81e73..c586e7d42 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-170 +++ b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-170 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature DeleteOrderLimit is not supported by current dialect diff --git a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-171 b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-171 index 673a81e73..5c110df5a 100644 --- a/internal/dbtest/testdata/snapshots/TestQuery-sqlite-171 +++ b/internal/dbtest/testdata/snapshots/TestQuery-sqlite-171 @@ -1 +1 @@ -bun: limit is not supported for current dialect +bun: feature UpdateOrderLimit is not supported by current dialect diff --git a/query_column_add.go b/query_column_add.go index 48cb2542a..aa9aacf35 100644 --- a/query_column_add.go +++ b/query_column_add.go @@ -5,6 +5,7 @@ import ( "database/sql" "fmt" + "github.com/uptrace/bun/dialect/feature" "github.com/uptrace/bun/internal" "github.com/uptrace/bun/schema" ) @@ -133,6 +134,10 @@ func (q *AddColumnQuery) AppendQuery(fmter schema.Formatter, b []byte) (_ []byte //------------------------------------------------------------------------------ func (q *AddColumnQuery) Exec(ctx context.Context, dest ...interface{}) (sql.Result, error) { + if q.ifNotExists && !q.hasFeature(feature.AlterColumnExists) { + return nil, feature.NewNotSupportError(feature.AlterColumnExists) + } + queryBytes, err := q.AppendQuery(q.db.fmter, q.db.makeQueryBytes()) if err != nil { return nil, err diff --git a/query_delete.go b/query_delete.go index d2cf34bd5..8fffe448b 100644 --- a/query_delete.go +++ b/query_delete.go @@ -128,7 +128,7 @@ func (q *DeleteQuery) WhereAllWithDeleted() *DeleteQuery { func (q *DeleteQuery) Order(orders ...string) *DeleteQuery { if !q.hasFeature(feature.DeleteOrderLimit) { - q.err = errors.New("bun: order is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.DeleteOrderLimit) return q } q.addOrder(orders...) @@ -137,7 +137,7 @@ func (q *DeleteQuery) Order(orders ...string) *DeleteQuery { func (q *DeleteQuery) OrderExpr(query string, args ...interface{}) *DeleteQuery { if !q.hasFeature(feature.DeleteOrderLimit) { - q.err = errors.New("bun: order is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.DeleteOrderLimit) return q } q.addOrderExpr(query, args...) @@ -152,7 +152,7 @@ func (q *DeleteQuery) ForceDelete() *DeleteQuery { // ------------------------------------------------------------------------------ func (q *DeleteQuery) Limit(n int) *DeleteQuery { if !q.hasFeature(feature.DeleteOrderLimit) { - q.err = errors.New("bun: limit is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.DeleteOrderLimit) return q } q.setLimit(n) @@ -166,7 +166,7 @@ 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") + q.err = feature.NewNotSupportError(feature.DeleteOrderLimit) return q } diff --git a/query_update.go b/query_update.go index 24a90d512..c16b751ae 100644 --- a/query_update.go +++ b/query_update.go @@ -207,7 +207,7 @@ func (q *UpdateQuery) WhereAllWithDeleted() *UpdateQuery { // ------------------------------------------------------------------------------ func (q *UpdateQuery) Order(orders ...string) *UpdateQuery { if !q.hasFeature(feature.UpdateOrderLimit) { - q.err = errors.New("bun: order is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.UpdateOrderLimit) return q } q.addOrder(orders...) @@ -216,7 +216,7 @@ func (q *UpdateQuery) Order(orders ...string) *UpdateQuery { func (q *UpdateQuery) OrderExpr(query string, args ...interface{}) *UpdateQuery { if !q.hasFeature(feature.UpdateOrderLimit) { - q.err = errors.New("bun: order is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.UpdateOrderLimit) return q } q.addOrderExpr(query, args...) @@ -225,7 +225,7 @@ func (q *UpdateQuery) OrderExpr(query string, args ...interface{}) *UpdateQuery func (q *UpdateQuery) Limit(n int) *UpdateQuery { if !q.hasFeature(feature.UpdateOrderLimit) { - q.err = errors.New("bun: limit is not supported for current dialect") + q.err = feature.NewNotSupportError(feature.UpdateOrderLimit) return q } q.setLimit(n)