mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge PR #40491
This commit is contained in:
commit
21c6c225a3
8 changed files with 72 additions and 0 deletions
|
@ -1,3 +1,9 @@
|
|||
* Add support for FILTER clause (SQL:2003) to Arel.
|
||||
|
||||
Currently supported by PostgreSQL 9.4+ and SQLite 3.30+.
|
||||
|
||||
*Andrey Novikov*
|
||||
|
||||
* Automatically set timestamps on record creation during bulk insert/upsert
|
||||
|
||||
Prior to this change, only updates during an upsert operation (e.g. `upsert_all`) would touch timestamps (`updated_{at,on}`). Now, record creations also touch timestamp columns (`{created,updated}_{at,on}`).
|
||||
|
|
|
@ -7,6 +7,7 @@ require "arel/factory_methods"
|
|||
|
||||
require "arel/expressions"
|
||||
require "arel/predications"
|
||||
require "arel/filter_predications"
|
||||
require "arel/window_predications"
|
||||
require "arel/math"
|
||||
require "arel/alias_predication"
|
||||
|
|
9
activerecord/lib/arel/filter_predications.rb
Normal file
9
activerecord/lib/arel/filter_predications.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Arel
|
||||
module FilterPredications
|
||||
def filter(expr)
|
||||
Nodes::Filter.new(self, expr)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -28,6 +28,7 @@ require "arel/nodes/with"
|
|||
# binary
|
||||
require "arel/nodes/binary"
|
||||
require "arel/nodes/equality"
|
||||
require "arel/nodes/filter"
|
||||
require "arel/nodes/in"
|
||||
require "arel/nodes/join_source"
|
||||
require "arel/nodes/delete_statement"
|
||||
|
|
10
activerecord/lib/arel/nodes/filter.rb
Normal file
10
activerecord/lib/arel/nodes/filter.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Arel
|
||||
module Nodes
|
||||
class Filter < Binary
|
||||
include Arel::WindowPredications
|
||||
include Arel::AliasPredication
|
||||
end
|
||||
end
|
||||
end
|
|
@ -4,6 +4,7 @@ module Arel # :nodoc: all
|
|||
module Nodes
|
||||
class Function < Arel::Nodes::NodeExpression
|
||||
include Arel::WindowPredications
|
||||
include Arel::FilterPredications
|
||||
attr_accessor :expressions, :alias, :distinct
|
||||
|
||||
def initialize(expr, aliaz = nil)
|
||||
|
|
|
@ -245,6 +245,13 @@ module Arel # :nodoc: all
|
|||
collector << ")"
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_Filter(o, collector)
|
||||
visit o.left, collector
|
||||
collector << " FILTER (WHERE "
|
||||
visit o.right, collector
|
||||
collector << ")"
|
||||
end
|
||||
|
||||
def visit_Arel_Nodes_Rows(o, collector)
|
||||
if o.expr
|
||||
collector << "ROWS "
|
||||
|
|
37
activerecord/test/cases/arel/nodes/filter_test.rb
Normal file
37
activerecord/test/cases/arel/nodes/filter_test.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../helper"
|
||||
|
||||
module Arel
|
||||
module Nodes
|
||||
class ::FilterTest < Arel::Spec
|
||||
describe "Filter" do
|
||||
it "should add filter to expression" do
|
||||
table = Arel::Table.new :users
|
||||
_(table[:id].count.filter(table[:income].gteq(40_000)).to_sql).must_be_like %{
|
||||
COUNT("users"."id") FILTER (WHERE "users"."income" >= 40000)
|
||||
}
|
||||
end
|
||||
|
||||
describe "as" do
|
||||
it "should alias the expression" do
|
||||
table = Arel::Table.new :users
|
||||
_(table[:id].count.filter(table[:income].gteq(40_000)).as("rich_users_count").to_sql).must_be_like %{
|
||||
COUNT("users"."id") FILTER (WHERE "users"."income" >= 40000) AS rich_users_count
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "over" do
|
||||
it "should reference the window definition by name" do
|
||||
table = Arel::Table.new :users
|
||||
window = Arel::Nodes::Window.new.partition(table[:year])
|
||||
_(table[:id].count.filter(table[:income].gteq(40_000)).over(window).to_sql).must_be_like %{
|
||||
COUNT("users"."id") FILTER (WHERE "users"."income" >= 40000) OVER (PARTITION BY "users"."year")
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue