Skip to content

Commit a085a7a

Browse files
committed
make distinct its own verb and node
1 parent cb126ae commit a085a7a

File tree

2 files changed

+30
-40
lines changed

2 files changed

+30
-40
lines changed

src/SQLQuery.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ module SQLQuery
1313
args::QueryArgs
1414
end
1515

16+
type DistinctNode{T} <: QueryNode{T}
17+
input::T
18+
args::QueryArgs
19+
end
20+
1621
type FilterNode{T} <: QueryNode{T}
1722
input::T
1823
args::Vector{Expr}
@@ -61,6 +66,7 @@ module SQLQuery
6166
Base.show(io::IO, q::QueryNode) = print(io, translatesql(q))
6267

6368
QUERYNODE = Dict(:select => SelectNode,
69+
:distinct => DistinctNode,
6470
:filter => FilterNode,
6571
:groupby => GroupbyNode,
6672
:orderby => OrderbyNode,

src/translate.jl

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,41 +18,22 @@ end
1818
# should process this properly in the future
1919
_sqlexpr(ex::QueryArg) = "$ex"
2020

21-
function _translatesubquery(q::QueryNode, offset::Int)
22-
if isa(q.input, Symbol)
23-
return ident(q.input)
24-
else
25-
@assert isa(q.input, QueryNode)
26-
return "($(translatesql(q.input, offset)))"
27-
end
28-
end
21+
translatesql(q::Symbol, offset::Int) = ident(q) # table-name
22+
_translatesubquery(q::Symbol, offset::Int) = ident(q)
23+
_translatesubquery(q::QueryNode, offset::Int) =
24+
"($(translatesql(q.input, offset)))"
2925

30-
"Returns the prefix to the SELECT clause (if any): either of DISTINCT/ALL"
31-
function _selectprefix(q::SelectNode)
32-
# Two Expr Possibilities: either
33-
# (i) newcol = f(colname) (satisfies .head == :kw)
34-
# (ii) distinct/all(columns...) (satisfies .head == :call)
35-
# we check for the second kind here
36-
if isa(q.args[1], Expr) && q.args[1].head == :call
37-
clause = q.args[1].args[1]
38-
clause == :distinct && return "DISTINCT "
39-
clause == :all && return "ALL "
40-
end
41-
"" # returns nothing by default
42-
end
43-
44-
_selectarg(a::Symbol) = "$a" # assume it corresponds to a column-name
26+
_selectarg(a::Symbol) = string(a) # assume it corresponds to a column-name
4527

4628
function _selectarg(a::Expr)
4729
if a.head == :kw # newcol=col (SELECT col AS newcol)
4830
@assert length(a.args) == 2
4931
newcol,expr = a.args
5032
@assert isa(newcol, Symbol)
5133
return "$(_sqlexpr(expr)) AS $newcol"
52-
elseif a.head == :. # table.columnname
53-
return ident(a)
5434
else
55-
error("unidentified SELECT result-column: $a")
35+
@assert a.head == :. # table.columnname
36+
return ident(a)
5637
end
5738
end
5839

@@ -121,7 +102,7 @@ end
121102
function translatesql(q::FilterNode, offset::Int=0)
122103
@assert length(q.args) > 0 "you shouldn't filter by nothing"
123104
indent = " " ^ offset
124-
source = _translatesubquery(q, offset+8)
105+
source = _translatesubquery(q.input, offset+8)
125106
# TODO: should properly parse q.args
126107
conditions = join(q.args, "\n$(indent) AND ")
127108
"SELECT *\n $indent FROM $source\n$indent WHERE $conditions"
@@ -130,20 +111,23 @@ end
130111
function translatesql(q::SelectNode, offset::Int=0)
131112
@assert length(q.args) > 0 "you shouldn't select by nothing"
132113
indent = " " ^ offset
133-
prefix = _selectprefix(q) # "distinct"/"all"/""
134-
source = _translatesubquery(q, offset+8)
135-
resultcolumns = if prefix == ""
136-
join(map(_selectarg, q.args), ",\n $indent ")
137-
else
138-
join(map(_selectarg, exfargs(q.args[1])), ",\n $indent ")
139-
end
140-
"SELECT $prefix$resultcolumns\n $indent FROM $source"
114+
source = _translatesubquery(q.input, offset+8)
115+
resultcolumns = join(map(_selectarg, q.args), ",\n $indent ")
116+
"SELECT $resultcolumns\n $indent FROM $source"
117+
end
118+
119+
function translatesql(q::DistinctNode, offset::Int=0)
120+
@assert length(q.args) > 0 "you shouldn't select by nothing"
121+
indent = " " ^ offset; pad = " " ^ 9
122+
source = _translatesubquery(q.input, offset+8)
123+
resultcolumns = join(map(_selectarg, q.args), ",\n $indent$pad ")
124+
"SELECT DISTINCT $resultcolumns\n $indent FROM $source"
141125
end
142126

143127
function translatesql(q::GroupbyNode, offset::Int=0)
144128
@assert length(q.args) > 0 "you shouldn't groupby nothing"
145129
indent = " " ^ offset
146-
source = _translatesubquery(q, offset+10)
130+
source = _translatesubquery(q.input, offset+10)
147131
lastarg = q.args[end]
148132
groupby = if _groupbyhaving(lastarg)
149133
groupbyargs = q.args[1:end-1]
@@ -162,27 +146,27 @@ end
162146
function translatesql(q::OrderbyNode, offset::Int=0)
163147
@assert length(q.args) > 0 "you shouldn't order by nothing"
164148
indent = " " ^ offset
165-
source = _translatesubquery(q, offset+10)
149+
source = _translatesubquery(q.input, offset+10)
166150
orderby = join(map(_orderbyterm, q.args), ",\n $indent ")
167151
" SELECT *\n $indent FROM $source\n$(indent)ORDER BY $orderby"
168152
end
169153

170154
function translatesql(q::LimitNode, offset::Int=0)
171155
indent = " " ^ offset
172-
source = _translatesubquery(q, offset+8)
156+
source = _translatesubquery(q.input, offset+8)
173157
"SELECT *\n $indent FROM $source\n$(indent) LIMIT $(q.limit)"
174158
end
175159

176160
function translatesql(q::OffsetNode, offset::Int=0)
177161
indent = " " ^ offset
178-
source = _translatesubquery(q, offset+8)
162+
source = _translatesubquery(q.input, offset+8)
179163
limit = "LIMIT -1 OFFSET $(q.offset)"
180164
"SELECT *\n $indent FROM $source\n$(indent) $limit"
181165
end
182166

183167
function translatesql(q::JoinNode, offset::Int=0)
184168
indent = " " ^ offset
185169
join, table, on, by = _parsejoin(q, offset)
186-
source = _translatesubquery(q, offset+8)
170+
source = _translatesubquery(q.input, offset+8)
187171
"SELECT *\n $indent FROM $source\n $indent$join $table$on$by"
188172
end

0 commit comments

Comments
 (0)