Skip to content

Commit fd74ee0

Browse files
committed
refactor parser and remove deprecated code
closes #21
1 parent cf0be59 commit fd74ee0

File tree

8 files changed

+218
-558
lines changed

8 files changed

+218
-558
lines changed

lib/adapters/ansi.ex

Lines changed: 44 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,41 @@ defmodule SQL.Adapters.ANSI do
1414
def token_to_string(value, _mod) when is_struct(value) do
1515
to_string(value)
1616
end
17-
def token_to_string({:*, _, []}, _mod) do
18-
"*"
17+
def token_to_string({:as, [], [left, right]}, mod) do
18+
"#{mod.token_to_string(left)} #{mod.token_to_string(right)}"
19+
end
20+
def token_to_string({tag, _, [left]}, mod) when tag in ~w[asc desc isnull notnull]a do
21+
"#{mod.token_to_string(left)} #{mod.token_to_string(tag)}"
1922
end
2023
def token_to_string({:fun, _, [left, right]}, mod) do
2124
"#{mod.token_to_string(left)}#{mod.token_to_string(right)}"
2225
end
23-
def token_to_string({tag, _, [{:paren, _, _} = value]}, mod) when tag in ~w[numeric update]a do
24-
"#{mod.token_to_string(tag)}#{mod.token_to_string(value)}"
25-
end
2626
def token_to_string({:ident, [{:keyword, :non_reserved},{:tag, tag}|_], [{:paren, _, _} = value]}, mod) do
2727
"#{mod.token_to_string(tag)}#{mod.token_to_string(value)}"
2828
end
2929
def token_to_string({:ident, [{:keyword, :non_reserved}, {:tag, tag}|_], [{:numeric, _, _} = value]}, mod) do
3030
"#{mod.token_to_string(tag)} #{mod.token_to_string(value)}"
3131
end
32-
def token_to_string({_tag, [{:keyword, :non_reserved}|_], value}, mod) do
33-
"#{mod.token_to_string(value)}"
32+
def token_to_string({:ident, [{:keyword, :non_reserved}, {:tag, tag}|_], _}, mod) do
33+
mod.token_to_string(tag)
3434
end
35-
def token_to_string({:numeric = tag, _, []}, mod), do: mod.token_to_string(tag)
36-
def token_to_string({tag, _, value}, _mod) when tag in ~w[ident numeric]a do
37-
value
35+
def token_to_string({tag, [{:keyword, :reserved}|_], [{:paren, _, _} = value]}, mod) when tag not in ~w[on as in select]a do
36+
"#{mod.token_to_string(tag)}#{mod.token_to_string(value)}"
37+
end
38+
def token_to_string({tag, [{:keyword, :reserved}|_], []}, mod) do
39+
mod.token_to_string(tag)
40+
end
41+
def token_to_string({tag, _, [left, {:all = t, _, right}]}, mod) when tag in ~w[union except intersect]a do
42+
"#{mod.token_to_string(left)} #{mod.token_to_string(tag)} #{mod.token_to_string(t)} #{mod.token_to_string(right)}"
43+
end
44+
def token_to_string({:between = tag, _, [{:not = t, _, right}, left]}, mod) do
45+
"#{mod.token_to_string(right)} #{mod.token_to_string(t)} #{mod.token_to_string(tag)} #{mod.token_to_string(left)}"
46+
end
47+
def token_to_string({:binding, _, [idx]}, _mod) when is_integer(idx) do
48+
"?"
49+
end
50+
def token_to_string({:binding, _, value}, _mod) do
51+
"{{#{value}}}"
3852
end
3953
def token_to_string({:comment, _, value}, _mod) do
4054
"--#{value}"
@@ -55,83 +69,45 @@ defmodule SQL.Adapters.ANSI do
5569
"[#{mod.token_to_string(value)}]"
5670
end
5771
def token_to_string({:colon, _, value}, mod) do
58-
"; #{mod.token_to_string(value)}"
72+
"#{mod.token_to_string(value)};"
5973
end
6074
def token_to_string({:comma, _, value}, mod) do
6175
", #{mod.token_to_string(value)}"
6276
end
6377
def token_to_string({:dot, _, [left, right]}, mod) do
6478
"#{mod.token_to_string(left)}.#{mod.token_to_string(right)}"
6579
end
66-
def token_to_string({tag, _, []}, mod) do
67-
mod.token_to_string(tag)
68-
end
69-
def token_to_string({:join=tag, _, [right]}, mod) do
70-
"#{mod.token_to_string(tag)} #{mod.token_to_string(right)}"
71-
end
72-
def token_to_string({:join=tag, _, [{t, [{:keyword, :reserved}|_], _}=p, p1, p2, right]}, mod) when t != :as do
73-
"#{mod.token_to_string(p)} #{mod.token_to_string(p1)} #{mod.token_to_string(p2)} #{mod.token_to_string(tag)} #{mod.token_to_string(right)}"
74-
end
75-
def token_to_string({:join=tag, _, [{t, [{:keyword, :reserved}|_], _}=p, p1, right]}, mod) when t != :as do
76-
"#{mod.token_to_string(p)} #{mod.token_to_string(p1)} #{mod.token_to_string(tag)} #{mod.token_to_string(right)}"
77-
end
78-
def token_to_string({:join=tag, _, [{t, [{:keyword, :reserved}|_], _}=left, right]}, mod) when t != :as do
79-
"#{mod.token_to_string(left)} #{mod.token_to_string(tag)} #{mod.token_to_string(right)}"
80-
end
81-
def token_to_string({tag, _, [{:with = t, _, [left, right]}]}, mod) when tag in ~w[to]a do
82-
"#{mod.token_to_string(tag)} #{mod.token_to_string(left)} #{mod.token_to_string(t)} #{mod.token_to_string(right)}"
83-
end
84-
def token_to_string({tag, _, value}, mod) when tag in ~w[select from fetch limit where order offset group having with join by distinct create type drop insert alter table add into delete update start grant revoke set declare open close commit rollback references recursive outer]a do
85-
"#{mod.token_to_string(tag)} #{mod.token_to_string(value)}"
86-
end
87-
def token_to_string({:on = tag, _, [source, as, value]}, mod) do
88-
"#{mod.token_to_string(source)} #{mod.token_to_string(as)} #{mod.token_to_string(tag)} #{mod.token_to_string(value)}"
80+
def token_to_string({tag, _, value}, _mod) when tag in ~w[ident numeric]a do
81+
"#{value}"
8982
end
90-
def token_to_string({:not = tag, _, [ident | values]}, mod) when values != [] do
91-
"#{mod.token_to_string(ident)} #{mod.token_to_string(tag)} #{mod.token_to_string(values)}"
83+
def token_to_string(value, _mod) when is_atom(value) do
84+
"#{value}"
9285
end
93-
def token_to_string({tag, _, [left, [{:all = t, _, right}]]}, mod) when tag in ~w[union except intersect]a do
94-
"#{mod.token_to_string(left)} #{mod.token_to_string(tag)} #{mod.token_to_string(t)} #{mod.token_to_string(right)}"
86+
def token_to_string(value, _mod) when is_binary(value) do
87+
"'#{value}'"
9588
end
96-
def token_to_string({:between = tag, _, [{:not = t, _, right}, left]}, mod) do
97-
"#{mod.token_to_string(right)} #{mod.token_to_string(t)} #{mod.token_to_string(tag)} #{mod.token_to_string(left)}"
89+
def token_to_string(value, _mod) when is_integer(value) do
90+
[value]
9891
end
99-
def token_to_string({tag, _, [left, right]}, mod) when tag in ~w[:: [\] <> <= >= != || + - ^ * / % < > = like ilike as union except intersect between and or on is not in cursor for to]a do
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
10093
"#{mod.token_to_string(left)} #{mod.token_to_string(tag)} #{mod.token_to_string(right)}"
10194
end
102-
def token_to_string({tag, _, [{:paren, _, _} = value]}, mod) when tag not in ~w[in on]a do
103-
"#{mod.token_to_string(tag)}#{mod.token_to_string(value)}"
104-
end
105-
def token_to_string({tag, _, values}, mod) when tag in ~w[not all between asymmetric symmetric absolute relative forward backward on in for without]a do
95+
def token_to_string({tag, [{:keyword, :reserved}|_], values}, mod) do
10696
"#{mod.token_to_string(tag)} #{mod.token_to_string(values)}"
10797
end
108-
def token_to_string({tag, _, [left]}, mod) when tag in ~w[asc desc isnull notnull not]a do
109-
"#{mod.token_to_string(left)} #{mod.token_to_string(tag)}"
110-
end
111-
def token_to_string({:binding, _, [idx]}, _mod) when is_integer(idx) do
112-
"?"
113-
end
114-
def token_to_string({:binding, _, value}, _mod) do
115-
"{{#{value}}}"
116-
end
117-
def token_to_string(:*, _mod) do
118-
"*"
119-
end
120-
def token_to_string(value, _mod) when is_atom(value) do
121-
"#{value}"
98+
def token_to_string({tag, [{:keyword, :non_reserved}|_], values}, mod) when tag != :ident do
99+
"#{mod.token_to_string(tag)} #{mod.token_to_string(values)}"
122100
end
123-
def token_to_string(value, _mod) when is_binary(value) do
124-
"'#{value}'"
101+
def token_to_string({tag, _, []}, mod) do
102+
mod.token_to_string(tag)
125103
end
126-
def token_to_string([h|_]=values, mod) when is_tuple(h) or is_tuple(hd(h)) do
104+
def token_to_string(values, mod) do
127105
values
128106
|> Enum.reduce([], fn
129-
token, [] = acc -> [acc,mod.token_to_string(token, mod)]
130-
{:comma, _, _} = token, acc -> [acc,mod.token_to_string(token, mod)]
131-
token, acc -> [acc," ",mod.token_to_string(token, mod)]
107+
[], acc -> acc
108+
token, [] -> [mod.token_to_string(token)]
109+
{:comma, _, _} = token, acc -> [acc,mod.token_to_string(token)]
110+
token, acc -> [acc, " ", mod.token_to_string(token)]
132111
end)
133112
end
134-
def token_to_string(value, _mod) do
135-
value
136-
end
137113
end

