Skip to content

Commit

Permalink
Merge pull request #37585 from sebastian-palma/upsert-all-partitioned…
Browse files Browse the repository at this point in the history
…-indexes

Add support for partitioned indexes in PostgreSQL 11+
  • Loading branch information
kamipo authored and rafaelfranca committed Mar 30, 2020
1 parent 639e646 commit 1db2ae1
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 2 deletions.
4 changes: 4 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
* Fix support for PostgreSQL 11+ partitioned indexes.

*Sebastián Palma*

* Add support for beginless ranges, introduced in Ruby 2.7.

*Josh Goodall*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,10 @@ def prefetch_primary_key?(table_name = nil)
false
end

def supports_partitioned_indexes?
false
end

# Does this adapter support index sort order?
def supports_index_sort_order?
false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def index_name_exists?(table_name, index_name)
INNER JOIN pg_index d ON t.oid = d.indrelid
INNER JOIN pg_class i ON d.indexrelid = i.oid
LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
WHERE i.relkind = 'i'
WHERE i.relkind IN ('i', 'I')
AND i.relname = #{index[:name]}
AND t.relname = #{table[:name]}
AND n.nspname = #{index[:schema]}
Expand All @@ -92,7 +92,7 @@ def indexes(table_name) # :nodoc:
INNER JOIN pg_index d ON t.oid = d.indrelid
INNER JOIN pg_class i ON d.indexrelid = i.oid
LEFT JOIN pg_namespace n ON n.oid = i.relnamespace
WHERE i.relkind = 'i'
WHERE i.relkind IN ('i', 'I')
AND d.indisprimary = 'f'
AND t.relname = #{scope[:name]}
AND n.nspname = #{scope[:schema]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ def supports_index_sort_order?
true
end

def supports_partitioned_indexes?
database_version >= 110_000
end

def supports_partial_index?
true
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 @@ -45,6 +45,8 @@ class SchemaTest < ActiveRecord::PostgreSQLTestCase
PK_TABLE_NAME = "table_with_pk"
UNMATCHED_SEQUENCE_NAME = "unmatched_primary_key_default_value_seq"
UNMATCHED_PK_TABLE_NAME = "table_with_unmatched_sequence_for_pk"
PARTITIONED_TABLE = "measurements"
PARTITIONED_TABLE_INDEX = "index_measurements_on_logdate_and_city_id"

class Thing1 < ActiveRecord::Base
self.table_name = "test_schema.things"
Expand Down Expand Up @@ -311,6 +313,12 @@ def test_index_name_exists
assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME)
assert @connection.index_name_exists?(TABLE_NAME, INDEX_E_NAME)
assert_not @connection.index_name_exists?(TABLE_NAME, "missing_index")

if supports_partitioned_indexes?
create_partitioned_table
create_partitioned_table_index
assert @connection.index_name_exists?(PARTITIONED_TABLE, PARTITIONED_TABLE_INDEX)
end
end
end

Expand All @@ -329,6 +337,13 @@ def test_dump_indexes_for_schema_multiple_schemas_in_search_path
def test_dump_indexes_for_table_with_scheme_specified_in_name
indexes = @connection.indexes("#{SCHEMA_NAME}.#{TABLE_NAME}")
assert_equal 5, indexes.size

if supports_partitioned_indexes?
create_partitioned_table
create_partitioned_table_index
indexes = @connection.indexes("#{SCHEMA_NAME}.#{PARTITIONED_TABLE}")
assert_equal 1, indexes.size
end
end

def test_with_uppercase_index_name
Expand All @@ -337,6 +352,15 @@ def test_with_uppercase_index_name
with_schema_search_path SCHEMA_NAME do
assert_nothing_raised { @connection.remove_index "things", name: "things_Index" }
end

if supports_partitioned_indexes?
create_partitioned_table
@connection.execute "CREATE INDEX \"#{PARTITIONED_TABLE}_Index\" ON #{SCHEMA_NAME}.#{PARTITIONED_TABLE} (logdate, city_id)"

with_schema_search_path SCHEMA_NAME do
assert_nothing_raised { @connection.remove_index PARTITIONED_TABLE, name: "#{PARTITIONED_TABLE}_Index" }
end
end
end

def test_remove_index_when_schema_specified
Expand All @@ -351,6 +375,22 @@ def test_remove_index_when_schema_specified

@connection.execute "CREATE INDEX \"things_Index\" ON #{SCHEMA_NAME}.things (name)"
assert_raises(ArgumentError) { @connection.remove_index "#{SCHEMA2_NAME}.things", name: "#{SCHEMA_NAME}.things_Index" }

if supports_partitioned_indexes?
create_partitioned_table

@connection.execute "CREATE INDEX \"#{PARTITIONED_TABLE}_Index\" ON #{SCHEMA_NAME}.#{PARTITIONED_TABLE} (logdate, city_id)"
assert_nothing_raised { @connection.remove_index PARTITIONED_TABLE, name: "#{SCHEMA_NAME}.#{PARTITIONED_TABLE}_Index" }

@connection.execute "CREATE INDEX \"#{PARTITIONED_TABLE}_Index\" ON #{SCHEMA_NAME}.#{PARTITIONED_TABLE} (logdate, city_id)"
assert_nothing_raised { @connection.remove_index "#{SCHEMA_NAME}.#{PARTITIONED_TABLE}", name: "#{PARTITIONED_TABLE}_Index" }

@connection.execute "CREATE INDEX \"#{PARTITIONED_TABLE}_Index\" ON #{SCHEMA_NAME}.#{PARTITIONED_TABLE} (logdate, city_id)"
assert_nothing_raised { @connection.remove_index "#{SCHEMA_NAME}.#{PARTITIONED_TABLE}", name: "#{SCHEMA_NAME}.#{PARTITIONED_TABLE}_Index" }

@connection.execute "CREATE INDEX \"#{PARTITIONED_TABLE}_Index\" ON #{SCHEMA_NAME}.#{PARTITIONED_TABLE} (logdate, city_id)"
assert_raises(ArgumentError) { @connection.remove_index "#{SCHEMA2_NAME}.#{PARTITIONED_TABLE}", name: "#{SCHEMA_NAME}.#{PARTITIONED_TABLE}_Index" }
end
end

def test_primary_key_with_schema_specified
Expand Down Expand Up @@ -473,6 +513,14 @@ def do_dump_index_assertions_for_one_index(this_index, this_index_name, this_ind
def bind_param(value)
ActiveRecord::Relation::QueryAttribute.new(nil, value, ActiveRecord::Type::Value.new)
end

def create_partitioned_table
@connection.execute "CREATE TABLE #{SCHEMA_NAME}.\"#{PARTITIONED_TABLE}\" (city_id integer not null, logdate date not null) PARTITION BY LIST (city_id)"
end

def create_partitioned_table_index
@connection.execute "CREATE INDEX #{PARTITIONED_TABLE_INDEX} ON #{SCHEMA_NAME}.#{PARTITIONED_TABLE} (logdate, city_id)"
end
end

class SchemaForeignKeyTest < ActiveRecord::PostgreSQLTestCase
Expand Down
1 change: 1 addition & 0 deletions activerecord/test/cases/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def supports_default_expression?
%w[
supports_savepoints?
supports_partial_index?
supports_partitioned_indexes?
supports_insert_returning?
supports_insert_on_duplicate_skip?
supports_insert_on_duplicate_update?
Expand Down

0 comments on commit 1db2ae1

Please sign in to comment.