From dd23d992ec7c44023e6ef5b2b228394cc698019a Mon Sep 17 00:00:00 2001 From: Nick Veys Date: Wed, 21 May 2014 14:59:43 -0500 Subject: [PATCH 1/3] Adding test for count w/distinct and order --- test/cases/finder_test_sqlserver.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/cases/finder_test_sqlserver.rb b/test/cases/finder_test_sqlserver.rb index beb0162be..ae0971a67 100644 --- a/test/cases/finder_test_sqlserver.rb +++ b/test/cases/finder_test_sqlserver.rb @@ -34,6 +34,23 @@ def test_find_with_order_on_included_associations_with_construct_finder_sql_for_ ) end + def test_multiple_select_with_count_distinct_and_order + posts = Post.joins(:authors) + .select('COUNT(DISTINCT authors.id) as total') + .select('title as x, body as y') + .group(:title, :body) + .order(:title).to_a + + # quick sanity check, known number of records were returned + assert_equal(3, posts.size) + + # the defined aliases should be present + post = posts.first + assert_respond_to(post, :total) + assert_respond_to(post, :x) + assert_respond_to(post, :y) + end + def test_coerced_exists_does_not_select_columns_without_alias assert_sql(/SELECT TOP \(1\) 1 AS one FROM \[topics\]/i) do Topic.exists? From 94ed463c6248bf1e01b01cafdfa175b2e579bb11 Mon Sep 17 00:00:00 2001 From: Nick Veys Date: Wed, 21 May 2014 13:24:47 -0500 Subject: [PATCH 2/3] Remove aliases from PARTITION BY value expression --- lib/arel/visitors/sqlserver.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index d230684e7..b06c89a12 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -76,6 +76,9 @@ def visit_Arel_Nodes_SelectStatementDistinctNonPresentOrders(o, a) projection_list = projections.map { |x| projection_to_sql_remove_distinct(x, core, a) }.join(', ') + # strip aliases from projection list for PARTITION BY value expression + partitions = projection_list.gsub(/\s+AS\s+[^,]*/i, '') + sql = [ ('SELECT'), (visit(core.set_quantifier, a) if core.set_quantifier && !o.offset), @@ -90,7 +93,7 @@ def visit_Arel_Nodes_SelectStatementDistinctNonPresentOrders(o, a) ("ORDER BY #{orders.map { |x| visit(x, a) }.join(', ')}" unless orders.empty?), (') AS __order'), (', ROW_NUMBER() OVER ('), - ("PARTITION BY #{projection_list}" if !orders.empty?), + ("PARTITION BY #{partitions}" if !orders.empty?), (" ORDER BY #{orders.map { |x| visit(x, a) }.join(', ')}" unless orders.empty?), (') AS __joined_row_num') ].join('') From 36dbb7cddf7cffe87eb645ee40e1ba3e99a8bae7 Mon Sep 17 00:00:00 2001 From: Nick Veys Date: Wed, 21 May 2014 13:22:49 -0500 Subject: [PATCH 3/3] Support multiple aliased projections in select --- lib/arel/visitors/sqlserver.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/arel/visitors/sqlserver.rb b/lib/arel/visitors/sqlserver.rb index b06c89a12..783d4f780 100644 --- a/lib/arel/visitors/sqlserver.rb +++ b/lib/arel/visitors/sqlserver.rb @@ -60,6 +60,9 @@ def visit_Arel_Nodes_SelectStatementDistinctNonPresentOrders(o, a) groups = core.groups orders = o.orders.uniq + # split out any projections that may have > 1 specified (comma-separated) + projections = projections.each_with_object(',').map(&:split).flatten + select_frags = projections.map do |x| frag = projection_to_sql_remove_distinct(x, core, a) # Remove the table specifier