From 0932f7c479cc0841f4e77574a0e2c14b41a806ed Mon Sep 17 00:00:00 2001 From: Steven Wallace Date: Fri, 25 Oct 2024 23:15:32 -0500 Subject: [PATCH 1/2] Fixed ordering of optimizer hints. --- lib/arel/visitors/sqlserver.rb | 11 ++++++----- test/cases/optimizer_hints_test_sqlserver.rb | 9 +++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index b4cef188d..7411c2b31 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -134,26 +134,27 @@ def visit_Arel_Nodes_HomogeneousIn(o, collector) def visit_Arel_Nodes_SelectStatement(o, collector) @select_statement = o + optimizer_hints = nil distinct_One_As_One_Is_So_Not_Fetch o if o.with collector = visit o.with, collector collector << " " end collector = o.cores.inject(collector) { |c, x| + if x.is_a? Arel::Nodes::SelectCore + # optimizer hints in SQL Server have to be at the very end of the query, so we need to hold onto these for now + optimizer_hints = x.optimizer_hints + end visit_Arel_Nodes_SelectCore(x, c) } collector = visit_Orders_And_Let_Fetch_Happen o, collector collector = visit_Make_Fetch_Happen o, collector + collector = maybe_visit optimizer_hints, collector collector ensure @select_statement = nil end - def visit_Arel_Nodes_SelectCore(o, collector) - collector = super - maybe_visit o.optimizer_hints, collector - end - def visit_Arel_Nodes_OptimizerHints(o, collector) hints = o.expr.map { |v| sanitize_as_option_clause(v) }.join(", ") collector << "OPTION (#{hints})" diff --git a/test/cases/optimizer_hints_test_sqlserver.rb b/test/cases/optimizer_hints_test_sqlserver.rb index 97752f36c..46f13ac0d 100644 --- a/test/cases/optimizer_hints_test_sqlserver.rb +++ b/test/cases/optimizer_hints_test_sqlserver.rb @@ -36,6 +36,15 @@ class OptimizerHitsTestSQLServer < ActiveRecord::TestCase end end + + it "support order" do + assert_queries_match(%r{\ASELECT .+ FROM .+ ORDER .+ OPTION .+\z}) do + companies = Company.optimizer_hints("LABEL='FindCompanies'") + companies = companies.order(:id) + companies.to_a + end + end + it "sanitize values" do assert_queries_match(%r{\ASELECT .+ FROM .+ OPTION \(HASH GROUP\)\z}) do companies = Company.optimizer_hints("OPTION (HASH GROUP)") From eac917f8778a96e228d9d262f353569e70dd23eb Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Fri, 8 Nov 2024 13:57:11 +0000 Subject: [PATCH 2/2] Cleanup and updated CHANGELOG --- CHANGELOG.md | 1 + lib/arel/visitors/sqlserver.rb | 11 ++++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae573f62d..69ab388b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [#1244](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1244) Allow INSERT statements with SELECT notation - [#1247](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1247) Fix queries with date and date-time placeholder conditions - [#1249](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1249) Binary basic columns should be limitable +- [#1255](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1255)Fixed the ordering of optimizer hints in the generated SQL ## v7.2.1 diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index 7411c2b31..5890b7fc3 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -140,13 +140,10 @@ def visit_Arel_Nodes_SelectStatement(o, collector) collector = visit o.with, collector collector << " " end - collector = o.cores.inject(collector) { |c, x| - if x.is_a? Arel::Nodes::SelectCore - # optimizer hints in SQL Server have to be at the very end of the query, so we need to hold onto these for now - optimizer_hints = x.optimizer_hints - end - visit_Arel_Nodes_SelectCore(x, c) - } + collector = o.cores.inject(collector) do |collect, core| + optimizer_hints = core.optimizer_hints if core.optimizer_hints + visit_Arel_Nodes_SelectCore(core, collect) + end collector = visit_Orders_And_Let_Fetch_Happen o, collector collector = visit_Make_Fetch_Happen o, collector collector = maybe_visit optimizer_hints, collector