Skip to content

Commit

Permalink
Fix using filter with block in function syntax
Browse files Browse the repository at this point in the history
We had unit tests before but it wasn't enough, I've stumbled upon it recently.
  • Loading branch information
flash-gordon committed May 6, 2024
1 parent 7ae2d88 commit 58f589d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
4 changes: 2 additions & 2 deletions lib/rom/sql/projection_dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def `(value)
#
# @api public
def function(name, *attrs)
::ROM::SQL::Function.new(::ROM::Types::Any, schema: schema).public_send(name, *attrs)
::ROM::SQL::Function.new(::ROM::Types::Any).meta(schema: schema).public_send(name, *attrs)
end
alias_method :f, :function

Expand All @@ -57,7 +57,7 @@ def method_missing(meth, *args, &block)

if type
if args.empty?
::ROM::SQL::Function.new(type, schema: schema)
::ROM::SQL::Function.new(type).meta(schema: schema)
else
::ROM::SQL::Attribute[type].value(args[0])
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rom/sql/restriction_dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def method_missing(meth, *args, &block)
type = type(meth)

if type
::ROM::SQL::Function.new(type)
::ROM::SQL::Function.new(type).meta(schema: schema)
else
::Sequel::VIRTUAL_ROW.__send__(meth, *args, &block)
end
Expand Down
26 changes: 21 additions & 5 deletions spec/unit/projection_dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@
expect(literals).to eql([%(IF(("id" > 0), "id", NULL) AS "id")])
end

it 'supports functions with arg being a qualified attribute' do
literals = dsl
.call { function(:count, :id).filter { id > 0 }.as(:count) }
.map { |attr| attr.sql_literal(ds) }

expect(literals).to eql([%(COUNT("id") FILTER (WHERE ("id" > 0)) AS "count")])
end

it 'supports functions with arg being a qualified attribute' do
literals = dsl
.call { integer::count(id.qualified).as(:count) }
Expand Down Expand Up @@ -128,17 +136,25 @@
end

it 'responds to methods matching type identifiers' do
expect(dsl.integer).to eql(ROM::SQL::Types::Integer)
expect(dsl.string).to eql(ROM::SQL::Types::String)
expect(dsl.bool).to eql(ROM::SQL::Types::Bool)
expect(dsl.integer).to eql(ROM::SQL::Function.new(
ROM::SQL::Types::Integer
).meta(schema: schema))
expect(dsl.string).to eql(ROM::SQL::Function.new(
ROM::SQL::Types::String
).meta(schema: schema))
expect(dsl.bool).to eql(ROM::SQL::Function.new(
ROM::SQL::Types::Bool
).meta(schema: schema))
end

it 'responds to methods matching type names' do
expect(dsl.DateTime).to eql(ROM::SQL::Types::DateTime)
expect(dsl.DateTime).to eql(
ROM::SQL::Function.new(ROM::SQL::Types::DateTime).meta(schema: schema)
)
end

it 'returns sql functions with return type specified' do
function = ROM::SQL::Function.new(ROM::SQL::Types::String).upper(schema[:name])
function = ROM::SQL::Function.new(ROM::SQL::Types::String).meta(schema: schema).upper(schema[:name])

expect(dsl.string::upper(schema[:name])).to eql(function)
end
Expand Down
6 changes: 6 additions & 0 deletions spec/unit/restriction_dsl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
it 'evaluates the block and returns an SQL expression' do
expect(conn[:users].literal(dsl.call { count(id) >= 3 })).to eql('(count(`id`) >= 3)')
end

it "supports using blocks in filter clause" do
expect(conn[:users].literal(dsl.call { integer.count(id).filter { id > 0 } >= 3 })).to eql(
"(COUNT(`id`) FILTER (WHERE (`id` > 0)) >= 3)"
)
end
end

describe '#method_missing' do
Expand Down

0 comments on commit 58f589d

Please sign in to comment.