Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/arel/visitors/sqlserver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,19 @@ def visit_Arel_Nodes_OuterJoin o, collector
visit o.right, collector
end

# Need to remove ordering from subqueries unless TOP/OFFSET also used. Otherwise, SQLServer
# returns error "The ORDER BY clause is invalid in views, inline functions, derived tables,
# subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified."
def collect_in_clause(left, right, collector)
if Array === right
right.each { |node| remove_invalid_ordering_from_in_clause(node) }
else
remove_invalid_ordering_from_in_clause(right)
end

super
end

# SQLServer ToSql/Visitor (Additions)

def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
Expand Down Expand Up @@ -219,6 +232,11 @@ def remote_server_table_name o
).quoted
end

def remove_invalid_ordering_from_in_clause(node)
return unless Arel::Nodes::SelectStatement === node

node.orders = [] unless node.offset || node.limit
end
end
end
end
34 changes: 34 additions & 0 deletions test/cases/in_clause_test_sqlserver.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'cases/helper_sqlserver'
require 'models/post'
require 'models/author'

class InClauseTestSQLServer < ActiveRecord::TestCase
fixtures :posts, :authors

it 'removes ordering from subqueries' do
authors_subquery = Author.where(name: ['David', 'Mary', 'Bob']).order(:name)
posts = Post.where(author: authors_subquery)

assert_includes authors_subquery.to_sql, "ORDER BY [authors].[name]"
assert_not_includes posts.to_sql, "ORDER BY [authors].[name]"
assert_equal 10, posts.length
end

it 'does not remove ordering from subquery that includes a limit' do
authors_subquery = Author.where(name: ['David', 'Mary', 'Bob']).order(:name).limit(2)
posts = Post.where(author: authors_subquery)

assert_includes authors_subquery.to_sql, "ORDER BY [authors].[name]"
assert_includes posts.to_sql, "ORDER BY [authors].[name]"
assert_equal 7, posts.length
end

it 'does not remove ordering from subquery that includes an offset' do
authors_subquery = Author.where(name: ['David', 'Mary', 'Bob']).order(:name).offset(1)
posts = Post.where(author: authors_subquery)

assert_includes authors_subquery.to_sql, "ORDER BY [authors].[name]"
assert_includes posts.to_sql, "ORDER BY [authors].[name]"
assert_equal 8, posts.length
end
end