diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index 26ef23a0d9..69aa02ccf4 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -101,15 +101,19 @@ module ActiveRecord
 
         # Verifies existence of an index with a given name.
         def index_name_exists?(table_name, index_name, default)
+          table = Utils.extract_schema_qualified_name(table_name.to_s)
+          index = Utils.extract_schema_qualified_name(index_name.to_s)
+
           select_value(<<-SQL, 'SCHEMA').to_i > 0
             SELECT COUNT(*)
             FROM pg_class t
             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'
-              AND i.relname = '#{index_name}'
-              AND t.relname = '#{table_name}'
-              AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )
+              AND i.relname = '#{index.identifier}'
+              AND t.relname = '#{table.identifier}'
+              AND n.nspname = #{index.schema ? "'#{index.schema}'" : 'ANY (current_schemas(false))'}
           SQL
         end
 
@@ -450,7 +454,7 @@ module ActiveRecord
         def remove_index(table_name, options = {}) #:nodoc:
           index_name = index_name_for_remove(table_name, options)
           algorithm =
-            if options.key?(:algorithm)
+            if Hash === options && options.key?(:algorithm)
               index_algorithms.fetch(options[:algorithm]) do
                 raise ArgumentError.new("Algorithm must be one of the following: #{index_algorithms.keys.map(&:inspect).join(', ')}")
               end
diff --git a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
index d0f5f56786..24def31e36 100644
--- a/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/active_schema_test.rb
@@ -25,7 +25,7 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
 
   def test_add_index
     # add_index calls index_name_exists? which can't work since execute is stubbed
-    ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.stubs(:index_name_exists?).returns(false)
+    ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_exists?) { |*| false }
 
     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'")
@@ -49,15 +49,22 @@ class PostgresqlActiveSchemaTest < ActiveRecord::PostgreSQLTestCase
 
     expected = %(CREATE UNIQUE INDEX  "index_people_on_last_name" ON "people" USING gist ("last_name") WHERE state = 'active')
     assert_equal expected, add_index(:people, :last_name, :unique => true, :where => "state = 'active'", :using => :gist)
+
+    ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :remove_method, :index_name_exists?
   end
 
   def test_remove_index
+    # remove_index calls index_name_exists? which can't work since execute is stubbed
+    ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send(:define_method, :index_name_exists?) { |*| true }
+
     expected = %(DROP INDEX CONCURRENTLY "index_people_on_last_name")
     assert_equal expected, remove_index(:people, name: "index_people_on_last_name", algorithm: :concurrently)
 
     assert_raise ArgumentError do
       add_index(:people, :last_name, algorithm: :copy)
     end
+
+    ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.send :remove_method, :index_name_exists?
   end
 
   private