提交 d70e0236 编写于 作者: M Marcelo Silveira

Added where option to add_index to support postgresql partial indices

The `add_index` method now supports a `where` option that receives a
string with the partial index criteria.

    add_index(:accounts, :code, :where => "active")

    Generates

    CREATE INDEX index_accounts_on_code ON accounts(code) WHERE active
上级 12c3b3d6
## Rails 4.0.0 (unreleased) ##
* Added support for partial indices to PostgreSQL adapter
The `add_index` method now supports a `where` option that receives a
string with the partial index criteria.
add_index(:accounts, :code, :where => "active")
Generates
CREATE INDEX index_accounts_on_code ON accounts(code) WHERE active
*Marcelo Silveira*
* Implemented ActiveRecord::Relation#none method
The `none` method returns a chainable relation with zero records
......
......@@ -381,9 +381,16 @@ def rename_column(table_name, column_name, new_column_name)
#
# Note: mysql doesn't yet support index order (it accepts the syntax but ignores it)
#
# ====== Creating a partial index
# add_index(:accounts, [:branch_id, :party_id], :unique => true, :where => "active")
# generates
# CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id ON accounts(branch_id, party_id) WHERE active
#
# Note: only supported by PostgreSQL
#
def add_index(table_name, column_name, options = {})
index_name, index_type, index_columns = add_index_options(table_name, column_name, options)
execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})"
index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)} (#{index_columns})#{index_options}"
end
# Remove the given index from the table.
......@@ -581,6 +588,9 @@ def add_index_options(table_name, column_name, options = {})
if Hash === options # legacy support, since this param was a string
index_type = options[:unique] ? "UNIQUE" : ""
index_name = options[:name].to_s if options.key?(:name)
if supports_partial_index?
index_options = options[:where] ? " WHERE #{options[:where]}" : ""
end
else
index_type = options
end
......@@ -593,7 +603,7 @@ def add_index_options(table_name, column_name, options = {})
end
index_columns = quoted_columns_for_index(column_names, options).join(", ")
[index_name, index_type, index_columns]
[index_name, index_type, index_columns, index_options]
end
def index_name_for_remove(table_name, options = {})
......
......@@ -142,6 +142,11 @@ def supports_index_sort_order?
false
end
# Does this adapter support partial indices?
def supports_partial_index?
false
end
# Does this adapter support explain? As of this writing sqlite3,
# mysql2, and postgresql are the only ones that do.
def supports_explain?
......
......@@ -302,6 +302,10 @@ def supports_index_sort_order?
true
end
def supports_partial_index?
true
end
class StatementPool < ConnectionAdapters::StatementPool
def initialize(connection, max)
super
......
......@@ -21,6 +21,18 @@ def test_create_database_with_encoding
assert_equal %(CREATE DATABASE "aimonetti" ENCODING = 'latin1'), create_database(:aimonetti, :encoding => :latin1)
end
def test_add_index
# add_index calls index_name_exists? which can't work since execute is stubbed
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_exists?) do |*|
false
end
expected = %(CREATE UNIQUE INDEX "index_people_on_last_name" ON "people" ("last_name") WHERE state = 'active')
assert_equal expected, add_index(:people, :last_name, :unique => true, :where => "state = 'active'")
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:remove_method, :index_name_exists?)
end
private
def method_missing(method_symbol, *arguments)
ActiveRecord::Base.connection.send(method_symbol, *arguments)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册