Skip to content

Commit 2e57fe4

Browse files
committed
In clause cannot use ordering
Added tests and don't remove ordering if limit or offset Removed debug Cleanup In clause cannot use ordering Added tests and don't remove ordering if limit or offset Update sqlserver.rb
1 parent b10e2b2 commit 2e57fe4

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

lib/arel/visitors/sqlserver.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,19 @@ def visit_Arel_Nodes_OuterJoin o, collector
127127
visit o.right, collector
128128
end
129129

130+
# Need to remove ordering from subqueries unless TOP/OFFSET also used. Otherwise, SQLServer
131+
# returns error "The ORDER BY clause is invalid in views, inline functions, derived tables,
132+
# subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified."
133+
def collect_in_clause(left, right, collector)
134+
if Array === right
135+
right.each { |node| remove_invalid_ordering_from_in_clause(node) }
136+
else
137+
remove_invalid_ordering_from_in_clause(right)
138+
end
139+
140+
super
141+
end
142+
130143
# SQLServer ToSql/Visitor (Additions)
131144

132145
def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
@@ -219,6 +232,11 @@ def remote_server_table_name o
219232
).quoted
220233
end
221234

235+
def remove_invalid_ordering_from_in_clause(node)
236+
return unless Arel::Nodes::SelectStatement === node
237+
238+
node.orders = [] unless node.offset || node.limit
239+
end
222240
end
223241
end
224242
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
require 'cases/helper_sqlserver'
2+
require 'models/post'
3+
require 'models/author'
4+
5+
class InClauseTestSQLServer < ActiveRecord::TestCase
6+
fixtures :posts, :authors
7+
8+
it 'removes ordering from subqueries' do
9+
authors_subquery = Author.where(name: ['David', 'Mary', 'Bob']).order(:name)
10+
posts = Post.where(author: authors_subquery)
11+
12+
assert_includes authors_subquery.to_sql, "ORDER BY [authors].[name]"
13+
assert_not_includes posts.to_sql, "ORDER BY [authors].[name]"
14+
assert_equal 10, posts.length
15+
end
16+
17+
it 'does not remove ordering from subquery that includes a limit' do
18+
authors_subquery = Author.where(name: ['David', 'Mary', 'Bob']).order(:name).limit(2)
19+
posts = Post.where(author: authors_subquery)
20+
21+
assert_includes authors_subquery.to_sql, "ORDER BY [authors].[name]"
22+
assert_includes posts.to_sql, "ORDER BY [authors].[name]"
23+
assert_equal 7, posts.length
24+
end
25+
26+
it 'does not remove ordering from subquery that includes an offset' do
27+
authors_subquery = Author.where(name: ['David', 'Mary', 'Bob']).order(:name).offset(1)
28+
posts = Post.where(author: authors_subquery)
29+
30+
assert_includes authors_subquery.to_sql, "ORDER BY [authors].[name]"
31+
assert_includes posts.to_sql, "ORDER BY [authors].[name]"
32+
assert_equal 8, posts.length
33+
end
34+
end

0 commit comments

Comments
 (0)