From 313e36f5f164634b87c4c5ea7a53fea0cba1260f Mon Sep 17 00:00:00 2001 From: Joshua Flanagan Date: Tue, 26 Sep 2017 17:17:23 -0500 Subject: [PATCH 1/2] Add SQL comment to original lock string for PostgreSQL The PostgreSQL implementation requires translating the user-specified lock string into a pair of 32 bit numbers, which makes the lock and unlock statements opaque in the SQL logs. To aid debugging, add a SQL comment containing the original lock string. The comment will be removed from the input by the PostgreSQL parser, but it will still show up in logs. --- lib/with_advisory_lock/postgresql.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/with_advisory_lock/postgresql.rb b/lib/with_advisory_lock/postgresql.rb index 0740a62..0666560 100644 --- a/lib/with_advisory_lock/postgresql.rb +++ b/lib/with_advisory_lock/postgresql.rb @@ -10,7 +10,7 @@ def release_lock end def execute_successful?(pg_function) - sql = "SELECT #{pg_function}(#{lock_keys.join(',')}) AS #{unique_column_name}" + sql = "SELECT #{pg_function}(#{lock_keys.join(',')}) AS #{unique_column_name} /* #{lock_name} */" result = connection.select_value(sql) # MRI returns 't', jruby returns true. YAY! (result == 't' || result == true) From 14c48e096372d069cdcec84dd61849ff41a546f3 Mon Sep 17 00:00:00 2001 From: Joshua Flanagan Date: Tue, 26 Sep 2017 17:51:53 -0500 Subject: [PATCH 2/2] Don't let a lock name end the SQL comment --- lib/with_advisory_lock/postgresql.rb | 3 ++- test/lock_test.rb | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/with_advisory_lock/postgresql.rb b/lib/with_advisory_lock/postgresql.rb index 0666560..386f5f6 100644 --- a/lib/with_advisory_lock/postgresql.rb +++ b/lib/with_advisory_lock/postgresql.rb @@ -10,7 +10,8 @@ def release_lock end def execute_successful?(pg_function) - sql = "SELECT #{pg_function}(#{lock_keys.join(',')}) AS #{unique_column_name} /* #{lock_name} */" + comment = lock_name.gsub(/(\/\*)|(\*\/)/, "--") + sql = "SELECT #{pg_function}(#{lock_keys.join(',')}) AS #{unique_column_name} /* #{comment} */" result = connection.select_value(sql) # MRI returns 't', jruby returns true. YAY! (result == 't' || result == true) diff --git a/test/lock_test.rb b/test/lock_test.rb index 9f42795..9c8a4d0 100644 --- a/test/lock_test.rb +++ b/test/lock_test.rb @@ -14,6 +14,14 @@ Tag.current_advisory_lock.must_match /#{lock_name}/ end end + + it 'can obtain a lock with a name that attempts to disrupt a SQL comment' do + dangerous_lock_name = 'test */ lock /*' + Tag.with_advisory_lock(dangerous_lock_name) do + Tag.current_advisory_lock.must_match(/#{Regexp.escape(dangerous_lock_name)}/) + end + + end end describe '.advisory_lock_exists?' do