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

More improvements for PostgreSQL parse / diff #161

Merged
merged 4 commits into from
Dec 19, 2023

Conversation

nrdvana
Copy link
Contributor

@nrdvana nrdvana commented Nov 2, 2023

The first commit fixes a very obvious bug that creates spurrous diffs of foreign key constraints.

The second commit makes it easier to run t/66

The third commit adds a new deconstruct_enum_types option to the PostgreSQL parser so that it returns a field of { data_type => 'enum', extra => { list => ... } } instead of { data_type => 'my_custom_enum_type' }. This gives Diff the ability to see when the schema contains a different set of enum values than the specification (only when the option is enabled).

The fourth commit improves the Producer's alter_table to generate ALTER TYPE ... ADD VALUE when an enum has gained a new value. This allows it to automatically upgrade schemas to include new enum values, but I didn't implement deletion of old enum values since that is much harder.

The parser was storing the ON UPDATE value into the constraint's
on_delete attribute, and vice versa.  This caused foreign keys to
always show as diffs in SQL::Translator::Diff if the on_update
differed from on_delete.
Test::PostgreSQL requires the postgres server binaries to be installed
on the host, which is a steep requirement.  So, eval{} both the
presence of the module and whether the module is successfully able to
create a postgres instance.  If so, use that.  (but only if none of
the env variables were set)
The ::Producer::PostgreSQL will take a column definition of
data_type 'enum' and convert it to a postgres custom data type,
and then declare the column of that type.  When parsed, the column
no longer shows the values of the enum and the data_type is the
custom name rather than 'enum'.  This new option reaches into the
postgres type to find the enum values, and reverts the data_type
to 'enum', like it was originally.
Now, when producing a diff between two enum columns where the list
of values are known, and when the postgres version is greater than
9.001, the producer will generate an ALTER TYPE ... ADD VALUE
statments if the new enum includes values that the old one did not.
This is an easy case to support because it does not involve
re-creating the type.

The harder case of removing an enum value is not supported, yet.
The output includes a SQL comment to that effect, giving the
user a note that they need to perform that step on their own.
@rabbiveesh
Copy link
Contributor

This looks fantastic! Thanks so much for the contribution!

@rabbiveesh
Copy link
Contributor

Do you think we should warn when a diff detects removing values from an enum instead of just dropping a comment in the SQL?
I personally always review my generated upgrades, but perhaps it would be helpful to other people?

@nrdvana
Copy link
Contributor Author

nrdvana commented Nov 27, 2023

I'm fine with a warning, but it should probably only print once per process? Or maybe once per Translator instance?

Maybe a new setting warn_unimplemented, with values once (default), each, or 0?

Somewhat related, in my local wrapper object I prevent all DROP statements universally, replacing them with a SQL comment and a warning, just to make sure I never deploy a production disaster. It might be nice to make that into a standard feature that all producers are aware of.

@rabbiveesh
Copy link
Contributor

That sounds like a good idea. I've been wanting to make improvements around renaming columns, which is something that also should get a warning.
I suppose ill open a new ticket about the unimplemented warnings and merge this when I'm not on mobile

@rabbiveesh rabbiveesh merged commit dee6a8d into dbsrgits:master Dec 19, 2023
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants