Skip to content

Commit

Permalink
Fixes #36238 - drop all data owned by the DB user, not only tables
Browse files Browse the repository at this point in the history
The old logic (introduced all the way back in [1]) took a list of all
tables and executed a `DROP … CASCADE` on them. While this is sufficient
for tables and the *associated* sequences, triggers etc [2][3], it will
not delete objects that have no direct dependency on tables, like types
or functions.

However, we might have DDLs that do create such objects and then after
performing a database reset (thus assuming the DB is empty) the DDL will
fail to re-run with an error like:

    psycopg2.errors.DuplicateObject: type "pulp_evr_array_item" already exists

In a perferct world, those DDLs would be written in a way that they
detect that a certain object already exists and replace it instead.
This is what the problematic pulp DDL [5] does for functions, but
PostgreSQL doesn't support `CREATE OR REPLACE` for types [6].

Instead of trying to obtain a list of all tables and drop those, we can
instruct PostgreSQL to drop all objects owned by a certain user [4].
This has the benefit that it will drop all types of objects, so also
types and functions (but not databases, which is good as we cannot
recreate those without superuser permissions).
The downside is that this will not delete things not owned by the user,
but in our setups I would expect everything to be owned by the
application user as that is the one we use for setup etc and if things
would not be owned by the user, the user would not have been able to
`DROP` it with the old code either.

[1] Katello/katello-installer#550
[2] https://www.postgresql.org/docs/12/sql-droptable.html
[3] https://www.postgresql.org/docs/12/ddl-depend.html
[4] https://www.postgresql.org/docs/12/sql-drop-owned.html
[5] https://github.com/pulp/pulp_rpm/blob/06ed3c2b214684b06186d32b6a7c4ff018efa2c1/pulp_rpm/app/migrations/0013_RAW_rpm_evr_extension.py
[6] https://www.postgresql.org/docs/12/sql-createtype.html
  • Loading branch information
evgeni authored and ekohl committed Mar 28, 2023
1 parent 416f452 commit bb67be5
Showing 1 changed file with 3 additions and 8 deletions.
11 changes: 3 additions & 8 deletions hooks/pre/10-reset_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,10 @@ def pg_sql_statement(config, statement)
pg_command_base(config, 'psql', "-d #{config[:database]} -t -c \"" + statement + '"')
end

# WARNING: deletes all the data from a database. No warnings. No confirmations.
# WARNING: deletes all the data owned by the user. No warnings. No confirmations.
def empty_database!(config)
generate_delete_statements = pg_sql_statement(config, %q(
select string_agg('drop table if exists \"' || tablename || '\" cascade;', '')
from pg_tables
where schemaname = 'public';
))
delete_statements = `#{generate_delete_statements}`
execute!(pg_sql_statement(config, delete_statements), false, true) if delete_statements
delete_statement = 'DROP OWNED BY CURRENT_USER CASCADE;'
execute!(pg_sql_statement(config, delete_statement), false, true)
end

def clear_pulpcore_content(content_dir)
Expand Down

0 comments on commit bb67be5

Please sign in to comment.