From 5d74f61360375ad85f6eff5305016544b60cbdb6 Mon Sep 17 00:00:00 2001 From: Aaron Todd Date: Wed, 12 Feb 2014 08:49:11 +0800 Subject: [PATCH] Explictly check return from lock functions Currently the postgres adapter uses connection#select_value which looking at the documentation the call chain is : select_value -> select_one -> select_all select_all "... returns an array of hashes ..." select_one "... selects first hash of array ..." select_value " ... selects first value of hash ..." This means that when selecting more than one value in a statement you need to explictly request which column you want. In some Rubies maybe select_value always returns the output of the lock functions but at least in REE/MRI 1.8 and jRuby in 1.8 mode where I tested this is not true. The fix is simple - use execute and retrieve the value ( PR coming ) or change the SQL to only select the lock function result. --- lib/with_advisory_lock/postgresql.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/with_advisory_lock/postgresql.rb b/lib/with_advisory_lock/postgresql.rb index 2e25ac6..330f786 100644 --- a/lib/with_advisory_lock/postgresql.rb +++ b/lib/with_advisory_lock/postgresql.rb @@ -8,12 +8,12 @@ def try_lock # pg_try_advisory_lock will either obtain the lock immediately # and return true, or return false if the lock cannot be acquired immediately sql = "SELECT pg_try_advisory_lock(#{numeric_lock}), #{Time.now.to_f}" - "t" == connection.select_value(sql).to_s + "t" == connection.execute(sql).first["pg_try_advisory_lock"].to_s end def release_lock sql = "SELECT pg_advisory_unlock(#{numeric_lock}), #{Time.now.to_f}" - "t" == connection.select_value(sql).to_s + "t" == connection.execute(sql).first["pg_advisory_unlock"].to_s end def numeric_lock(name=lock_name)