From 408d3f196e5aee90745f1da3f7290b8d1d84c988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Tersl=C3=B8v=20Forsberg?= Date: Wed, 22 Jul 2015 16:43:59 +0200 Subject: [PATCH 1/6] Call expr/2 on call tuple in param/1 --- src/sqerl.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sqerl.erl b/src/sqerl.erl index c1d95d6..bb0ce10 100644 --- a/src/sqerl.erl +++ b/src/sqerl.erl @@ -432,6 +432,8 @@ param({Key, Value}) when is_atom(Key) -> [convert(Key), <<" := ">>, encode(Value)]; param(Key) when is_atom(Key) -> convert(Key); +param({call, _FuncName, _Params} = Call) -> + expr(Call, undefined); param(Value) -> encode(Value). From 368fdaa937c8d5cc275d9768b7a33cb243e75517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Tersl=C3=B8v=20Forsberg?= Date: Wed, 22 Jul 2015 17:13:45 +0200 Subject: [PATCH 2/6] Match call tuples in {Key, Value} case of param/1 --- src/sqerl.erl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sqerl.erl b/src/sqerl.erl index bb0ce10..307edb3 100644 --- a/src/sqerl.erl +++ b/src/sqerl.erl @@ -429,7 +429,12 @@ expr2(Expr, _Safe) when is_atom(Expr) -> convert(Expr); expr2(Expr, Safe) -> expr(Expr, Safe). param({Key, Value}) when is_atom(Key) -> - [convert(Key), <<" := ">>, encode(Value)]; + case Value of + {call, _FuncName, _Params} = Call -> + [convert(Key), <<" := ">>, expr(Call, undefined)]; + _ -> + [convert(Key), <<" := ">>, encode(Value)] + end; param(Key) when is_atom(Key) -> convert(Key); param({call, _FuncName, _Params} = Call) -> From 359ef1059340ecf55ac4ccc7170a7f105b5d6327 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Tersl=C3=B8v=20Forsberg?= Date: Wed, 22 Jul 2015 17:15:23 +0200 Subject: [PATCH 3/6] Added eunit test cases for nested call handling --- test/sqerl_tests.erl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/sqerl_tests.erl b/test/sqerl_tests.erl index baff481..aba665f 100644 --- a/test/sqerl_tests.erl +++ b/test/sqerl_tests.erl @@ -186,6 +186,14 @@ safe_test_() -> {<<"SELECT name FROM search_people(age := 18)">>, ?_safe_test({select,name,{from,{call,search_people,[{age, 18}]}}}) + }, + + {<<"SELECT * FROM search_people(age := 18, area := postal_area(code := 1234))">>, + ?_safe_test({select,'*',{from,{call,search_people,[{age, 18},{area,{call,postal_area,[{code, 1234}]}}]}}}) + }, + + {<<"SELECT * FROM outer_function(column1, inner_function())">>, + ?_safe_test({select,'*',{from,{call,outer_function,[column1,{call,inner_function,[]}]}}}) } ] }. From 680356ba55b82519f2c641f2a9dcc186789071ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Tersl=C3=B8v=20Forsberg?= Date: Wed, 22 Jul 2015 17:15:51 +0200 Subject: [PATCH 4/6] (Unrelated) whitespace fix for failing eunit test --- test/sqerl_tests.erl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/sqerl_tests.erl b/test/sqerl_tests.erl index aba665f..31b491c 100644 --- a/test/sqerl_tests.erl +++ b/test/sqerl_tests.erl @@ -137,8 +137,8 @@ safe_test_() -> {select,distinct,name,{from,gymnast}}}}}) }, - {<<"SELECT name FROM developer WHERE name IN ((SELECT DISTINCT name FROM gymnast)" - "UNION (SELECT name FROM dancer WHERE ((name LIKE 'Mikhail%') OR (country = 'Russia')))" + {<<"SELECT name FROM developer WHERE name IN ((SELECT DISTINCT name FROM gymnast) " + "UNION (SELECT name FROM dancer WHERE ((name LIKE 'Mikhail%') OR (country = 'Russia'))) " "WHERE (name LIKE 'M%') ORDER BY name DESC LIMIT 5, 10)">>, ?_safe_test({select,name, {from,developer}, From 8c98e63d23c7dc46dd85c0b1615e1fd669b88ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Tersl=C3=B8v=20Forsberg?= Date: Wed, 28 Oct 2015 12:19:41 +0100 Subject: [PATCH 5/6] Added rudimentary OVER support --- src/sqerl.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sqerl.erl b/src/sqerl.erl index 307edb3..eb3162a 100644 --- a/src/sqerl.erl +++ b/src/sqerl.erl @@ -360,6 +360,8 @@ expr({call, FuncName, []}, _Safe) -> [convert(FuncName), <<"()">>]; expr({call, FuncName, Params}, _Safe) -> [convert(FuncName), $(, make_list(Params, fun param/1), $)]; +expr({over, Left, Right}, Safe) -> + [expr2(Left, Safe), <<" OVER ">>, $(, extra_clause(Right, Safe) ,$)]; expr({Val, Op, {select, _} = Subquery}, Safe) -> subquery(Val, Op, Subquery, Safe); expr({Val, Op, {select, _, _} = Subquery}, Safe) -> From 16a9b45636994ccd21dce3d536dd696befcb6fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Tersl=C3=B8v=20Forsberg?= Date: Wed, 28 Oct 2015 17:19:18 +0100 Subject: [PATCH 6/6] Added rudimentary support for (SELECT ..) AS foo --- src/sqerl.erl | 12 ++++++++++++ test/sqerl_tests.erl | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/src/sqerl.erl b/src/sqerl.erl index eb3162a..533b0e6 100644 --- a/src/sqerl.erl +++ b/src/sqerl.erl @@ -356,6 +356,18 @@ expr({Table, Field}, _Safe) when is_atom(Table), is_atom(Field) -> [convert(Table), $., convert(Field)]; expr({Expr1, as, Alias}, Safe) when is_atom(Alias) -> [expr2(Expr1, Safe), <<" AS ">>, convert(Alias)]; +expr({select, _} = Subquery, Safe) -> + [$(, sql2(Subquery, Safe), $) ]; +expr({select, _, _} = Subquery, Safe) -> + [$(, sql2(Subquery, Safe), $)]; +expr({select, _, _, _} = Subquery, Safe) -> + [$(, sql2(Subquery, Safe), $)]; +expr({select, _, _, _, _} = Subquery, Safe) -> + [$(, sql2(Subquery, Safe), $)]; +expr({select, _, _, _, _, _} = Subquery, Safe) -> + [$(, sql2(Subquery, Safe), $)]; +expr({select, _, _, _, _, _, _} = Subquery, Safe) -> + [$(, sql2(Subquery, Safe), $)]; expr({call, FuncName, []}, _Safe) -> [convert(FuncName), <<"()">>]; expr({call, FuncName, Params}, _Safe) -> diff --git a/test/sqerl_tests.erl b/test/sqerl_tests.erl index 31b491c..c4aaf37 100644 --- a/test/sqerl_tests.erl +++ b/test/sqerl_tests.erl @@ -288,6 +288,14 @@ unsafe_test_() -> {<<"SELECT NOT (foo = bar)">>, ?_unsafe_test({select,{'!',"foo = bar"}}) + }, + + {<<"SELECT row_number() OVER ( ORDER BY id DESC), bar FROM lol">>, + ?_unsafe_test({select, [{over, {call, row_number, []}, {order_by, [{id, desc}]}}, bar], {from, lol}}) + }, + + {<<"SELECT foo FROM (SELECT foo FROM bar) AS baz">>, + ?_unsafe_test({select, [foo], {from, {{select, [foo], {from, bar}}, as, baz}}}) } ] }.