From edc78acf0a0f3932f43b192c988bc7bd8c2d08df Mon Sep 17 00:00:00 2001 From: Andrew Farries Date: Mon, 6 Nov 2023 11:56:03 +0000 Subject: [PATCH] Stop quoting column default values (#200) When adding a column to a table (either at creation time or afterwards with an alter table migration), any default value for the column is automatically single quoted. This makes it easier to define migrations, as the user does not have to remember to add the single quotes in the migration. For example in this migration: ```json { "name": "28_different_defaults", "operations": [ { "create_table": { "name": "items", "columns": [ { "name": "id", "type": "serial", "pk": true }, { "name": "name", "type": "varchar(255)", "default": "unnamed" } ] } } ] } ``` the default value for the `name` column (`unnamed`) does not need to be quoted as `pgroll` does that automatically. However, this automatic quoting causes a problem when assigning a default value of `now()` to a timestamp column: ```json { "name": "28_different_defaults", "operations": [ { "create_table": { "name": "items", "columns": [ { "name": "id", "type": "serial", "pk": true }, { "name": "created_at", "type": "timestamptz", "default": "now()" } ] } } ] } ``` when run, this will result in a `created_at` column with a default value of the time at which the migration was run, eg: ``` | created_at | timestamp with time zone | not null default '2023-11-06 08:37:01.203691+00'::timestamp with time zone | ``` rather than the desired default: ``` | created_at | timestamp with time zone | not null default now() | ``` This PR removes the automatic quoting of default values so that `now()`, `CURRENT_TIMESTAMP` etc can be used correctly as column defaults. This pushes some complexity onto users who now have to single-quote those default values that require it. --- docs/README.md | 1 + examples/28_different_defaults.json | 32 +++++++++++++++++++++++++++++ pkg/migrations/op_create_table.go | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 examples/28_different_defaults.json diff --git a/docs/README.md b/docs/README.md index 856cb84..74688d0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -925,6 +925,7 @@ Example **create table** migrations: * [19_create_orders_table.json](../examples/19_create_orders_table.json) * [20_create_posts_table.json](../examples/20_create_posts_table.json) * [25_add_table_with_check_constraint.json](../examples/25_add_table_with_check_constraint.json) +* [28_different_defaults.json](../examples/28_different_defaults.json) ### Drop column diff --git a/examples/28_different_defaults.json b/examples/28_different_defaults.json new file mode 100644 index 0000000..ca7a2c8 --- /dev/null +++ b/examples/28_different_defaults.json @@ -0,0 +1,32 @@ +{ + "name": "28_different_defaults", + "operations": [ + { + "create_table": { + "name": "items", + "columns": [ + { + "name": "id", + "type": "serial", + "pk": true + }, + { + "name": "name", + "type": "varchar(255)", + "default": "'unnamed'" + }, + { + "name": "price", + "type": "decimal(10,2)", + "default": "0.00" + }, + { + "name": "created_at", + "type": "timestamptz", + "default": "now()" + } + ] + } + } + ] +} diff --git a/pkg/migrations/op_create_table.go b/pkg/migrations/op_create_table.go index fe0e9c0..f0a86f5 100644 --- a/pkg/migrations/op_create_table.go +++ b/pkg/migrations/op_create_table.go @@ -127,7 +127,7 @@ func ColumnToSQL(col Column) string { sql += " NOT NULL" } if col.Default != nil { - sql += fmt.Sprintf(" DEFAULT %s", pq.QuoteLiteral(*col.Default)) + sql += fmt.Sprintf(" DEFAULT %s", *col.Default) } if col.References != nil { sql += fmt.Sprintf(" CONSTRAINT %s REFERENCES %s(%s)",