From 66e533f9b13f2ea1f56a19246af55621cc368489 Mon Sep 17 00:00:00 2001 From: Mauricio Linhares Date: Wed, 29 Jan 2014 01:56:20 -0300 Subject: [PATCH] Correctly send the string given to lock! and reload(:lock) to the lock scope - fixes #13788 As per the documentation at lock!, if the :lock option is a string it should use the given SQL to generate the lock statement. --- activerecord/CHANGELOG.md | 10 ++++++++++ activerecord/lib/active_record/persistence.rb | 2 +- activerecord/test/cases/locking_test.rb | 11 +++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 2e103ba354..ddf5592a78 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,13 @@ +* Correctly send an user provided statement to a `lock!()` call. + + person.lock! 'FOR SHARE NOWAIT' + # Before: SELECT * ... LIMIT 1 FOR UPDATE + # After: SELECT * ... LIMIT 1 FOR SHARE NOWAIT + + Fixes #13788. + + *MaurĂ­cio Linhares* + * Handle aliased attributes `select()`, `order()` and `reorder()`. *Tsutomu Kuroda* diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index 460fbdb3f8..b1b35ed940 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -389,7 +389,7 @@ module ActiveRecord fresh_object = if options && options[:lock] - self.class.unscoped { self.class.lock.find(id) } + self.class.unscoped { self.class.lock(options[:lock]).find(id) } else self.class.unscoped { self.class.find(id) } end diff --git a/activerecord/test/cases/locking_test.rb b/activerecord/test/cases/locking_test.rb index a16ed963fe..c373dc1511 100644 --- a/activerecord/test/cases/locking_test.rb +++ b/activerecord/test/cases/locking_test.rb @@ -431,6 +431,17 @@ unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter) || in_memory_db? assert_equal old, person.reload.first_name end + if current_adapter?(:PostgreSQLAdapter) + def test_lock_sending_custom_lock_statement + Person.transaction do + person = Person.find(1) + assert_sql(/LIMIT 1 FOR SHARE NOWAIT/) do + person.lock!('FOR SHARE NOWAIT') + end + end + end + end + if current_adapter?(:PostgreSQLAdapter, :OracleAdapter) def test_no_locks_no_wait first, second = duel { Person.find 1 }