aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2014-06-26 15:22:50 +0800
committerAaron Patterson <aaron.patterson@gmail.com>2014-06-26 15:22:50 +0800
commitebbd786945c12f65062ef5b4809b4f13643e3c52 (patch)
treea015fcbaf2ab27d88f79122889ee409940f02a73 /lib
parentf50de54a6f0c59ab75526cfdb7896830130ffdf7 (diff)
parent4a72415555de19ca33c8ea16ee9ba26d1b73b078 (diff)
downloadrails-ebbd786945c12f65062ef5b4809b4f13643e3c52.tar.gz
rails-ebbd786945c12f65062ef5b4809b4f13643e3c52.tar.bz2
rails-ebbd786945c12f65062ef5b4809b4f13643e3c52.zip
Merge pull request #163 from atombender/master
Support for PARTITION BY in window
Diffstat (limited to 'lib')
-rw-r--r--lib/arel/nodes/window.rb27
-rw-r--r--lib/arel/visitors/dot.rb2
-rw-r--r--lib/arel/visitors/to_sql.rb8
3 files changed, 33 insertions, 4 deletions
diff --git a/lib/arel/nodes/window.rb b/lib/arel/nodes/window.rb
index 60259e8c05..fee8eeff7a 100644
--- a/lib/arel/nodes/window.rb
+++ b/lib/arel/nodes/window.rb
@@ -1,10 +1,12 @@
module Arel
module Nodes
class Window < Arel::Nodes::Node
- attr_accessor :orders, :framing
+ attr_accessor :orders, :framing, :partitions
def initialize
@orders = []
+ @partitions = []
+ @framing = nil
end
def order *expr
@@ -15,16 +17,32 @@ module Arel
self
end
+ def partition *expr
+ # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically
+ @partitions.concat expr.map { |x|
+ String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x
+ }
+ self
+ end
+
def frame(expr)
@framing = expr
end
def rows(expr = nil)
- frame(Rows.new(expr))
+ if @framing
+ Rows.new(expr)
+ else
+ frame(Rows.new(expr))
+ end
end
def range(expr = nil)
- frame(Range.new(expr))
+ if @framing
+ Range.new(expr)
+ else
+ frame(Range.new(expr))
+ end
end
def initialize_copy other
@@ -39,7 +57,8 @@ module Arel
def eql? other
self.class == other.class &&
self.orders == other.orders &&
- self.framing == other.framing
+ self.framing == other.framing &&
+ self.partitions == other.partitions
end
alias :== :eql?
end
diff --git a/lib/arel/visitors/dot.rb b/lib/arel/visitors/dot.rb
index d96cf7a6a0..f0cefeabd7 100644
--- a/lib/arel/visitors/dot.rb
+++ b/lib/arel/visitors/dot.rb
@@ -82,12 +82,14 @@ module Arel
alias :visit_Arel_Nodes_Range :unary
def window o
+ visit_edge o, "partitions"
visit_edge o, "orders"
visit_edge o, "framing"
end
alias :visit_Arel_Nodes_Window :window
def named_window o
+ visit_edge o, "partitions"
visit_edge o, "orders"
visit_edge o, "framing"
visit_edge o, "name"
diff --git a/lib/arel/visitors/to_sql.rb b/lib/arel/visitors/to_sql.rb
index 7f74ebb402..8c63070084 100644
--- a/lib/arel/visitors/to_sql.rb
+++ b/lib/arel/visitors/to_sql.rb
@@ -336,12 +336,20 @@ module Arel
def visit_Arel_Nodes_Window o, collector
collector << "("
+
+ if o.partitions.any?
+ collector << "PARTITION BY "
+ collector = inject_join o.partitions, collector, ", "
+ end
+
if o.orders.any?
+ collector << ' ' if o.partitions.any?
collector << "ORDER BY "
collector = inject_join o.orders, collector, ", "
end
if o.framing
+ collector << ' ' if o.partitions.any? or o.orders.any?
collector = visit o.framing, collector
end