Skip to content

Commit

Permalink
support dumping PostgreSQL partitioning options to schema.rb
Browse files Browse the repository at this point in the history
  • Loading branch information
waymondo committed Jan 7, 2024
1 parent c09f963 commit 9fa4d44
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 1 deletion.
4 changes: 4 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
* Add support for dumping native partitioning table definitions for PostgeSQL adapter

*Justin Talbott*

* Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.

Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,14 @@ def indexes(table_name) # :nodoc:
end

def table_options(table_name) # :nodoc:
options = {}
if comment = table_comment(table_name)
{ comment: comment }
options[:comment] = comment
end
if supports_native_partitioning? && partition_definition = table_partition_definition(table_name)
options[:options] = "PARTITION BY #{partition_definition}"
end
options
end

# Returns a comment stored in database for given table
Expand All @@ -172,6 +177,20 @@ def table_comment(table_name) # :nodoc:
end
end

# Returns the partition definition of a given table
def table_partition_definition(table_name) # :nodoc:
scope = quoted_scope(table_name, type: "BASE TABLE")

query_value(<<~SQL, "SCHEMA")
SELECT pg_catalog.pg_get_partkeydef(c.oid)
FROM pg_catalog.pg_class c
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = #{scope[:name]}
AND c.relkind IN (#{scope[:type]})
AND n.nspname = #{scope[:schema]}
SQL
end

# Returns the current database name.
def current_database
query_value("SELECT current_database()", "SCHEMA")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,10 @@ def supports_nulls_not_distinct?
database_version >= 15_00_00 # >= 15.0
end

def supports_native_partitioning?
database_version >= 12_00_00 # >= 12.0
end

def index_algorithms
{ concurrently: "CONCURRENTLY" }
end
Expand Down
48 changes: 48 additions & 0 deletions activerecord/test/cases/adapters/postgresql/schema_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -832,3 +832,51 @@ def test_nulls_not_set_is_dumped
assert_no_match(/nulls_not_distinct/, output)
end
end

class SchemaPartitionDefinitionsTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper

setup do
@connection = ActiveRecord::Base.connection
end

teardown do
@connection.drop_table "trains", if_exists: true
end

def test_list_partition_options_is_dumped
skip("current adapter doesn't support native partitioning") unless supports_native_partitioning?

@connection.create_table "trains", id: false, options: "PARTITION BY LIST (kind)" do |t|
t.string :name
t.string :kind
end

output = dump_table_schema "trains"

assert_match('options: "PARTITION BY LIST (kind)"', output)
end

def test_range_partition_options_is_dumped
skip("current adapter doesn't support native partitioning") unless supports_native_partitioning?

@connection.create_table "trains", id: false, options: "PARTITION BY RANGE (created_at)" do |t|
t.string :name
t.datetime :created_at, null: false
end

output = dump_table_schema "trains"

assert_match('options: "PARTITION BY RANGE (created_at)"', output)
end

def test_no_partition_options_are_dumped
@connection.create_table "trains" do |t|
t.string :name
end

output = dump_table_schema "trains"

assert_no_match("options:", output)
end
end
1 change: 1 addition & 0 deletions activerecord/test/support/adapter_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def supports_text_column_with_default?
supports_nulls_not_distinct?
supports_identity_columns?
supports_virtual_columns?
supports_native_partitioning?
].each do |method_name|
define_method method_name do
ActiveRecord::Base.connection.public_send(method_name)
Expand Down

0 comments on commit 9fa4d44

Please sign in to comment.