lib/lexer.ex

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -177,30 +177,15 @@ defmodule SQL.Lexer do
177177
def update_state(rest, file, params, binding, aliases, _line, _column, nil=_type, _data, _meta, acc, n, l, c, t, d, m) do
178178
lex(rest, file, params, binding, aliases, l, c, t, d, m, acc, n)
179179
end
180+
def update_state(rest, file, params, binding, aliases, line, column, :colon=type, []=_data, meta, acc, n, l, c, t, d, m) do
181+
lex(rest, file, params, binding, aliases, l, c, t, d, m, [node(type, line, column, acc, meta, file)], n)
182+
end
180183
def update_state(rest, file, params, binding, aliases, line, column, :ident=type, data, meta, [{:as=tt, mm, []=aa}, {:ident, _, a}=right|acc]=ac, n, l, c, t, d, m) do
181184
case node(type, line, column, data, meta, file) do
182185
{:ident, _, as} = node -> lex(rest, file, params, binding, [{as, a}|aliases], l, c, t, d, m, [{tt, mm, [right, node|aa]}|acc], n)
183186
node -> lex(rest, file, params, binding, aliases, l, c, t, d, m, [node|ac], n)
184187
end
185188
end
186-
def update_state(rest, file, params, binding, aliases, line, column, :ident=type, data, meta, [{:outer, _, []}=p, {tag, _, []}=p1, {:natural, _, []}=p2|acc], n, l, c, t, d, m) when tag in ~w[left right full]a do
187-
{tt, mm, aa} = node(type, line, column, data, meta, file)
188-
lex(rest, file, params, binding, aliases, l, c, t, d, m, [{tt, mm, [p2, p1, p|aa]} | acc], n)
189-
end
190-
def update_state(rest, file, params, binding, aliases, line, column, :ident=type, data, meta, [{:outer, _, []}=p, {tag, _, []}=p1|acc], n, l, c, t, d, m) when tag in ~w[left right full]a do
191-
{tt, mm, aa} = node(type, line, column, data, meta, file)
192-
lex(rest, file, params, binding, aliases, l, c, t, d, m, [{tt, mm, [p1, p|aa]} | acc], n)
193-
end
194-
def update_state(rest, file, params, binding, aliases, line, column, :ident=type, data, meta, [{:inner, _, []}=p, {:natural, _, []}=p1|acc], n, l, c, t, d, m) do
195-
{tt, mm, aa} = node(type, line, column, data, meta, file)
196-
lex(rest, file, params, binding, aliases, l, c, t, d, m, [{tt, mm, [p1, p|aa]} | acc], n)
197-
end
198-
def update_state(rest, file, params, binding, aliases, line, column, :ident=type, data, meta, [{tag, _, []}=p|acc], n, l, c, t, d, m) when tag in ~w[inner left right full natural cross]a do
199-
case node(type, line, column, data, meta, file) do
200-
{:join=tt, mm, aa} -> lex(rest, file, params, binding, aliases, l, c, t, d, m, [{tt, mm, [p|aa]}|acc], n)
201-
node -> lex(rest, file, params, binding, aliases, l, c, t, d, m, [node, p|acc], n)
202-
end
203-
end
204189
def update_state(rest, file, params, binding, aliases, line, column, type, data, meta, [{:dot=t2, m2, []=a}, {tag, _, _}=right|acc], n, l, c, t, d, m) when (type in ~w[ident double_quote bracket dot]a or data==[[], ?*]) and tag in ~w[ident double_quote bracket dot]a do
205190
lex(rest, file, params, binding, aliases, l, c, t, d, m, [{t2, m2, [right, node(type, line, column, data, meta, file)|a]}|acc], n)
206191
end

lib/mix/tasks/sql.gen.test.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ defmodule Mix.Tasks.Sql.Gen.Test do
2828
|> String.replace(~r{\(\s+'}, &String.replace(&1, " ", ""))
2929
|> String.replace(~r{\(\s+"}, &String.replace(&1, " ", ""))
3030
|> String.replace(~r{\(\s+\*}, &String.replace(&1, " ", ""))
31-
|> String.replace(~r{[[:alpha:]]+\s+\(}, &String.replace(&1, " ", ""))
3231
|> String.replace(~r{\b\s+\,}, &String.replace(&1, " ", ""))
3332
|> String.replace(~r{\)\s+\,}, &String.replace(&1, " ", ""))
3433
|> String.replace(~r{\'\s+\,}, &String.replace(&1, " ", ""))

0 commit comments

Comments
 (0)