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

Better dependency tracking for non-sql functions #129

Open
ewan-escience opened this issue May 6, 2024 · 11 comments
Open

Better dependency tracking for non-sql functions #129

ewan-escience opened this issue May 6, 2024 · 11 comments

Comments

@ewan-escience
Copy link

When trying out this product with the plan command, the program errors, because it seems to do some live validation of the plan. If I understand correctly what is happening, this generates errors because:

  1. some of the function are written in plpgsql, for which the program doesn't check its dependencies
  2. those functions seem to be created in alphabetical order, so some functions are created before their dependencies

One of the following would solve this:

  1. add flag is added that sets check_function_bodies = off before doing the validation
  2. add support for dependency checking of plpgsql functions
  3. don't validate the plan when the plan was created from two live databases (i.e. with both --dsn and --schema-source-dsn)
@bplunkett-stripe
Copy link
Collaborator

Yes, that is an unfortunate limitation of postgres. It doesn't actually build any hard dependencies with pgplsql functions, so pg-schema-diff is kind of operating in the dark. We could manually try to parse dependencies from the function but that is a lot of complexity: not only would the function itself need to be parsed, but the context of the function would need to be known (is it used in a trigger, check constraint, etc).

Plan validaiton is a confidence check. If plan validation fails, it normally implies the plan will fail against your actual database. We can definitely add an option to disable it, but I'd be curious to know if the plan validation is actually failing here, or you're okay with an invalid plan.

Thanks for the great breakdown here! I might rename the ticket to "Improve track of plpgsql functions"

@ewan-escience
Copy link
Author

Thanks for the quick reply. I'm trying to move away from migra, as it isn't developed anymore and doesn't support diffing domains. Migra would always add set check_function_bodies = off; to its diffs, and I never had any problems with it.

I'm quite sure the plan would work, but I cannot test it, as no plan is generated at all.

How does the validation work? Is it executed in the database to upgrade? Is it isolated? Is it reverted afterwards? I would like to disable it, as we always manually check the diff anyways.

@bplunkett-stripe bplunkett-stripe changed the title Support for plpgsql functions Better dependency tracking for non-sql functions May 6, 2024
@bplunkett-stripe
Copy link
Collaborator

I added a flag to disable plan validation in the cli via --disable-plan-validation.

The way plan validation works:

  1. Spins up a temporary database on your postgres instance
  2. Places the current schema in the temporary database
  3. Runs the migration
  4. Re-generates a diff and asserts that the diff is empty

We unfortunately do not support diffing of domains yet. If you add a ticket, we can try to get to it, since I imagine implementing that won't be too tricky.

@peterldowns
Copy link

We could manually try to parse dependencies from the function but that is a lot of complexity: not only would the function itself need to be parsed, but the context of the function would need to be known (is it used in a trigger, check constraint, etc).

@bplunkett-stripe have you considered letting the developer manually specify dependencies for the cases that they cannot be inferred (or inferred correctly)? That's what I do in pgmigrate, and it works great.

@bplunkett-stripe
Copy link
Collaborator

We could manually try to parse dependencies from the function but that is a lot of complexity: not only would the function itself need to be parsed, but the context of the function would need to be known (is it used in a trigger, check constraint, etc).

@bplunkett-stripe have you considered letting the developer manually specify dependencies for the cases that they cannot be inferred (or inferred correctly)? That's what I do in pgmigrate, and it works great.

Interesting. That is also a definite possibility. Not super conducive to the CLI format unfortunately, but I'm also thinking of adding support for some sort of configuration YAML.

@peterldowns
Copy link

Yeah, has to come from a configuration file, not passable on the command line, but it's pretty common for these kinds of tools to have config files (in my experience.) You could take a look at how I parse/merge cli options and config file options here in pgmigrate or just use something like Viper, which I've been meaning to try.

btw very cool project, watching with interest, keep up the good work 🫡

@bplunkett-stripe
Copy link
Collaborator

Awesome! pgmigrate looks pretty neat. We use cobra already, so viper will probably slot in pretty nicely.

Hopefully can get some bigger features out soon. This project is a bit on the side-burner for me with current priorities 😢 .

@bplunkett-stripe
Copy link
Collaborator

This is effectively blocked by #131, which will enable us to more easily build dependencies on statements like column additions/deletions.

@aleclarson

This comment was marked as outdated.

@Navbryce
Copy link

Navbryce commented Sep 2, 2024

This should be an option in pg-schema-diff. It seems that SET statements are not included in the diff plan, so the plan validation fails even when I tried setting check_function_bodies = off myself.

Maybe a special filename like pre_plan.sql could let us always run certain statements on the temporary database before plan validation?

The problem you're trying to solve for here is there are certain schema objects not yet supported by pg-schema-diff but referenced by your functions?

@aleclarson

This comment was marked as outdated.

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

No branches or pull requests

5 participants