Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions lib/bmg/sql/processor/transform.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ def on_select_list(sexpr)
}
end

AstAble = ->(t){ t.respond_to?(:to_sql_ast) }

def on_select_item(sexpr)
as = sexpr.as_name.to_sym
case t = transformation_for(as)
when NilClass
sexpr
when Class, Array
when AstAble, Class, Array
sexpr([:select_item,
func_call_node(sexpr, Array(t).reverse),
sexpr[2]
Expand All @@ -83,10 +85,15 @@ def _func_call_node(sexpr, head, tail)
else
_func_call_node(sexpr, tail.first, tail[1..-1])
end
[:func_call,
:cast,
inside,
[ :literal, head ] ]
case head
when AstAble
head.to_sql_ast(self, inside)
when Class
[:func_call,
:cast,
inside,
[ :literal, head ] ]
end
end

def transformation_for(as)
Expand Down
3 changes: 2 additions & 1 deletion lib/bmg/sql/relation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@ def _summarize(type, by, defs)
def _transform(type, transformation, options)
expr = before_use(self.expr)
sup, unsup = Processor::Transform.split_supported(transformation){|x|
[String, Integer, Float, Date, DateTime].include?(x)
[String, Integer, Float, Date, DateTime].include?(x) || \
x.respond_to?(:to_sql_ast)
}
return super if sup.nil?
expr = Processor::Transform.new(sup, options, builder).call(expr)
Expand Down
1 change: 0 additions & 1 deletion spec/integration/sequel/base/transform.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

---
- bmg: |-
supplies.transform(:qty => String)
Expand Down
99 changes: 72 additions & 27 deletions spec/unit/sql/processor/transform/test_on_select_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,86 @@ module Sql
class Processor
describe Transform, "on_select_list" do

subject{
Transform.new({
:a => Date
}, {}, Builder.new).on_select_list(expr)
}

let(:expr){
sexpr [:select_list,
[:select_item,
[:qualified_name,
[:range_var_name, "t1"],
context 'with a Date' do
subject{
Transform.new({
:a => Date
}, {}, Builder.new).on_select_list(expr)
}

let(:expr){
sexpr [:select_list,
[:select_item,
[:qualified_name,
[:range_var_name, "t1"],
[:column_name, "a"]
],
[:column_name, "a"]
]
]
}

let(:expected){
sexpr [:select_list,
[:select_item,
[:func_call,
:cast,
[:qualified_name,
[:range_var_name, "t1"],
[:column_name, "a"]
],
[ :literal, Date ]
],
[:column_name, "a"]
],
[:column_name, "a"]
]
]
]
}

let(:expected){
sexpr [:select_list,
[:select_item,
[:func_call,
:cast,
}

it{ should eq(expected) }
end

context 'with a Translatable transformation' do
class Translatable
def to_sql_ast(engine, operand)
[ :func_call, :upcase, operand ]
end
end

subject{
Transform.new({
:a => Translatable.new
}, {}, Builder.new).on_select_list(expr)
}

let(:expr){
sexpr [:select_list,
[:select_item,
[:qualified_name,
[:range_var_name, "t1"],
[:column_name, "a"]
],
[ :literal, Date ]
],
[:column_name, "a"]
[:column_name, "a"]
]
]
}

let(:expected){
sexpr [:select_list,
[:select_item,
[:func_call,
:upcase,
[:qualified_name,
[:range_var_name, "t1"],
[:column_name, "a"]
]
],
[:column_name, "a"]
]
]
]
}
}

it{ should eq(expected) }
it{ should eq(expected) }
end

end
end
Expand Down