diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb b/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb index 0ed8e72ea7..44a7338bf5 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity.rb @@ -14,7 +14,7 @@ module ActiveRecord transaction(requires_new: true) do execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";")) end - rescue => e + rescue ActiveRecord::ActiveRecordError => e original_exception = e end @@ -37,7 +37,7 @@ Rails needs superuser privileges to disable referential integrity. transaction(requires_new: true) do execute(tables.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";")) end - rescue + rescue ActiveRecord::ActiveRecordError end else yield diff --git a/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb b/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb index 98291f1bbf..71ee2d9bab 100644 --- a/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb +++ b/activerecord/test/cases/adapters/postgresql/referential_integrity_test.rb @@ -6,9 +6,13 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::TestCase include ConnectionHelper + IS_REFERENTIAL_INTEGRITY_SQL = lambda do |sql| + sql.match(/DISABLE TRIGGER ALL/) || sql.match(/ENABLE TRIGGER ALL/) + end + module MissingSuperuserPrivileges def execute(sql) - if sql.match(/DISABLE TRIGGER ALL/) || sql.match(/ENABLE TRIGGER ALL/) + if IS_REFERENTIAL_INTEGRITY_SQL.call(sql) super "BROKEN;" rescue nil # put transaction in broken state raise ActiveRecord::StatementInvalid, 'PG::InsufficientPrivilege' else @@ -17,6 +21,16 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::TestCase end end + module ProgrammerMistake + def execute(sql) + if IS_REFERENTIAL_INTEGRITY_SQL.call(sql) + raise ArgumentError, 'something is not right.' + else + super + end + end + end + def setup @connection = ActiveRecord::Base.connection end @@ -81,6 +95,14 @@ class PostgreSQLReferentialIntegrityTest < ActiveRecord::TestCase end end + def test_only_catch_active_record_errors_others_bubble_up + @connection.extend ProgrammerMistake + + assert_raises ArgumentError do + @connection.disable_referential_integrity {} + end + end + private def assert_transaction_is_not_broken