Skip to content

Commit d9cd0dd

Browse files
committed
fix perfomance regressions
1 parent a4e5a0e commit d9cd0dd

File tree

6 files changed

+134
-134
lines changed

6 files changed

+134
-134
lines changed

bench.exs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ SQL.Repo.__adapter__().storage_up(SQL.Repo.config())
99
SQL.Repo.start_link()
1010
sql = ~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]
1111
query = "temp" |> recursive_ctes(true) |> with_cte("temp", as: ^union_all(select("temp", [t], %{n: 0, fact: 1}), ^where(select("temp", [t], [t.n+1, t.n+1*t.fact]), [t], t.n < 9))) |> select([t], [t.n])
12-
result = Tuple.to_list(SQL.Lexer.lex("with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)", __ENV__.file))
12+
result = Tuple.to_list(SQL.Lexer.lex("with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)"))
1313
tokens = Enum.at(result, -1)
1414
context = Enum.at(result, 1)
1515
Benchee.run(
@@ -18,18 +18,14 @@ Benchee.run(
1818
"comptime to_sql" => fn _ -> SQL.to_sql(sql) end,
1919
"comptime inspect" => fn _ -> inspect(sql) end,
2020
"comptime ecto" => fn _ -> SQL.Repo.to_sql(:all, query) end,
21-
"lex" => fn _ -> SQL.Lexer.lex("with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)", __ENV__.file) end,
21+
"lex" => fn _ -> SQL.Lexer.lex("with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)") end,
2222
"parse" => fn _ -> SQL.Parser.parse(tokens, context) end,
2323
"runtime to_string" => fn _ -> to_string(~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]) end,
2424
"runtime to_sql" => fn _ -> SQL.to_sql(~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]) end,
2525
"runtime inspect" => fn _ -> inspect(~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]) end,
2626
"runtime ecto" => fn _ -> SQL.Repo.to_sql(:all, "temp" |> recursive_ctes(true) |> with_cte("temp", as: ^union_all(select("temp", [t], %{n: 0, fact: 1}), ^where(select("temp", [t], [t.n+1, t.n+1*t.fact]), [t], t.n < 9))) |> select([t], [t.n])) end
2727
},
28-
inputs: %{
29-
"Small" => Enum.to_list(1..1_000),
30-
"Medium" => Enum.to_list(1..10_000),
31-
"Bigger" => Enum.to_list(1..100_000)
32-
},
28+
inputs: %{"1..100_000" => Enum.to_list(1..100_000)},
3329
memory_time: 2,
3430
reduction_time: 2
3531
)

lib/adapters/ansi.ex

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,22 @@ defmodule SQL.Adapters.ANSI do
2323
def token_to_string({:fun, _, [left, right]}, mod) do
2424
"#{mod.token_to_string(left)}#{mod.token_to_string(right)}"
2525
end
26-
def token_to_string({:ident, [{:keyword, :non_reserved},{:tag, tag}|_], [{:paren, _, _} = value]}, mod) do
26+
def token_to_string({tag, [{:type, :operator}|_], [left, right]}, mod) do
27+
"#{mod.token_to_string(left)} #{mod.token_to_string(tag)} #{mod.token_to_string(right)}"
28+
end
29+
def token_to_string({:ident, [{:type, :non_reserved},{:tag, tag}|_], [{:paren, _, _} = value]}, mod) do
2730
"#{mod.token_to_string(tag)}#{mod.token_to_string(value)}"
2831
end
29-
def token_to_string({:ident, [{:keyword, :non_reserved}, {:tag, tag}|_], [{:numeric, _, _} = value]}, mod) do
32+
def token_to_string({:ident, [{:type, :non_reserved}, {:tag, tag}|_], [{:numeric, _, _} = value]}, mod) do
3033
"#{mod.token_to_string(tag)} #{mod.token_to_string(value)}"
3134
end
32-
def token_to_string({:ident, [{:keyword, :non_reserved}, {:tag, tag}|_], _}, mod) do
35+
def token_to_string({:ident, [{:type, :non_reserved}, {:tag, tag}|_], _}, mod) do
3336
mod.token_to_string(tag)
3437
end
35-
def token_to_string({tag, [{:keyword, :reserved}|_], [{:paren, _, _} = value]}, mod) when tag not in ~w[on as in select]a do
38+
def token_to_string({tag, [{:type, :reserved}|_], [{:paren, _, _} = value]}, mod) when tag not in ~w[on as in select]a do
3639
"#{mod.token_to_string(tag)}#{mod.token_to_string(value)}"
3740
end
38-
def token_to_string({tag, [{:keyword, :reserved}|_], []}, mod) do
41+
def token_to_string({tag, [{:type, :reserved}|_], []}, mod) do
3942
mod.token_to_string(tag)
4043
end
4144
def token_to_string({tag, _, [left, {:all = t, _, right}]}, mod) when tag in ~w[union except intersect]a do
@@ -89,13 +92,13 @@ defmodule SQL.Adapters.ANSI do
8992
def token_to_string(value, _mod) when is_integer(value) do
9093
[value]
9194
end
92-
def token_to_string({tag, _, [left, right]}, mod) when tag in ~w[:: [\] <> <= >= != || + - ^ * / % < > = like ilike as union except intersect between and or is not in cursor for to]a do
95+
def token_to_string({tag, _, [left, right]}, mod) when tag in ~w[like ilike as union except intersect between and or is not in cursor for to]a do
9396
"#{mod.token_to_string(left)} #{mod.token_to_string(tag)} #{mod.token_to_string(right)}"
9497
end
95-
def token_to_string({tag, [{:keyword, :reserved}|_], values}, mod) do
98+
def token_to_string({tag, [{:type, :reserved}|_], values}, mod) do
9699
"#{mod.token_to_string(tag)} #{mod.token_to_string(values)}"
97100
end
98-
def token_to_string({tag, [{:keyword, :non_reserved}|_], values}, mod) when tag != :ident do
101+
def token_to_string({tag, [{:type, :non_reserved}|_], values}, mod) when tag != :ident do
99102
"#{mod.token_to_string(tag)} #{mod.token_to_string(values)}"
100103
end
101104
def token_to_string({tag, _, []}, mod) do

