Skip to content

Conversation

@fatkodima
Copy link
Member

Fixes #54841.

The problem was that tables defined with declarative partitioning (https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE) weren't correctly dumped.

In the original PR (#50475) it was always assumed that tables are defined with inheritance based partitioning (https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITIONING-USING-INHERITANCE).

@balbesina
Copy link

balbesina commented Apr 6, 2025

this solution does not consider child tables' columns might differ from main table definition: indexes, constraints and default values.
see doc.

Although all partitions must have the same columns as their partitioned parent, partitions may have their own indexes, constraints and default values, distinct from those of other partitions

that's why in the issue #54841 i mentioned attaching partition after child table is defined. this is the way pg_dump solves it. tbh, i was gonna work on my pr today. but since it's already here, i won't :)

@fatkodima
Copy link
Member Author

this solution does not consider child tables

By "child" tables do you mean inheritance based partitioning? Because this should not be a problem for declarative partitioning.

I was originally against this feature in rails, because much of complexity when people can simply use structure.sql format. I don't understand why people try to stick with schema.rb for as long as possible. I prefer to switch to sql format as soon as any advanced db feature is used in the project.

@balbesina
Copy link

balbesina commented Apr 6, 2025

i mean, when we only define table with options: partiotion of parent for values in ('value') child tables will lack indexes or default values if they have them different from parent table.

if we create tables like

# migration def up create_table :parent, id: false, options: 'partition by list(type)' do |t| t.string :type, null: false t.string :status, default: 'X', null: false t.timestamps end create_table :parent_a, id: false, options: "partition of parent for values in ('a')" create_table :parent_b, id: false, options: "partition of parent for values in ('b')" # index for child table only add_index :parent_b, :status, name: 'index_parent_b_on_status' # change default value for child table only change_column_default :parent_b, :status, 'Y' end

this pr will dump tables similar to:

create_table :parent, id: false, options: 'partition by list(type)' do |t| t.string :type, null: false t.string :status, default: 'X', null: false t.timestamps end create_table :parent_a, id: false, options: "partition of parent for values in ('a')" create_table :parent_b, id: false, options: "partition of parent for values in ('b')"

and now we will miss index and default value for status column in table_b.

@fatkodima fatkodima force-pushed the fix-dumping-decl-partitioned-tables branch from 16e52d8 to 62e1871 Compare April 6, 2025 20:48
@fatkodima
Copy link
Member Author

Agreed. Using a separate alter table is the only way I can see currently how it can be done. Switched the PR to use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

2 participants