Skip to content

Commit 5656098

Browse files
committed
Implemented optimizer hints
1 parent 9018912 commit 5656098

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
#### Added
1212

1313
- [#855](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/855) Add helpers to create/change/drop a schema.
14-
- [#857](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/857) Included WAITFOR as read query type.
14+
- [#857](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/857) Included WAITFOR as read query type.
15+
- [#864](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/864) Implemented optimizer hints.
1516

1617
## v6.0.1
1718

lib/active_record/connection_adapters/sqlserver_adapter.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ def supports_insert_conflict_target?
176176
false
177177
end
178178

179+
def supports_optimizer_hints?
180+
true
181+
end
182+
179183
def disable_referential_integrity
180184
tables = tables_with_referential_integrity
181185
tables.each { |t| do_execute "ALTER TABLE #{quote_table_name(t)} NOCHECK CONSTRAINT ALL" }

lib/arel/visitors/sqlserver.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,20 @@ def collect_in_clause(left, right, collector)
144144
super
145145
end
146146

147+
def visit_Arel_Nodes_SelectCore(o, collector)
148+
collector = super
149+
maybe_visit o.optimizer_hints, collector
150+
end
151+
152+
def visit_Arel_Nodes_OptimizerHints(o, collector)
153+
hints = o.expr.map { |v| sanitize_as_sql_comment(v) }.join(", ")
154+
collector << "OPTION (#{hints})"
155+
end
156+
157+
def collect_optimizer_hints(o, collector)
158+
collector
159+
end
160+
147161
# SQLServer ToSql/Visitor (Additions)
148162

149163
def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# frozen_string_literal: true
2+
3+
require "cases/helper_sqlserver"
4+
require "models/post"
5+
6+
class OptimizerHintsTestSQLServer < ActiveRecord::TestCase
7+
fixtures :posts
8+
9+
def test_optimizer_hints
10+
expected_sql = "SELECT [posts].* FROM [posts] OPTION (MAXDOP 2)"
11+
current_sql = Post.optimizer_hints("MAXDOP 2").to_sql
12+
assert_equal expected_sql, current_sql
13+
end
14+
15+
def test_multiple_optimizer_hints
16+
expected_sql = "SELECT [posts].* FROM [posts] OPTION (MAXDOP 2, KEEPFIXED PLAN)"
17+
current_sql = Post.optimizer_hints("MAXDOP 2").optimizer_hints("KEEPFIXED PLAN").to_sql
18+
assert_equal expected_sql, current_sql
19+
end
20+
21+
def test_optimizer_hints_with_count_subquery
22+
assert_sql(%r{.*'SELECT COUNT\(count_column\) FROM \(SELECT .*\) subquery_for_count OPTION \(MAXDOP 2\)'.*}) do
23+
posts = Post.optimizer_hints("MAXDOP 2")
24+
posts = posts.select(:id).where(author_id: [0, 1]).limit(5)
25+
assert_equal 5, posts.count
26+
end
27+
end
28+
29+
def test_optimizer_hints_with_unscope
30+
expected_sql = "SELECT [posts].* FROM [posts]"
31+
current_sql = Post.optimizer_hints("MAXDOP 2").unscope(:optimizer_hints).to_sql
32+
assert_equal expected_sql, current_sql
33+
end
34+
end

0 commit comments

Comments
 (0)