1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Add #extract, which produces ANSI SQL function EXTRACT(<field> from <expr>).

This commit is contained in:
Alexander Staubo 2012-02-23 14:06:05 +01:00
parent a1a6fbc189
commit 2db4ec6a28
6 changed files with 57 additions and 0 deletions

View file

@ -19,5 +19,9 @@ module Arel
def average
Nodes::Avg.new [self], Nodes::SqlLiteral.new('avg_id')
end
def extract field
Nodes::Extract.new [self], field
end
end
end

View file

@ -36,6 +36,7 @@ require 'arel/nodes/and'
# We should make Function a Unary node and deprecate the use of "aliaz"
require 'arel/nodes/function'
require 'arel/nodes/count'
require 'arel/nodes/extract'
require 'arel/nodes/values'
require 'arel/nodes/named_function'

23
lib/arel/nodes/extract.rb Normal file
View file

@ -0,0 +1,23 @@
module Arel
module Nodes
class Extract < Arel::Nodes::Unary
include Arel::Expression
include Arel::Predications
attr_accessor :field
attr_accessor :alias
def initialize expr, field, aliaz = nil
super(expr)
@field = field
@alias = aliaz && SqlLiteral.new(aliaz)
end
def as aliaz
self.alias = SqlLiteral.new(aliaz)
self
end
end
end
end

View file

@ -103,6 +103,12 @@ module Arel
alias :visit_Arel_Nodes_Avg :function
alias :visit_Arel_Nodes_Sum :function
def extract o
visit_edge o, "expressions"
visit_edge o, "alias"
end
alias :visit_Arel_Nodes_Extract :extract
def visit_Arel_Nodes_NamedFunction o
visit_edge o, "name"
visit_edge o, "expressions"

View file

@ -272,6 +272,10 @@ key on UpdateManager using UpdateManager#key=
}.join(', ')})#{o.alias ? " AS #{visit o.alias}" : ''}"
end
def visit_Arel_Nodes_Extract o
"EXTRACT(#{o.field.to_s.upcase} FROM #{visit o.expr})#{o.alias ? " AS #{visit o.alias}" : ''}"
end
def visit_Arel_Nodes_Count o
"COUNT(#{o.distinct ? 'DISTINCT ' : ''}#{o.expressions.map { |x|
visit x

View file

@ -0,0 +1,19 @@
require 'helper'
describe Arel::Nodes::Extract do
it "should extract field" do
table = Arel::Table.new :users
table[:timestamp].extract('date').to_sql.must_be_like %{
EXTRACT(DATE FROM "users"."timestamp")
}
end
describe "as" do
it 'should alias the extract' do
table = Arel::Table.new :users
table[:timestamp].extract('date').as('foo').to_sql.must_be_like %{
EXTRACT(DATE FROM "users"."timestamp") AS foo
}
end
end
end