Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Use the query lock hint when joining tables
  • Loading branch information
Aidan Haran committed Jan 23, 2018
1 parent 1f870c5 commit bc75817
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,9 @@
## v5.1.5

#### Added

* Use lock hint when joining table in query.

#### Fixed

* Memoize `@@version` queries. Fixes #632
Expand Down
16 changes: 14 additions & 2 deletions lib/arel/visitors/sqlserver.rb
Expand Up @@ -95,17 +95,29 @@ def visit_Arel_Nodes_JoinSource o, collector
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector
end
if o.right.any?
collector << " " if o.left
collector << SPACE if o.left
collector = inject_join o.right, collector, ' '
end
collector
end

def visit_Arel_Nodes_InnerJoin o, collector
collector << "INNER JOIN "
collector = visit o.left, collector
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
if o.right
collector << SPACE
visit(o.right, collector)
else
collector
end
end

def visit_Arel_Nodes_OuterJoin o, collector
collector << "LEFT OUTER JOIN "
collector = visit o.left, collector
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
collector << " "
collector << SPACE
visit o.right, collector
end

Expand Down
28 changes: 28 additions & 0 deletions test/cases/pessimistic_locking_test_sqlserver.rb
Expand Up @@ -52,6 +52,34 @@ class PessimisticLockingTestSQLServer < ActiveRecord::TestCase
end
end

describe 'joining tables' do

it 'joined tables use updlock by default' do
assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\) INNER JOIN \[readers\] WITH\(UPDLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
Person.lock(true).joins(:readers).load
end
end

it 'joined tables can use custom lock directive' do
assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(NOLOCK\) INNER JOIN \[readers\] WITH\(NOLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
Person.lock('WITH(NOLOCK)').joins(:readers).load
end
end

it 'left joined tables use updlock by default' do
assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(UPDLOCK\) LEFT OUTER JOIN \[readers\] WITH\(UPDLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
Person.lock(true).left_joins(:readers).load
end
end

it 'left joined tables can use custom lock directive' do
assert_sql %r|SELECT \[people\]\.\* FROM \[people\] WITH\(NOLOCK\) LEFT OUTER JOIN \[readers\] WITH\(NOLOCK\)\s+ON \[readers\]\.\[person_id\] = \[people\]\.\[id\]| do
Person.lock('WITH(NOLOCK)').left_joins(:readers).load
end
end

end

end

describe 'For paginated finds' do
Expand Down

0 comments on commit bc75817

Please sign in to comment.