Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Adding "partition by" support for window functions #184

Closed
wants to merge 1 commit into from

3 participants

@beedub

No description provided.

@vipulnsward

This can be closed since #163 was merged.

@matthewd matthewd closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 3, 2013
  1. @beedub
This page is out of date. Refresh to see the latest.
View
12 lib/arel/nodes/window.rb
@@ -2,10 +2,11 @@ module Arel
module Nodes
class Window < Arel::Nodes::Node
include Arel::Expression
- attr_accessor :orders, :framing
+ attr_accessor :orders, :framing, :partitions
def initialize
@orders = []
+ @partitions = []
end
def order *expr
@@ -16,6 +17,13 @@ def order *expr
self
end
+ def partition(*expr)
+ @partitions.concat expr.map { |x|
+ String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x
+ }
+ self
+ end
+
def frame(expr)
raise ArgumentError, "Window frame cannot be set more than once" if @frame
@framing = expr
@@ -75,4 +83,4 @@ def initialize(expr = nil)
end
end
end
-end
+end
View
1  lib/arel/visitors/to_sql.rb
@@ -182,6 +182,7 @@ def visit_Arel_Nodes_NamedWindow o
def visit_Arel_Nodes_Window o
s = [
+ ("PARTITION BY #{o.partitions.map { |x| visit(x) }.join(', ')}" unless o.partitions.empty?),
("ORDER BY #{o.orders.map { |x| visit(x) }.join(', ')}" unless o.orders.empty?),
(visit o.framing if o.framing)
].compact.join ' '
View
52 test/nodes/test_window.rb
@@ -0,0 +1,52 @@
+require 'helper'
+
+module Arel::Nodes
+ describe Window do
+ describe 'backwards compatibility' do
+ it 'must be an expression' do
+ Window.new.must_be_kind_of Arel::Expression
+ end
+ end
+
+ describe "order" do
+ it "should generate a single argument" do
+ table = Arel::Table.new("users")
+ Window.new.order(table[:id]).to_sql.must_be_like %{
+ (ORDER BY \"users\".\"id\")
+ }
+ end
+
+ it "should generate multiple arguments" do
+ table = Arel::Table.new("users")
+ Window.new.order(table[:id], table[:created_at]).to_sql.must_be_like %{
+ (ORDER BY \"users\".\"id\", \"users\".\"created_at\")
+ }
+ end
+ end
+
+ describe "partition" do
+ it "should generate a single argument" do
+ table = Arel::Table.new("users")
+ Window.new.partition(table[:id]).to_sql.must_be_like %{
+ (PARTITION BY \"users\".\"id\")
+ }
+ end
+
+ it "should generate multiple arguments" do
+ table = Arel::Table.new("users")
+ Window.new.partition(table[:id], table[:created_at]).to_sql.must_be_like %{
+ (PARTITION BY \"users\".\"id\", \"users\".\"created_at\")
+ }
+ end
+ end
+
+ describe "partition and order" do
+ it "should generate partition before order" do
+ table = Arel::Table.new("users")
+ Window.new.order(table[:id]).partition(table[:id]).to_sql.must_be_like %{
+ (PARTITION BY \"users\".\"id\" ORDER BY \"users\".\"id\")
+ }
+ end
+ end
+ end
+end
Something went wrong with that request. Please try again.