Commit Graph

284 Commits

Author SHA1 Message Date
Andrew Farries
8234b9e5d2
Revert "Add support to list views (#358)" (#360)
The state query changes from #358 are causing performance issues in an
upstream integration of `pgroll`.

Revert the PR until the cause of the regression is found and fixed.

This reverts commit f994a42192.
2024-06-20 13:37:03 +01:00
Alexis Rico
f994a42192
Add support to list views (#358)
Signed-off-by: Alexis Rico <sferadev@gmail.com>
2024-06-19 16:30:17 +02:00
Andrew Farries
fca5abdfe2
Export OpAlterColumn.IsRenameOnly method (#357)
Export `OpAlterColumn.IsRenameOnly` method and add a test for it.

Applications using `pgroll` as a module may need to test if an alter
column operation is only a column rename operation without having to
duplicate the logic of checking the fields of the `OpAlterColumn`
struct.
2024-05-22 11:16:06 +01:00
Andrew Farries
a87fa36dda
Support create/drop index with uppercase names (#356)
Fixes https://github.com/xataio/pgroll/issues/355

Postgres stores index names with uppercase characters in the `pg_index`
catalog using the quoted version of the name. For example:

```
"idx_USERS_name"
```

whereas a lowercase index name would be stored as:

```
idx_users_name
```

This is different to how other object types are stored in their
respective catalogs. For example, table names are stored in
the`pg_class` catalog without quotes, regardless of whether they contain
uppercase characters.

This makes it necessary to strip quotes from index names when retrieving
them from the `pg_index` catalog when building the internal schema
representation.
2024-05-16 12:08:58 +01:00
Andrew Farries
4d3faebffd
Make down SQL in rename column operations use the new name of the column (#354)
Ensure that 'alter column' operations that rename a column and also
specify `down` SQL (such as those that alter some other column attribute
at the time of the rename) must use the new name of the column in the
`down` SQL.

Without this change, the `down` SQL would require the use of the old
column name.

Fixes #350
2024-05-16 11:57:53 +01:00
Andrew Farries
4c1bc6a03f
Dont duplicate CHECK constraints and DEFAULTs when altering column type (#349)
When a column is duplicated with a new type, check constraints and
defaults defined on the column *may* be incompatible with the new type.

In this case column duplication should not fail, but rather the
incompatible constraints and defaults should be ignored and not be
duplicated to the new column.

This PR changes column duplication to ignore errors on `DEFAULT` and
`CHECK` constraint duplication that look as though they are caused by a
change of column type.

Fixes https://github.com/xataio/pgroll/issues/348
2024-05-08 18:52:47 +01:00
Andrew Farries
5c1aef2f24
Retry on lock_timeout errors (#353)
Retry statements and transactions that fail due to `lock_timeout`
errors.

DDL operations and backfills are run in a session in which `SET
lock_timout TO xms'` has been set (`x` defaults to `500` but can be
specified with the `--lock-timeout` parameter). This ensures that a long
running query can't cause other queries to queue up behind a DDL
operation as it waits to acquire its lock.

The current behaviour if a DDL operation or backfill batch times out
when requesting a lock is to fail, forcing the user to retry the
migration operation (start, rollback, or complete).

This PR retries individual statements (like the DDL operations run by
migration operations) and transactions (used by backfills) if they fail
due to a `lock_timeout` error. The retry uses an exponential backoff
with jitter.

Fixes #171
2024-05-08 15:54:27 +01:00
Andrew Farries
4f0a715613
Support setting table and column comments to NULL (#345)
Build on #344 to allow removing column comments by setting them to
`null`.

Make use of https://github.com/omissis/go-jsonschema/pull/220 and use
the [nullable](https://github.com/oapi-codegen/nullable) package so that
it's possible to distingush between a missing `comment` field and one
that is explicitly set to `null`.

With https://github.com/omissis/go-jsonschema/pull/220 not being part of
a release yet, use a custom build of `go-jsonschema`. It should be
possible to switch back to the official release images once
https://github.com/omissis/go-jsonschema/pull/220 is part of a release.

Without this change it becomes impossible to remove a comment from a
column using the 'set comment' 'alter column' sub-operation
(https://github.com/xataio/pgroll/pull/344).
2024-04-29 13:23:29 +01:00
Andrew Farries
4fbfdf7b7e
Add a 'set comment' sub-operation to 'alter column' (#344)
Allow 'alter column' operations to set the comment on a column:

```json
{
  "name": "02_change_comment",
  "operations": [
    {
      "alter_column": {
        "table": "events",
        "column": "name",
        "comment": "The full name of the event"
      }
    }
  ]
}
```

This is a versioned migration so the column to which the comment is
applied is duplicated and backfilled according to the `up` and `down`
SQL supplied with the 'alter column' operation. `up` and `down` default
to a simple copy of the field between new and old columns.

The intention is that this can be combined with a 'change type'
sub-operation if there is some column metadata that should be updated as
part of the type change:

```json
{
  "name": "35_alter_column_multiple",
  "operations": [
    {
      "alter_column": {
        "table": "events",
        "column": "name",
        "name": "event_name",
        "type": "text",
        "comment": "{type: some-metadata}",
        "up": "name",
        "down": "name"
      }
    }
  ]
}
```

Fixes #328
2024-04-29 10:40:10 +01:00
Andrew Farries
afad3d88cd
Add a 'set default' sub-operation to 'alter column' (#346)
Allow 'alter column' operations to set the default value on a column:

```json
{
  "name": "02_change_default",
  "operations": [
    {
      "alter_column": {
        "table": "events",
        "column": "name",
        "default": "'new default value'"
      }
    }
  ]
}
```

This is a versioned migration so the column to which the default is
applied is duplicated and backfilled according to the `up` and `down`
SQL supplied with the 'alter column' operation. `up` and `down` default
to a simple copy of the field between new and old columns.

Fixes #327
2024-04-25 11:47:44 +01:00
Andrew Farries
7d8460f405
Allow rename-only 'alter-column' operations on unbackfillable columns (#341)
Allow rename-only 'alter column' operations on unbackfillable columns.
Rename operations don't require backfills so there is no reason to
impose such a restriction.

Fixes #340
2024-04-24 06:38:51 +01:00
Andrew Farries
a4222d8f8c
Support multiple 'alter column' sub operations (#338)
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
2024-04-22 12:11:15 +01:00
Andrew Farries
a444723691
Restrict state connection search path (#342)
Restrict the search path of the connection used by the state package to
only the state schema (the schema that contains the `migrations` table).

This ensures that any column types that might reside in other schema are
always qualified with the schema name in the internal schema
representation. Without the restriction of the search path, these type
names would be unqualified if they lived in a schema that was on the
search path used by the state connection.

The representation (qualified/unqualified) of type names in the internal
schema is ultimately due to how the
[format-type](https://www.postgresql.org/docs/9.5/functions-info.html)
function behaves; types in the `search_path` of the caller are
unqualified, otherwise they are qualified.
2024-04-22 08:38:11 +01:00
dependabot[bot]
37d2c28803
Bump golang.org/x/net from 0.20.0 to 0.23.0 (#343)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.20.0 to
0.23.0.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c48da13158"><code>c48da13</code></a>
http2: fix TestServerContinuationFlood flakes</li>
<li><a
href="762b58d1cf"><code>762b58d</code></a>
http2: fix tipos in comment</li>
<li><a
href="ba872109ef"><code>ba87210</code></a>
http2: close connections when receiving too many headers</li>
<li><a
href="ebc8168ac8"><code>ebc8168</code></a>
all: fix some typos</li>
<li><a
href="3678185f8a"><code>3678185</code></a>
http2: make TestCanonicalHeaderCacheGrowth faster</li>
<li><a
href="448c44f928"><code>448c44f</code></a>
http2: remove clientTester</li>
<li><a
href="c7877ac421"><code>c7877ac</code></a>
http2: convert the remaining clientTester tests to testClientConn</li>
<li><a
href="d8870b0bf2"><code>d8870b0</code></a>
http2: use synthetic time in TestIdleConnTimeout</li>
<li><a
href="d73acffdc9"><code>d73acff</code></a>
http2: only set up deadline when Server.IdleTimeout is positive</li>
<li><a
href="89f602b7bb"><code>89f602b</code></a>
http2: validate client/outgoing trailers</li>
<li>Additional commits viewable in <a
href="https://github.com/golang/net/compare/v0.20.0...v0.23.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/net&package-manager=go_modules&previous-version=0.20.0&new-version=0.23.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/xataio/pgroll/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-22 08:33:08 +01:00
Andrew Farries
d4445bb6bb
Refactor alter column suboperations (#337)
Remove duplication between 'alter column' sub-operations. Pull:

* column duplication and trigger creation on migration start
* column rename and trigger removal on complete
* trigger and column drop on rollback

up to the parent 'alter column' operation. This removes a lot of
duplicated code from the sub-operations and will make it easier to
support multiple sub-operations in one 'alter column' operation.

Part of #336
2024-04-10 15:17:28 +01:00
Andrew Farries
d5d4bea947
Add complete phase hooks (#335)
Extend `MigrationHooks` with two new hooks:

* `BeforeCompleteDDL` - run before any DDL operations on migration
completion.
* `AfterCompleteDDL` - guaranteed to run after DDL operations on
migration complete are finished.

These hooks can be used, for example, to temporarily switch off schema
replication until all DDL has completed.
2024-04-10 15:07:50 +01:00
Andrew Farries
6334cb452c
Rewrite column DEFAULTs using the SQL transformer (#332)
Use the SQL transformer added in #329 to rewrite or reject column
`DEFAULT` values.

Column `DEFAULT` values are user-supplied SQL expressions that may need
to be restricted or rewritten in some environments.
2024-03-28 11:56:04 +00:00
Andrew Farries
130f451812
Strengthen SQL transformation tests (#331)
Improve the existing tests around SQL transformation by adding a
`MockSQLTransformer` type and using it in the existing SQL
transformation tests.

Also add several new testcases for transformation of raw SQL operations
to ensure that when transformation fails the operation fails.

---------

Co-authored-by: Alexis Rico <me@sferadev.com>
2024-03-28 07:17:01 +00:00
Andrew Farries
944ebedf8a
Revert: Add WithRawSQLURL to configure an optional URl for raw sql operations (#333)
Revert #315 as there is no longer a demonstrated need for this option.

The `WithSQLTransformer` option was added (#329) and can be used to
transform raw SQL operations in #330, removing the need for the
`WithRawSQLURL` option.
2024-03-28 07:03:45 +00:00
Andrew Farries
2932ea3883
Disallow unknown fields in migration JSON (#334)
Change JSON decoding of migrations to disallow unknown fields.
2024-03-28 06:42:12 +00:00
Andrew Farries
0673b1b470
Rewrite raw SQL operations using a SQL transformer (#330)
Use the SQL transformer to transform the `up` and `down` fields of a raw
SQL migration.

Builds on https://github.com/xataio/pgroll/pull/329 which added a
`SQLTransformer` option to rewrite user-supplied SQL.
2024-03-27 10:59:07 +00:00
Andrew Farries
cc8c2d38ba
Add a WithSQLTransformer option to rewrite user-defined SQL in up and down triggers (#329)
Add a new `WithSQLTransformer` option to rewrite the user-defined SQL
used to define `up` and `down` triggers.

The intention is that the transformer be used to sanitize user-input
SQL.

Transformers implement the following interface:

```go
type SQLTransformer interface {
	Transform(sql string) (string, error)
}
```

and are used by the `createTrigger` function to rewrite the `up` or
`down` SQL before using it in the trigger function definition.

Later PRs will use the same transformer to rewrite the `up` and `down`
values used in raw SQL migrations and column `DEFAULT` expressions.
2024-03-27 09:18:59 +00:00
Andrew Farries
cf66d1f5b7
Update operation types to set a default of "" for up and down SQL (#325)
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.
2024-03-26 09:52:33 +00:00
dependabot[bot]
3e49151648
Bump github.com/docker/docker from 24.0.7+incompatible to 24.0.9+incompatible (#324)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from
24.0.7+incompatible to 24.0.9+incompatible.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/docker/releases">github.com/docker/docker's
releases</a>.</em></p>
<blockquote>
<h2>v24.0.9</h2>
<h2>24.0.9</h2>
<p>For a full list of pull requests and changes in this release, refer
to the relevant GitHub milestones:</p>
<ul>
<li><a
href="https://github.com/docker/cli/issues?q=is%3Aclosed+milestone%3A24.0.9">docker/cli,
24.0.9 milestone</a></li>
<li><a
href="https://github.com/moby/moby/issues?q=is%3Aclosed+milestone%3A24.0.9">moby/moby,
24.0.9 milestone</a></li>
</ul>
<h2>Security</h2>
<p>This release contains security fixes for the following CVEs affecting
Docker Engine and its components.</p>
<table>
<thead>
<tr>
<th>CVE</th>
<th>Component</th>
<th>Fix version</th>
<th>Severity</th>
</tr>
</thead>
<tbody>
<tr>
<td><a
href="https://scout.docker.com/v/CVE-2024-21626">CVE-2024-21626</a></td>
<td>runc</td>
<td>1.1.12</td>
<td>High, CVSS 8.6</td>
</tr>
<tr>
<td><a
href="https://scout.docker.com/v/CVE-2024-24557">CVE-2024-24557</a></td>
<td>Docker Engine</td>
<td>24.0.9</td>
<td>Medium, CVSS 6.9</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>Important</strong> ⚠️</p>
<p>Note that this release of Docker Engine doesn't include fixes for the
following known vulnerabilities in BuildKit:</p>
<ul>
<li><a
href="https://scout.docker.com/v/CVE-2024-23651">CVE-2024-23651</a></li>
<li><a
href="https://scout.docker.com/v/CVE-2024-23652">CVE-2024-23652</a></li>
<li><a
href="https://scout.docker.com/v/CVE-2024-23653">CVE-2024-23653</a></li>
<li><a
href="https://scout.docker.com/v/CVE-2024-23650">CVE-2024-23650</a></li>
</ul>
<p>To address these vulnerabilities, upgrade to <a
href="https://github.com/docker/docker/blob/HEAD/25.0.md#2502">Docker
Engine v25.0.2</a>.</p>
</blockquote>
<p>For more information about the security issues addressed in this
release, and the unaddressed vulnerabilities in BuildKit, refer to the
<a
href="https://www.docker.com/blog/docker-security-advisory-multiple-vulnerabilities-in-runc-buildkit-and-moby/">blog
post</a>. For details about each vulnerability, see the relevant
security advisory:</p>
<ul>
<li><a
href="https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv">CVE-2024-21626</a></li>
<li><a
href="https://github.com/moby/moby/security/advisories/GHSA-xw73-rw38-6vjc">CVE-2024-24557</a></li>
</ul>
<h3>Packaging updates</h3>
<ul>
<li>Upgrade runc to <a
href="https://github.com/opencontainers/runc/releases/tag/v1.1.12">v1.1.12</a>.
<a
href="https://redirect.github.com/moby/moby/pull/47269">moby/moby#47269</a></li>
<li>Upgrade containerd to <a
href="https://github.com/containerd/containerd/releases/tag/v1.7.13">v1.7.13</a>
(static binaries only). <a
href="https://redirect.github.com/moby/moby/pull/47280">moby/moby#47280</a></li>
</ul>
<h2>v24.0.8</h2>
<h2>24.0.8</h2>
<p>For a full list of pull requests and changes in this release, refer
to the relevant GitHub milestones:</p>
<ul>
<li><a
href="https://github.com/docker/cli/issues?q=is%3Aclosed+milestone%3A24.0.8">docker/cli,
24.0.8 milestone</a></li>
<li><a
href="https://github.com/moby/moby/issues?q=is%3Aclosed+milestone%3A24.0.8">moby/moby,
24.0.8 milestone</a></li>
</ul>
<h3>Bug fixes and enhancements</h3>
<ul>
<li>Live restore: Containers with auto remove (<code>docker run
--rm</code>) are no longer forcibly removed on engine restart. <a
href="https://redirect.github.com/moby/moby/pull/46869">moby/moby#46857</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fca702de7f"><code>fca702d</code></a>
Merge pull request from GHSA-xw73-rw38-6vjc</li>
<li><a
href="f78a7726d7"><code>f78a772</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/docker/issues/47281">#47281</a>
from thaJeztah/24.0_backport_bump_containerd_binary...</li>
<li><a
href="61afffeeb3"><code>61afffe</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/docker/issues/47270">#47270</a>
from thaJeztah/24.0_backport_bump_runc_binary_1.1.12</li>
<li><a
href="b38e74c4e0"><code>b38e74c</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/docker/issues/47276">#47276</a>
from thaJeztah/24.0_backport_bump_runc_1.1.12</li>
<li><a
href="dac56638ad"><code>dac5663</code></a>
update containerd binary to v1.7.13</li>
<li><a
href="20e1af3616"><code>20e1af3</code></a>
vendor: github.com/opencontainers/runc v1.1.12</li>
<li><a
href="858919d399"><code>858919d</code></a>
update runc binary to v1.1.12</li>
<li><a
href="141ad39e38"><code>141ad39</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/docker/issues/47266">#47266</a>
from vvoland/ci-fix-makeps1-templatefail-24</li>
<li><a
href="db968c672b"><code>db968c6</code></a>
hack/make.ps1: Fix go list pattern</li>
<li><a
href="61c51fbb5a"><code>61c51fb</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/docker/issues/47221">#47221</a>
from vvoland/pkg-pools-close-noop-24</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/docker/compare/v24.0.7...v24.0.9">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/docker/docker&package-manager=go_modules&previous-version=24.0.7+incompatible&new-version=24.0.9+incompatible)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/xataio/pgroll/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-22 11:49:08 +00:00
Andrew Farries
79566b03bf
Preserve comments on column duplication (#323)
Ensure that column comments are preserved when a column is duplicated.

Part of #227
2024-03-20 16:08:11 +00:00
dependabot[bot]
14a2217910
Bump google.golang.org/protobuf from 1.31.0 to 1.33.0 (#319)
Bumps google.golang.org/protobuf from 1.31.0 to 1.33.0.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google.golang.org/protobuf&package-manager=go_modules&previous-version=1.31.0&new-version=1.33.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts page](https://github.com/xataio/pgroll/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-16 13:26:41 +00:00
Carlos Pérez-Aradros Herce
8ed57994fc
Add WithRawSQLURL to configure an optional URl for raw sql operations (#315)
This setting comes handy when you need to use a different connection
string for raw SQL operations, as they may require some more security
checks.

---------

Co-authored-by: Andrew Farries <andyrb@gmail.com>
2024-03-13 16:02:44 +01:00
Andrew Farries
f5d09d5014
Move example schema validation to its own job (#318)
Move the validation of the examples' JSON schema from a step in the
`example` job into its own job.

In its previous location the examples were having their schema validated
in each job in the matrix (pg version x public/non_public schema),
making each job in the matrix take ~15s longer.

---------

Co-authored-by: Carlos Pérez-Aradros Herce <carlos@xata.io>
2024-03-12 15:10:12 +00:00
Andrew Farries
631d64249a
Rollback on backfill failure (#317)
Ensure that migrations that fail during backfill are rolled back.

Add testcases to ensure rollback occurs when an error occurs:
* during the DDL phase of migration start
* during the backfill phase of migration start

Fixes #316
2024-03-12 13:58:08 +00:00
Andrew Farries
547ac3e55c
Preserve foreign key ON DELETE attributes when FK columns are duplicated (#314)
Ensure that a foreign key's `ON DELETE` attribute is preserved when a
foreign key column is duplicated by a migration.

Fixes #313
2024-03-07 18:40:09 +00:00
Andrew Farries
297dd380e8
Remove BeforeBackfill hook (#312)
Remove the `BeforeBackfill` hook.

The `BeforeBackfill` hook was added along with the `BeforeStartDDL` and
`AfterStartDDL` hooks in #290, but is of limited use as a hook that runs
only after successful execution of start phase DDL. Prefer a simpler API
with fewer hooks until there is a demonstrated need for it.
2024-03-07 08:59:53 +00:00
Andrew Farries
c88c0602c6
Track foreign key ON DELETE setting in the internal schema representation (#311)
Add the `ON DELETE` setting of a foreign key to the information stored
about the key in the internal schema representation.

The schema representation for a foreign key now looks like:

```json
{
  "some_table": {
    ...
    "foreignKeys": {
      "fk_users_id": {
        "name": "fk_users_id",
        "columns": [
          "user_id"
        ],
        "onDelete": "NO ACTION",
        "referencedTable": "users",
        "referencedColumns": [
          "id"
        ]
      }
    }
  }
}
```

Fixes https://github.com/xataio/pgroll/issues/309
2024-03-07 08:59:45 +00:00
Andrew Farries
099a443074
Update documentation for foreign key options (#310)
Update the documentation for the changes made in #308.
2024-03-06 16:39:05 +00:00
Andrew Farries
f6cacf7392
Respect foreign key ON DELETE in add column and create table operations (#308)
#297 added the ability to specify the `ON DELETE` behavior of a foreign
key when altering an existing column.

Make it so that the `ON DELETE` property of the the FK is respected for
FKs on new columns too (ie those created by add column and create table
operations).

Fixes #306
2024-03-06 16:22:39 +00:00
Elizabet Oliveira
a7d5095748
Update banner images and logo colors (#307)
This PR updates the banner images and logos colors.
2024-03-06 14:32:31 +00:00
Andrew Farries
162bd06f9f
Fix duplicate inferred migrations when dropping columns outside of a migration (#305)
Ensure that only one `inferred` migration is created in the
`pgroll.migrations` table when a column is dropped outside of a
migration.

From the Postgres
[docs](https://www.postgresql.org/docs/current/event-trigger-definition.html):
> The sql_drop event occurs just before the ddl_command_end event
trigger for any operation that drops database objects

This means that when the `raw_migration` function is run in response to
`sql_drop` and `ddl_command_end`, duplicate entries will be created in
`pgroll.migrations`; once as the function is run for `sql_drop` and
again when it's run for `ddl_command_end`.

Change the definition of the `pg_roll_handle_drop` event trigger to only
run on those kinds of drops that won't result in duplicates when the
`pg_roll_handle_ddl` trigger runs for the same change. `DROP TABLE` and
`DROP VIEW` won't result in duplicate migrations because their schema
can't be inferred by the `ddl_command_event` trigger because the object
has already been dropped when the trigger runs.

Update the inferred migration tests with two new testcases covering
dropping tables and columns.

Fixes #304
2024-03-06 09:56:52 +00:00
Andrew Farries
fb05aece0e
Add extra validation for the rename_constraint operation (#303)
* Add an extra step to the validation for the `rename_constraint`
operation to ensure that the referenced table exists.
* Add validation tests for the operation.

Fixes #302
2024-03-04 13:23:44 +00:00
Andrew Farries
0f75224e45
Add Roll.Schema method (#299)
Having access to the name of the schema in which a migration is being
applied is useful when writing migration hooks.
2024-03-04 08:16:26 +00:00
Andrew Farries
63d5a7f8fe
Add CI step to validate examples against the JSON schema (#301)
Add a CI step to validate that the example migrations are valid
according to the JSON schema.

This would have caught the problem where the JSON schema was not fully
updated in https://github.com/xataio/pgroll/pull/293 and had to be
updated in a follow-up PR https://github.com/xataio/pgroll/pull/300
despite #293 including an example migration.

Use [ajv-cli](https://ajv.js.org/packages/ajv-cli.html) to perform
schema validation.

Here is an [example
run](https://github.com/xataio/pgroll/actions/runs/8113707179/job/22177613982)
where the check fails.
2024-03-04 07:32:18 +00:00
Andrew Farries
eda936f158
Add rename_constraint operation to PgRollOperation JSON schema definition (#300)
Otherwise migrations that include this operation are not valid according
to the JSON schema.

Fixup to https://github.com/xataio/pgroll/pull/293.
2024-03-01 16:02:28 +00:00
Alexis Rico
577870c325
Add rename_constraint operation (#293) 2024-03-01 11:30:09 +00:00
Andrew Farries
def08e2bcc
Allow setting the ON DELETE behaviour of foreign key constraints (#297)
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
2024-03-01 09:26:50 +00:00
Andrew Farries
431b95141a
Add testcase to ensure new columns can't be used as the the identity column in a backfill. (#298)
Add a test to ensure that new columns can't be used as the identity for
a backfill, even if they satisfy the conditions for an identity column.

A newly added `NOT NULL` and `UNIQUE` column could in theory be used as
the identity column for a backfill. However, it shouldn't be used as the
identity column fora backfill because it's a newly added column whose
temporary column will be full of NULLs for any existing rows in the
table.

Currently the column won't be selected as an identity for backfills
because the nullability and uniqueness for new column are not populated
when adding it to the virtual schema in the add_column operation:


c08ef7065c/pkg/migrations/op_add_column.go (L61-L63)

Following on from the discussion here:
https://github.com/xataio/pgroll/pull/289#discussion_r1505832826
2024-03-01 09:26:04 +00:00
Alexis Rico
52fb532e63
Format schema.json on generate (#294)
Add rule to format JSON Schema with prettier

---------

Signed-off-by: Alexis Rico <sferadev@gmail.com>
2024-03-01 09:24:05 +00:00
Andrew Farries
c08ef7065c
Add two new options to help with replication control (#290)
Add two new migration options:

* `WithSettingsOnMigrationStart`: defines a map of Postgres
setting/value pairs to be set for the duration of the DDL phase of
migration start. Settings will be restored to their previous values once
the DDL phase is complete.
* `WithKickstartReplication`: defines an option that when set will make
a no-op schema change in between completing the DDL operations for
migration start and performing backfills. This can be used to ensure
that schema replication is up-to-date before starting backfills.

Neither of these options are exposed via the CLI; they are intended for
use by `pgroll` integrators, ie modules using `pgroll` as a Go
dependency.
2024-02-29 08:54:57 +00:00
Alexis Rico
0aebb5054c
Fix error message of column rename (#292) 2024-02-29 09:27:02 +01:00
Andrew Farries
0746ba660a
Separate DDL operations from DML (backfills) on migration start (#289)
Separate the DDL operations required during migration start from the DML
operations (backfills). Complete all DDL steps before starting DML.

Each `Start` operation returns the name of the table that requires
backfill, if any. After all operations have started, backfills are run
on each table that requires one.

Separating DDL and DML during migration start like this will allow for
setting Postgres options that should apply only for the DDL phase of
migration start (as in #290).
2024-02-29 06:39:26 +00:00
Carlos Pérez-Aradros Herce
937f65c0e9
Relax backfill requirements so it works with unique columns (#288)
UNIQUE NOT NULL columns should also work in order to perform backfills.
This change relaxes the check on backfill requirements to use those
columns if a primary key is not available.

Validation will still error out if no suitable column is found

Note: this also fixes the `unique` retrieval from schema, where we were
failing to understand composed unique indices, resulting in columns
flagged as unique where they weren't really unique.
2024-02-27 15:16:44 +00:00
Carlos Pérez-Aradros Herce
16377ca121
Relax add_column requirements on pk (#286)
Primary keys are only required by pgroll when backfilling tables, relax
checks in the `add_column` op so we only require a present PK if
backfill will be needed (up function defined).
2024-02-26 16:13:21 +01:00
Andrew Farries
51de6d4518
Bump golangci-lint action to v4 (#287)
Bump the `golangci-lint` action to `v4` and stop using the cache from
`setup-go` as `golangci-lint` manages its own cache.

This removes all warnings from the summary page from workflow runs.
2024-02-26 12:17:37 +00:00