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

Support to recursively create partitioned index #86

Merged
merged 1 commit into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,21 +209,24 @@ Add an index to a natively partitioned table concurrently, as described in the [
safe_add_concurrent_partitioned_index :partitioned_table, :column
```

Add a composite index using the `hash` index type with custom name suffix.
Add a composite index using the `hash` index type with custom name for the parent index when the parent table contains sub-partitions.

```ruby
# Assuming this table has partitions child1 and child2, the following indexes will be created:
# Assuming this table has partitions child1 and child2, and child1 has sub-partitions sub1 and sub2,
# the following indexes will be created:
# - custom_name_idx
# - index_child1_on_column1_column2 (attached to custom_name_idx)
# - index_sub1_on_column1_column2 (attached to index_child1_on_column1_column2)
# - index_sub2_on_column1_column2 (attached to index_child1_on_column1_column2)
# - index_child2_on_column1_column2 (attached to custom_name_idx)
safe_add_concurrent_partitioned_index :partitioned_table, [:column1, :column2], name: "custom_name_idx", using: :hash
```

Notes:
Note:

- This method does not support sub-partitioning.
- This method runs multiple DDL statements non-transactionally.
- Creating or attaching an index on a child table could fail. In such cases an exception will be raised, and an `INVALID` index will be left on the parent table.
This method runs multiple DDL statements non-transactionally.
Creating or attaching an index on a child table could fail.
In such cases an exception will be raised, and an `INVALID` index will be left on the parent table.

#### safe\_add\_unvalidated\_check\_constraint

Expand Down
5 changes: 4 additions & 1 deletion lib/pg_ha_migrations/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ def self.from_table_name(table, mode=nil)
end

def natively_partitioned?
!!connection.select_value(<<~SQL)
return @natively_partitioned if defined?(@natively_partitioned)

@natively_partitioned = !!connection.select_value(<<~SQL)
SELECT true
FROM pg_partitioned_table, pg_class, pg_namespace
WHERE pg_class.oid = pg_partitioned_table.partrelid
Expand All @@ -79,6 +81,7 @@ def partitions(include_sub_partitions: false, include_self: false)
JOIN pg_namespace child_ns ON child.relnamespace = child_ns.oid
WHERE parent.relname = #{connection.quote(name)}
AND parent_ns.nspname = #{connection.quote(schema)}
ORDER BY child.oid -- Ensure consistent ordering for tests
SQL

if include_sub_partitions
Expand Down
13 changes: 8 additions & 5 deletions lib/pg_ha_migrations/safe_statements.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,6 @@ def safe_add_concurrent_partitioned_index(
return if if_not_exists && parent_index.valid?

child_indexes = parent_table.partitions.map do |child_table|
raise PgHaMigrations::InvalidMigrationError, "Partitioned table #{parent_table.inspect} contains sub-partitions" if child_table.natively_partitioned?

PgHaMigrations::Index.from_table_and_columns(child_table, columns)
end

Expand All @@ -221,8 +219,14 @@ def safe_add_concurrent_partitioned_index(
end

child_indexes.each do |child_index|
# CREATE INDEX CONCURRENTLY ON child_table
safe_add_concurrent_index(
add_index_method = if child_index.table.natively_partitioned?
:safe_add_concurrent_partitioned_index
else
:safe_add_concurrent_index
end

send(
add_index_method,
child_index.table.fully_qualified_name,
columns,
name: child_index.name,
Expand Down Expand Up @@ -491,7 +495,6 @@ def _fully_qualified_table_name_for_partman(table)
end.join(".")
end


def _per_migration_caller
@_per_migration_caller ||= Kernel.caller
end
Expand Down
Loading