Skip to content

Commit 455ecad

Browse files
committed
[Rails3] Specific SQL build/change for eager limiting.
1 parent d295b2e commit 455ecad

File tree

2 files changed

+28
-11
lines changed

2 files changed

+28
-11
lines changed

RAILS3_NOTES

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,7 @@
212212
end
213213
end
214214

215-
def order_to_min_set(order)
216-
orders_dirs = orders_and_dirs_set(order)
217-
orders_dirs.map do |o,d|
218-
"MIN(#{o}) #{d}".strip
219-
end.join(', ')
220-
end
215+
221216

222217
context 'dealing with various orders SQL snippets' do
223218

@@ -274,8 +269,12 @@
274269
sql << "GROUP BY #{columns} ORDER BY #{order_to_min_set(options[:order])}"
275270
end
276271

277-
278-
272+
def order_to_min_set(order)
273+
orders_dirs = orders_and_dirs_set(order)
274+
orders_dirs.map do |o,d|
275+
"MIN(#{o}) #{d}".strip
276+
end.join(', ')
277+
end
279278

280279
def orders_and_dirs_set(order)
281280
orders = order.sub('ORDER BY','').split(',').map(&:strip).reject(&:blank?)

lib/arel/engines/sql/compilers/sqlserver_compiler.rb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ def taken_clause
4545
"TOP (#{relation.taken.to_i}) "
4646
end
4747

48+
def eager_limiting_select?
49+
single_distinct_select? && taken_only? && relation.group_clauses.blank?
50+
end
51+
4852
def single_distinct_select?
4953
relation.select_clauses.size == 1 && relation.select_clauses.first.include?('DISTINCT')
5054
end
@@ -87,10 +91,24 @@ def select_sql_without_skipped(windowed=false)
8791
groups = relation.group_clauses
8892
havings = relation.having_clauses
8993
orders = relation.order_clauses
90-
select_clause = windowed ? selects.map{ |sc| select_clause_without_expression(sc) }.join(', ') :
91-
"SELECT #{taken_clause if taken_only?}#{selects.join(', ')}"
94+
if windowed
95+
selects = selects.map{ |sc| select_clause_without_expression(sc) }
96+
elsif eager_limiting_select?
97+
groups = selects.map { |sc| select_clause_without_expression(sc) }
98+
selects = selects.map { |sc| "#{taken_clause}#{select_clause_without_expression(sc)}" }
99+
orders = orders.map do |oc|
100+
oc.split(',').reject(&:blank?).map do |c|
101+
max = c =~ /desc\s*/i
102+
c = select_clause_without_expression(c).sub(/(asc|desc)/i,'').strip
103+
max ? "MAX(#{c})" : "MIN(#{c})"
104+
end.join(', ')
105+
end
106+
elsif taken_only?
107+
fsc = "#{taken_clause}#{selects.first}"
108+
selects = selects.tap { |sc| sc.shift ; sc.unshift(fsc) }
109+
end
92110
build_query(
93-
select_clause,
111+
(windowed ? selects.join(', ') : "SELECT #{selects.join(', ')}"),
94112
"FROM #{relation.from_clauses}",
95113
(locked unless locked.blank?),
96114
(joins unless joins.blank?),

0 commit comments

Comments
 (0)