/
select.jl
72 lines (57 loc) · 1.65 KB
/
select.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# Selecting.
mutable struct SelectNode <: TabularNode
over::Union{SQLNode, Nothing}
args::Vector{SQLNode}
label_map::OrderedDict{Symbol, Int}
function SelectNode(; over = nothing, args, label_map = nothing)
if label_map !== nothing
new(over, args, label_map)
else
n = new(over, args, OrderedDict{Symbol, Int}())
populate_label_map!(n)
n
end
end
end
SelectNode(args...; over = nothing) =
SelectNode(over = over, args = SQLNode[args...])
"""
Select(; over; args)
Select(args...; over)
The `Select` node specifies the output columns.
```sql
SELECT \$args...
FROM \$over
```
Set the column labels with [`As`](@ref).
# Examples
*List patient IDs and their age.*
```jldoctest
julia> person = SQLTable(:person, columns = [:person_id, :birth_datetime]);
julia> q = From(:person) |>
Select(Get.person_id,
:age => Fun.now() .- Get.birth_datetime);
julia> print(render(q, tables = [person]))
SELECT
"person_1"."person_id",
(now() - "person_1"."birth_datetime") AS "age"
FROM "person" AS "person_1"
```
"""
Select(args...; kws...) =
SelectNode(args...; kws...) |> SQLNode
const funsql_select = Select
dissect(scr::Symbol, ::typeof(Select), pats::Vector{Any}) =
dissect(scr, SelectNode, pats)
function PrettyPrinting.quoteof(n::SelectNode, ctx::QuoteContext)
ex = Expr(:call, nameof(Select))
if isempty(n.args)
push!(ex.args, Expr(:kw, :args, Expr(:vect)))
else
append!(ex.args, quoteof(n.args, ctx))
end
if n.over !== nothing
ex = Expr(:call, :|>, quoteof(n.over, ctx), ex)
end
ex
end