Skip to content

Commit

Permalink
Stop quoting column default values (#200)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
andrew-farries committed Nov 6, 2023
1 parent 954746b commit edc78ac
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
32 changes: 32 additions & 0 deletions examples/28_different_defaults.json
Original file line number Diff line number Diff line change
@@ -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()"
}
]
}
}
]
}
2 changes: 1 addition & 1 deletion pkg/migrations/op_create_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down

0 comments on commit edc78ac

Please sign in to comment.