Skip to content

Commit ad5c3dc

Browse files
committed
Fix ordering on an aggregate in MSSQL
Ensure that an order clause which contains aggregate functions does not get manipulated. This should fix #532
1 parent f54152f commit ad5c3dc

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

lib/arjdbc/mssql/limit_helpers.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module LimitHelpers
44

55
# @private
66
FIND_SELECT = /\b(SELECT(\s+DISTINCT)?)\b(.*)/mi
7+
FIND_AGGREGATE_FUNCTIONS = /AVG|COUNT|COUNT_BIG|MAX|MIN|SUM|STDDEV|STDEVP|VAR|VARP/
78

89
module SqlServerReplaceLimitOffset
910

@@ -28,8 +29,10 @@ def replace_limit_offset!(sql, limit, offset, order)
2829
# ActiveRecord::StatementInvalid: ActiveRecord::JDBCError: Column 'users.id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
2930
# SELECT t.* FROM ( SELECT ROW_NUMBER() OVER(ORDER BY users.id) AS _row_num, [users].[lft], COUNT([users].[lft]) FROM [users] GROUP BY [users].[lft] HAVING COUNT([users].[lft]) > 1 ) AS t WHERE t._row_num BETWEEN 1 AND 1
3031
if rest_of_query.downcase.include?('group by')
31-
if order.count(',') == 0
32-
order.gsub!(/ORDER BY (.*)/, 'ORDER BY MIN(\1)')
32+
if order.match(/^ORDER +BY +(#{FIND_AGGREGATE_FUNCTIONS})\(/i)
33+
# do nothing
34+
elsif order.count(',') == 0
35+
order.gsub!(/ORDER +BY +([^\s]+)(\s+ASC|\s+DESC)?/i, 'ORDER BY MIN(\1)\2')
3336
else
3437
raise('Only one order condition allowed.')
3538
end

0 commit comments

Comments
 (0)