lib/helpers.ex

Lines changed: 102 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -7,68 +7,68 @@ defmodule SQL.Helpers do
77
defguard is_newline(b) when b in [10, 11, 12, 13, 133, 8232, 8233]
88
defguard is_space(b) when b in ~c" "
99
defguard is_whitespace(b) when b in [9, 13, 160, 160, 5760, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 6158, 8203, 8204, 8205, 8288, 65279]
10-
defguard is_literal(b) when b == ?" or b == ?' or b == ?`
10+
defguard is_literal(b) when b in ~c{"'`}
1111
defguard is_expr(b) when b in [:paren, :bracket, :brace]
1212
defguard is_nested_start(b) when b in ~c"([{"
1313
defguard is_nested_end(b) when b in ~c")]}"
1414
defguard is_special_character(b) when b in ~c" \"%&'()*+,-./:;<=>?[]^_|{}$@!~#"
1515
defguard is_digit(b) when b in ~c"0123456789"
1616
defguard is_comment(b) when b in ["--", "/*"]
17-
defguard is_sign(b) when b == ?- or b == ?+
17+
defguard is_sign(b) when b in ~c"-+"
1818
defguard is_dot(b) when b == ?.
19-
defguard is_delimiter(b) when b == ?; or b == ?,
19+
defguard is_delimiter(b) when b in ~c";,"
2020

21-
defguard is_a(b) when b == 97 or b == 65
21+
defguard is_a(b) when b in ~c"aA"
2222

23-
defguard is_b(b) when b == 98 or b == 66
23+
defguard is_b(b) when b in ~c"bB"
2424

25-
defguard is_c(b) when b == 99 or b == 67
25+
defguard is_c(b) when b in ~c"cC"
2626

27-
defguard is_d(b) when b == 100 or b == 68
27+
defguard is_d(b) when b in ~c"dD"
2828

29-
defguard is_e(b) when b == 101 or b == 69
29+
defguard is_e(b) when b in ~c"eE"
3030

31-
defguard is_f(b) when b == 102 or b == 70
31+
defguard is_f(b) when b in ~c"fF"
3232

33-
defguard is_g(b) when b == 103 or b == 71
33+
defguard is_g(b) when b in ~c"gG"
3434

35-
defguard is_h(b) when b == 104 or b == 72
35+
defguard is_h(b) when b in ~c"hH"
3636

37-
defguard is_i(b) when b == 105 or b == 73
37+
defguard is_i(b) when b in ~c"iI"
3838

39-
defguard is_j(b) when b == 106 or b == 74
39+
defguard is_j(b) when b in ~c"jJ"
4040

41-
defguard is_k(b) when b == 107 or b == 75
41+
defguard is_k(b) when b in ~c"kK"
4242

43-
defguard is_l(b) when b == 108 or b == 76
43+
defguard is_l(b) when b in ~c"lL"
4444

45-
defguard is_m(b) when b == 109 or b == 77
45+
defguard is_m(b) when b in ~c"mM"
4646

47-
defguard is_n(b) when b == 110 or b == 78
47+
defguard is_n(b) when b in ~c"nN"
4848

49-
defguard is_o(b) when b == 111 or b == 79
49+
defguard is_o(b) when b in ~c"oO"
5050

51-
defguard is_p(b) when b == 112 or b == 80
51+
defguard is_p(b) when b in ~c"pP"
5252

53-
defguard is_q(b) when b == 113 or b == 81
53+
defguard is_q(b) when b in ~c"qQ"
5454

55-
defguard is_r(b) when b == 114 or b == 82
55+
defguard is_r(b) when b in ~c"rR"
5656

57-
defguard is_s(b) when b == 115 or b == 83
57+
defguard is_s(b) when b in ~c"sS"
5858

59-
defguard is_t(b) when b == 116 or b == 84
59+
defguard is_t(b) when b in ~c"tT"
6060

61-
defguard is_u(b) when b == 117 or b == 85
61+
defguard is_u(b) when b in ~c"uU"
6262

63-
defguard is_v(b) when b == 118 or b == 86
63+
defguard is_v(b) when b in ~c"vV"
6464

65-
defguard is_w(b) when b == 119 or b == 87
65+
defguard is_w(b) when b in ~c"wW"
6666

67-
defguard is_x(b) when b == 120 or b == 88
67+
defguard is_x(b) when b in ~c"xX"
6868

69-
defguard is_y(b) when b == 121 or b == 89
69+
defguard is_y(b) when b in ~c"yY"
7070

71-
defguard is_z(b) when b == 122 or b == 90
71+
defguard is_z(b) when b in ~c"zZ"
7272

7373

7474

@@ -1378,151 +1378,151 @@ defmodule SQL.Helpers do
13781378
def tag([[[[[], b1], b2], b3], b4]) when is_z(b1) and is_o(b2) and is_n(b3) and is_e(b4), do: {:non_reserved, :zone}
13791379

13801380

1381-
def tag([[[[], ?^], ?-], ?=]), do: {:operator, :"^-="}
1381+
def tag([[[[], ?^], ?-], ?=]), do: :"^-="
13821382

1383-
def tag([[[[], ?<], ?=], ?>]), do: {:operator, :"<=>"}
1383+
def tag([[[[], ?<], ?=], ?>]), do: :"<=>"
13841384

1385-
def tag([[[[], ?-], ?>], ?>]), do: {:operator, :"->>"}
1385+
def tag([[[[], ?-], ?>], ?>]), do: :"->>"
13861386

1387-
def tag([[[[], ?|], ?|], ?/]), do: {:operator, :"||/"}
1387+
def tag([[[[], ?|], ?|], ?/]), do: :"||/"
13881388

1389-
def tag([[[[], ?!], ?~], ?*]), do: {:operator, :"!~*"}
1389+
def tag([[[[], ?!], ?~], ?*]), do: :"!~*"
13901390

1391-
def tag([[[[], ?<], ?<], ?|]), do: {:operator, :"<<|"}
1391+
def tag([[[[], ?<], ?<], ?|]), do: :"<<|"
13921392

1393-
def tag([[[[], ?|], ?>], ?>]), do: {:operator, :"|>>"}
1393+
def tag([[[[], ?|], ?>], ?>]), do: :"|>>"
13941394

1395-
def tag([[[[], ?&], ?<], ?|]), do: {:operator, :"&<|"}
1395+
def tag([[[[], ?&], ?<], ?|]), do: :"&<|"
13961396

1397-
def tag([[[[], ?|], ?&], ?>]), do: {:operator, :"|&>"}
1397+
def tag([[[[], ?|], ?&], ?>]), do: :"|&>"
13981398

1399-
def tag([[[[], ??], ?-], ?|]), do: {:operator, :"?-|"}
1399+
def tag([[[[], ??], ?-], ?|]), do: :"?-|"
14001400

1401-
def tag([[[[], ??], ?|], ?|]), do: {:operator, :"?||"}
1401+
def tag([[[[], ??], ?|], ?|]), do: :"?||"
14021402

1403-
def tag([[[[], ?<], ?<], ?=]), do: {:operator, :"<<="}
1403+
def tag([[[[], ?<], ?<], ?=]), do: :"<<="
14041404

1405-
def tag([[[[], ?>], ?>], ?=]), do: {:operator, :">>="}
1405+
def tag([[[[], ?>], ?>], ?=]), do: :">>="
14061406

1407-
def tag([[[[], ?#], ?>], ?>]), do: {:operator, :"#>>"}
1407+
def tag([[[[], ?#], ?>], ?>]), do: :"#>>"
14081408

1409-
def tag([[[[], ?-], ?|], ?-]), do: {:operator, :"-|-"}
1409+
def tag([[[[], ?-], ?|], ?-]), do: :"-|-"
14101410

1411-
def tag([[[], ?&], ?&]), do: {:operator, :&&}
1411+
def tag([[[], ?&], ?&]), do: :&&
14121412

1413-
def tag([[[], ?|], ?|]), do: {:operator, :||}
1413+
def tag([[[], ?|], ?|]), do: :||
14141414

1415-
def tag([[[], ?&], ?=]), do: {:operator, :"&="}
1415+
def tag([[[], ?&], ?=]), do: :"&="
14161416

1417-
def tag([[[], ?^], ?=]), do: {:operator, :"^="}
1417+
def tag([[[], ?^], ?=]), do: :"^="
14181418

1419-
def tag([[[], ?|], ?=]), do: {:operator, :"|="}
1419+
def tag([[[], ?|], ?=]), do: :"|="
14201420

1421-
def tag([[[[], ?|], ?*], ?=]), do: {:operator, :"|*="}
1421+
def tag([[[[], ?|], ?*], ?=]), do: :"|*="
14221422

1423-
def tag([[[], ?>], ?>]), do: {:operator, :">>"}
1423+
def tag([[[], ?>], ?>]), do: :">>"
14241424

1425-
def tag([[[], ?<], ?<]), do: {:operator, :"<<"}
1425+
def tag([[[], ?<], ?<]), do: :"<<"
14261426

1427-
def tag([[[], ?-], ?>]), do: {:operator, :->}
1427+
def tag([[[], ?-], ?>]), do: :->
14281428

1429-
def tag([[[], ?:], ?=]), do: {:operator, :":="}
1429+
def tag([[[], ?:], ?=]), do: :":="
14301430

1431-
def tag([[[], ?+], ?=]), do: {:operator, :"+="}
1431+
def tag([[[], ?+], ?=]), do: :"+="
14321432

1433-
def tag([[[], ?-], ?=]), do: {:operator, :"-="}
1433+
def tag([[[], ?-], ?=]), do: :"-="
14341434

1435-
def tag([[[], ?*], ?=]), do: {:operator, :"*="}
1435+
def tag([[[], ?*], ?=]), do: :"*="
14361436

1437-
def tag([[[], ?/], ?=]), do: {:operator, :"/="}
1437+
def tag([[[], ?/], ?=]), do: :"/="
14381438

1439-
def tag([[[], ?%], ?=]), do: {:operator, :"%="}
1439+
def tag([[[], ?%], ?=]), do: :"%="
14401440

1441-
def tag([[[], ?!], ?>]), do: {:operator, :"!>"}
1441+
def tag([[[], ?!], ?>]), do: :"!>"
14421442

1443-
def tag([[[], ?!], ?<]), do: {:operator, :"!<"}
1443+
def tag([[[], ?!], ?<]), do: :"!<"
14441444

1445-
def tag([[[], ?@], ?>]), do: {:operator, :"@>"}
1445+
def tag([[[], ?@], ?>]), do: :"@>"
14461446

1447-
def tag([[[], ?<], ?@]), do: {:operator, :"<@"}
1447+
def tag([[[], ?<], ?@]), do: :"<@"
14481448

1449-
def tag([[[], ?|], ?/]), do: {:operator, :"|/"}
1449+
def tag([[[], ?|], ?/]), do: :"|/"
14501450

1451-
def tag([[[], ?^], ?@]), do: {:operator, :"^@"}
1451+
def tag([[[], ?^], ?@]), do: :"^@"
14521452

1453-
def tag([[[], ?~], ?*]), do: {:operator, :"~*"}
1453+
def tag([[[], ?~], ?*]), do: :"~*"
14541454

1455-
def tag([[[], ?!], ?~]), do: {:operator, :"!~"}
1455+
def tag([[[], ?!], ?~]), do: :"!~"
14561456

1457-
def tag([[[], ?#], ?#]), do: {:operator, :"##"}
1457+
def tag([[[], ?#], ?#]), do: :"##"
14581458

1459-
def tag([[[], ?&], ?<]), do: {:operator, :"&<"}
1459+
def tag([[[], ?&], ?<]), do: :"&<"
14601460

1461-
def tag([[[], ?&], ?>]), do: {:operator, :"&>"}
1461+
def tag([[[], ?&], ?>]), do: :"&>"
14621462

1463-
def tag([[[], ?<], ?^]), do: {:operator, :"<^"}
1463+
def tag([[[], ?<], ?^]), do: :"<^"
14641464

1465-
def tag([[[], ?>], ?^]), do: {:operator, :">^"}
1465+
def tag([[[], ?>], ?^]), do: :">^"
14661466

1467-
def tag([[[], ??], ?#]), do: {:operator, :"?#"}
1467+
def tag([[[], ??], ?#]), do: :"?#"
14681468

1469-
def tag([[[], ??], ?-]), do: {:operator, :"?-"}
1469+
def tag([[[], ??], ?-]), do: :"?-"
14701470

1471-
def tag([[[], ??], ?|]), do: {:operator, :"?|"}
1471+
def tag([[[], ??], ?|]), do: :"?|"
14721472

1473-
def tag([[[], ?~], ?=]), do: {:operator, :"~="}
1473+
def tag([[[], ?~], ?=]), do: :"~="
14741474

1475-
def tag([[[], ?@], ?@]), do: {:operator, :"@@"}
1475+
def tag([[[], ?@], ?@]), do: :"@@"
14761476

1477-
def tag([[[], ?!], ?!]), do: {:operator, :"!!"}
1477+
def tag([[[], ?!], ?!]), do: :"!!"
14781478

1479-
def tag([[[], ?#], ?>]), do: {:operator, :"#>"}
1479+
def tag([[[], ?#], ?>]), do: :"#>"
14801480

1481-
def tag([[[], ??], ?&]), do: {:operator, :"?&"}
1481+
def tag([[[], ??], ?&]), do: :"?&"
14821482

1483-
def tag([[[], ?#], ?-]), do: {:operator, :"#-"}
1483+
def tag([[[], ?#], ?-]), do: :"#-"
14841484

1485-
def tag([[[], ?@], ??]), do: {:operator, :"@?"}
1485+
def tag([[[], ?@], ??]), do: :"@?"
14861486

1487-
def tag([[[], ?:], ?:]), do: {:operator, :"::"}
1487+
def tag([[[], ?:], ?:]), do: :"::"
14881488

1489-
def tag([[[], ?<], ?>]), do: {:operator, :<>}
1489+
def tag([[[], ?<], ?>]), do: :<>
14901490

1491-
def tag([[[], ?>], ?=]), do: {:operator, :>=}
1491+
def tag([[[], ?>], ?=]), do: :>=
14921492

1493-
def tag([[[], ?<], ?=]), do: {:operator, :<=}
1493+
def tag([[[], ?<], ?=]), do: :<=
14941494

1495-
def tag([[[], ?!], ?=]), do: {:operator, :!=}
1495+
def tag([[[], ?!], ?=]), do: :!=
14961496

1497-
def tag([[], ?+]), do: {:operator, :+}
1497+
def tag([[], ?+]), do: :+
14981498

1499-
def tag([[], ?-]), do: {:operator, :-}
1499+
def tag([[], ?-]), do: :-
15001500

1501-
def tag([[], ?!]), do: {:operator, :!}
1501+
def tag([[], ?!]), do: :!
15021502

1503-
def tag([[], ?&]), do: {:operator, :&}
1503+
def tag([[], ?&]), do: :&
15041504

1505-
def tag([[], ?^]), do: {:operator, :^}
1505+
def tag([[], ?^]), do: :^
15061506

1507-
def tag([[], ?|]), do: {:operator, :|}
1507+
def tag([[], ?|]), do: :|
15081508

1509-
def tag([[], ?~]), do: {:operator, :"~"}
1509+
def tag([[], ?~]), do: :"~"
15101510

1511-
def tag([[], ?%]), do: {:operator, :%}
1511+
def tag([[], ?%]), do: :%
15121512

1513-
def tag([[], ?@]), do: {:operator, :@}
1513+
def tag([[], ?@]), do: :@
15141514

1515-
def tag([[], ?#]), do: {:operator, :"#"}
1515+
def tag([[], ?#]), do: :"#"
15161516

1517-
def tag([[], ?*]), do: {:operator, :*}
1517+
def tag([[], ?*]), do: :*
15181518

1519-
def tag([[], ?/]), do: {:operator, :/}
1519+
def tag([[], ?/]), do: :/
15201520

1521-
def tag([[], ?=]), do: {:operator, :=}
1521+
def tag([[], ?=]), do: :=
15221522

1523-
def tag([[], ?>]), do: {:operator, :>}
1523+
def tag([[], ?>]), do: :>
15241524

1525-
def tag([[], ?<]), do: {:operator, :<}
1525+
def tag([[], ?<]), do: :<
15261526

15271527
def tag(_), do: nil
15281528
end

0 commit comments

Comments
 (0)