Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow INITIALLY IMMEDIATE constraints in CREATE TABLE statements #560

Open
wants to merge 1 commit into
base: allow-named-inline-constraints-in-create-table
Choose a base branch
from

Conversation

andrew-farries
Copy link
Collaborator

Convert INITIALLY IMMEDIATE constraints appearing in CREATE TABLE column constraints to OpCreateTable operations rather than raw SQL.

The documentation is a little misleading, as it makes it sound like INITIALLY IMMEDIATE implies that the constraint is DEFERRABLE, but in practice it looks like INITIALLY IMMEDIATE without DEFERRABLE is a no-op:

CREATE TABLE foo(a int PRIMARY KEY GENERATED ALWAYS AS IDENTITY)

-- Specify an INITIALLY IMMEDIATE constraint without DEFERRABLE
ALTER TABLE foo ADD COLUMN bar int UNIQUE INITIALLY IMMEDIATE

-- Query the catalog to see the constraint
SELECT conname AS constraint_name,
        condeferrable AS is_deferrable,
        condeferred AS is_deferred
FROM pg_constraint
WHERE conrelid = 'foo'::regclass;

Result:

+-----------------+---------------+-------------+
| constraint_name | is_deferrable | is_deferred |
|-----------------+---------------+-------------|
| foo_pkey        | False         | False       |
| foo_bar_key     | False         | False       |
+-----------------+---------------+-------------+

ie, the UNIQUE constraint added to bar is not DEFERRABLE or DEFERRED.

In contrast, if the column bar is defined:

ALTER TABLE foo ADD COLUMN bar int UNIQUE DEFERRABLE INITIALLY IMMEDIATE

Then the same catalog query shows:

+-----------------+---------------+-------------+
| constraint_name | is_deferrable | is_deferred |
|-----------------+---------------+-------------|
| foo_pkey        | False         | False       |
| foo_bar_key     | True          | False       |
+-----------------+---------------+-------------+

ie, the constraint is DEFERRABLE.

So specifying INITIALLY IMMEDIATE without DEFERRABLE is a no-op.

@andrew-farries andrew-farries marked this pull request as ready for review December 20, 2024 07:41
@andrew-farries andrew-farries added the sql2pgroll Issues relating to the sql2pgroll package label Dec 20, 2024
Convert `INITIALLY IMMEDIATE` constraints appearing in `CREATE TABLE`
column constraints to `OpCreateTable` operations rather than raw SQL.

The documentation is a little misleading, as it makes it sound like
`INITIALLY IMMEDIATE` implies that the constraint is `DEFERRABLE`, but
in practice it looks like `INITIALLY IMMEDIATE` without `DEFERRABLE` is
a no-op.

Documentation:

https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-PARMS-INITIALLY

In practice:

```sql
CREATE TABLE foo(a int PRIMARY KEY GENERATED ALWAYS AS IDENTITY)

-- Specify an INITIALLY IMMEDIATE constraint without DEFERRABLE
ALTER TABLE foo ADD COLUMN bar int UNIQUE INITIALLY IMMEDIATE

-- Query the catalog to see the constraint
SELECT conname AS constraint_name,
        condeferrable AS is_deferrable,
        condeferred AS is_deferred
FROM pg_constraint
WHERE conrelid = 'foo'::regclass;
```

Result:
```
+-----------------+---------------+-------------+
| constraint_name | is_deferrable | is_deferred |
|-----------------+---------------+-------------|
| foo_pkey        | False         | False       |
| foo_bar_key     | False         | False       |
+-----------------+---------------+-------------+
```

ie, the `UNIQUE` constraint added to `bar` is not `DEFERRABLE` or
`DEFERRED`.

In contrast, if the column `bar` is defined:

```sql
ALTER TABLE foo ADD COLUMN bar int UNIQUE DEFERRABLE INITIALLY IMMEDIATE
```

Then the same catalog query shows:

```
+-----------------+---------------+-------------+
| constraint_name | is_deferrable | is_deferred |
|-----------------+---------------+-------------|
| foo_pkey        | False         | False       |
| foo_bar_key     | True          | False       |
+-----------------+---------------+-------------+
```
ie, the constraint is `DEFERRABLE`.

So specifying `INITIALLY IMMEDIATE` without `DEFERRABLE` is a no-op.
@andrew-farries andrew-farries changed the base branch from main to allow-named-inline-constraints-in-create-table December 20, 2024 11:34
@andrew-farries andrew-farries force-pushed the fix-initially-immediate-constraints branch from 6155486 to 5b04017 Compare December 20, 2024 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sql2pgroll Issues relating to the sql2pgroll package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant