Allow 'alter column' operations to include multiple sub-operations. This
means migrations like this one are now possible:
```json
{
"name": "35_alter_column_multiple",
"operations": [
{
"alter_column": {
"table": "events",
"column": "name",
"name": "event_name",
"type": "text",
"nullable": false,
"unique": {
"name": "events_event_name_unique"
},
"check": {
"name": "event_name_length",
"constraint": "length(name) > 3"
},
"up": "(SELECT CASE WHEN name IS NULL THEN 'placeholder' ELSE name END)",
"down": "name"
}
}
]
}
```
This 'alter column' operation:
* Renames a column
* Changes its type
* Sets it `NOT NULL`
* Adds a unique constraint
* Adds a check constraint
Previously, this would have required 5 different operations.
Builds on https://github.com/xataio/pgroll/pull/337. Fixes
https://github.com/xataio/pgroll/issues/336
Improve consistency between operation types by updating operation types
to ensure that all operations that use `up` or `down` SQL default these
fields to `""`.
There is no distinction between an empty string and `nil` for these
fields.
Add support for setting the `ON DELETE` behaviour of a foreign key
constraint.
An example migration that uses the behaviour is:
```json
{
"name": "21_add_foreign_key_constraint",
"operations": [
{
"alter_column": {
"table": "posts",
"column": "user_id",
"references": {
"name": "fk_users_id",
"table": "users",
"column": "id",
"on_delete": "CASCADE"
},
"up": "(SELECT CASE WHEN EXISTS (SELECT 1 FROM users WHERE users.id = user_id) THEN user_id ELSE NULL END)",
"down": "user_id"
}
}
]
}
```
The valid options for `on_delete` are `CASCADE`, `SET NULL`, `RESTRICT`,
or `NO ACTION`. If the field is omitted, the default is `NO ACTION`,
Fixes#221
This change updates the `sql` operation to:
* Allow for a new `onComplete` flag, that will make it run on the
Complete phase, rather than doing it during Start (default behavior).
* Allows for `sql` operations next to others in the same migration. We
added this limitation to ensure this operation doesn't affect others,
especially around schema state management.
Having `sql` next to other operations has proven convenient sometimes,
by adding `onComplete` flag, we can allow for these migrations to run
and rely on views recreation based on the final state.
---------
Co-authored-by: Andrew Farries <andyrb@gmail.com>
Update the JSON schema in `schema.json` to state that only `name` and
`type` are required fields when specifying a column.
Previously `required` was set to `["name", "nullable", "pk", "type",
"unique"]` resulting in some valid `create_table` and `add_column`
migrations failing to validate.
Add two new testcases to the JSON schema tests to cover 'create_table'
and 'add_column' operations.
Update `schema.json` to correctly describe the 'alter column' operation.
The [alter column
](https://github.com/xataio/pgroll/tree/main/docs#alter-column)
operation is used to perform different alter column operations according
to which fields are present.
The rules are:
* `table` and `column` are always required.
* Exactly one of `name`, `type`, `check`, `unique`, `references`,
`nullable` must be present.
* If `type`, `check`, `unique`, `references` or `nullable` is present,
then `up` and `down` must also be present.
* If `name` is present then neither `up` or `down` is allowed.
This PR updates `schema.json` to capture these dependencies.
This change causes churn in the test code as some fields that previously
`string` have become `*string`.
Fixes#222
Add a new sub-operation to the 'alter column' operation to drop `NOT
NULL` constraints from columns.
Currently, it is only possible to **set** `NOT NULL` constraints on
columns but not remove them. The syntax for doing this is:
```json
{
"name": "16_set_nullable",
"operations": [
{
"alter_column": {
"table": "reviews",
"column": "review",
"nullable": false,
"up": "(SELECT CASE WHEN review IS NULL THEN product || ' is good' ELSE review END)",
"down": "review"
}
}
]
}
```
Setting `nullable: true` in the above migration would result in a
validation error saying that removing `NOT NULL` constraints was not
supported. This PR removes this restriction and allows `nullable: true`
to remove an existing `NOT NULL` constraint.
A migration to remove a `NOT NULL` constraint looks like:
```json
{
"name": "31_unset_not_null",
"operations": [
{
"alter_column": {
"table": "posts",
"column": "title",
"nullable": true,
"up": "title",
"down": "(SELECT CASE WHEN title IS NULL THEN 'placeholder title' ELSE title END)"
}
}
]
}
```
The differences between adding and removing a `NOT NULL` constraint are:
* `nullable: true` vs `nullable: false`
* The roles of `up` and `down` SQL are reversed; `down` now needs to
rewrite any `NULL`s to meet the `NOT NULL` constraint on the old column.
`up` defaults to a simple copy of the data from the old column to the
new.
Fixes#223
Update the **create table** and **add column** operations so that they
support adding [Postgres
comments](https://www.postgresql.org/docs/current/sql-comment.html):
* **create table**: comments can be added to the table itself and to
each of its columns.
* **add column**: a comment can be added to the column.
A **create table** migration that includes a comment on the table itself
and on one of its columns looks like this:
```json
{
"name": "12_create_employees_table",
"operations": [
{
"create_table": {
"name": "employees",
"comment": "This is a comment for the employees table",
"columns": [
{
"name": "id",
"type": "serial",
"pk": true
},
{
"name": "role",
"type": "varchar(255)",
"comment": "This is a comment for the role column"
}
]
}
}
]
}
```
and an **add column** migration that includes a comment looks like this:
```json
{
"name": "30_add_column_simple_up",
"operations": [
{
"add_column": {
"table": "people",
"up": "'temporary-description'",
"column": {
"name": "description",
"type": "varchar(255)",
"nullable": false,
"comment": "This is a comment for the description column"
}
}
}
]
}
```
This allows new tables and columns to be created with comments.
Deletion and modification of comments should still be performed with a
raw SQL migration. Until we see a use case that requires versioned
modification/removal of comments, these operations are best performed
directly on the base table with raw SQL.
All structs matched well except for `PrimaryKey` which we mapped
differently, I've refactored it to `Pk` as it doesn't seem to support
different names for go and JSON
---------
Signed-off-by: Alexis Rico <sferadev@gmail.com>
Co-authored-by: Andrew Farries <andyrb@gmail.com>