Skip to content

Commit eb21a8d

Browse files
committed
Add Show/Hide combinators
1 parent 01d527b commit eb21a8d

File tree

6 files changed

+102
-7
lines changed

6 files changed

+102
-7
lines changed

src/FunSQL.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export
5353
funsql_from,
5454
funsql_fun,
5555
funsql_group,
56+
funsql_hide,
5657
funsql_highlight,
5758
funsql_in,
5859
funsql_into,
@@ -81,6 +82,7 @@ export
8182
funsql_rank,
8283
funsql_row_number,
8384
funsql_select,
85+
funsql_show,
8486
funsql_sort,
8587
funsql_sum,
8688
funsql_with

src/link.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ end
2424

2525
function _select(t::RowType)
2626
refs = SQLNode[]
27+
t.visible || return refs
2728
for (f, ft) in t.fields
2829
if ft isa ScalarType
30+
ft.visible || continue
2931
push!(refs, Get(f))
3032
else
3133
nested_refs = _select(ft)

src/nodes.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,7 @@ include("nodes/order.jl")
705705
include("nodes/over.jl")
706706
include("nodes/partition.jl")
707707
include("nodes/select.jl")
708+
include("nodes/show.jl")
708709
include("nodes/sort.jl")
709710
include("nodes/variable.jl")
710711
include("nodes/where.jl")

src/nodes/show.jl

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Show/Hide nodes
2+
3+
mutable struct ShowNode <: TabularNode
4+
over::Union{SQLNode, Nothing}
5+
names::Vector{Symbol}
6+
visible::Bool
7+
label_map::FunSQL.OrderedDict{Symbol, Int}
8+
9+
function ShowNode(; over = nothing, names = [], visible = true, label_map = nothing)
10+
if label_map !== nothing
11+
new(over, names, visible, label_map)
12+
else
13+
n = new(over, names, visible, FunSQL.OrderedDict{Symbol, Int}())
14+
for (i, name) in enumerate(n.names)
15+
if name in keys(n.label_map)
16+
err = FunSQL.DuplicateLabelError(name, path = [n])
17+
throw(err)
18+
end
19+
n.label_map[name] = i
20+
end
21+
n
22+
end
23+
end
24+
end
25+
26+
ShowNode(names...; over = nothing, visible = true) =
27+
ShowNode(over = over, names = Symbol[names...], visible = visible)
28+
29+
Show(args...; kws...) =
30+
ShowNode(args...; kws...) |> SQLNode
31+
32+
Hide(args...; kws...) =
33+
ShowNode(args...; kws..., visible = false) |> SQLNode
34+
35+
const funsql_show = Show
36+
const funsql_hide = Hide
37+
38+
dissect(scr::Symbol, ::typeof(Show), pats::Vector{Any}) =
39+
dissect(scr, ShowNode, pats)
40+
41+
function FunSQL.PrettyPrinting.quoteof(n::ShowNode, ctx::FunSQL.QuoteContext)
42+
ex = Expr(:call, nameof(n.visible ? Show : Hide), quoteof(n.names, ctx)...)
43+
if n.over !== nothing
44+
ex = Expr(:call, :|>, FunSQL.quoteof(n.over, ctx), ex)
45+
end
46+
ex
47+
end

src/resolve.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,33 @@ function resolve(n::SelectNode, ctx)
464464
Resolved(RowType(fields), over = n′)
465465
end
466466

467+
function resolve(n::ShowNode, ctx)
468+
over′ = resolve(n.over, ctx)
469+
t = row_type(over′)
470+
for name in n.names
471+
ft = get(t.fields, name, EmptyType())
472+
if ft isa EmptyType
473+
throw(
474+
ReferenceError(
475+
REFERENCE_ERROR_TYPE.UNDEFINED_NAME,
476+
name = name,
477+
path = get_path(ctx)))
478+
end
479+
end
480+
fields = FieldTypeMap()
481+
for (f, ft) in t.fields
482+
if f in keys(n.label_map)
483+
if ft isa ScalarType
484+
ft = ScalarType(visible = n.visible)
485+
else
486+
ft = RowType(ft.fields, ft.group, visible = n.visible)
487+
end
488+
end
489+
fields[f] = ft
490+
end
491+
Resolved(RowType(fields, t.group, visible = t.visible), over = over′)
492+
end
493+
467494
function resolve_scalar(n::SortNode, ctx)
468495
over′ = resolve_scalar(n.over, ctx)
469496
n′ = Sort(over = over′, value = n.value, nulls = n.nulls)

src/types.jl

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,27 @@ PrettyPrinting.quoteof(::EmptyType) =
1313
Expr(:call, nameof(EmptyType))
1414

1515
struct ScalarType <: AbstractSQLType
16+
visible::Bool
17+
18+
ScalarType(; visible = true) =
19+
new(visible)
1620
end
1721

18-
PrettyPrinting.quoteof(::ScalarType) =
19-
Expr(:call, nameof(ScalarType))
22+
function PrettyPrinting.quoteof(::ScalarType)
23+
ex = Expr(:call, nameof(ScalarType))
24+
if !t.visible
25+
push!(ex.args, Expr(:kw, :visible, t.visible))
26+
end
27+
ex
28+
end
2029

2130
struct RowType <: AbstractSQLType
2231
fields::OrderedDict{Symbol, Union{ScalarType, RowType}}
2332
group::Union{EmptyType, RowType}
33+
visible::Bool
2434

25-
RowType(fields, group = EmptyType()) =
26-
new(fields, group)
35+
RowType(fields, group = EmptyType(); visible = true) =
36+
new(fields, group, visible)
2737
end
2838

2939
const FieldTypeMap = OrderedDict{Symbol, Union{ScalarType, RowType}}
@@ -43,6 +53,9 @@ function PrettyPrinting.quoteof(t::RowType)
4353
if !(t.group isa EmptyType)
4454
push!(ex.args, Expr(:kw, :group, quoteof(t.group)))
4555
end
56+
if !t.visible
57+
push!(ex.args, Expr(:kw, :visible, t.visible))
58+
end
4659
ex
4760
end
4861

@@ -54,8 +67,8 @@ const EMPTY_ROW = RowType()
5467
Base.intersect(::AbstractSQLType, ::AbstractSQLType) =
5568
EmptyType()
5669

57-
Base.intersect(::ScalarType, ::ScalarType) =
58-
ScalarType()
70+
Base.intersect(t1::ScalarType, t2::ScalarType) =
71+
ScalarType(visible = t1.visible || t2.visible)
5972

6073
function Base.intersect(t1::RowType, t2::RowType)
6174
if t1 === t2
@@ -71,7 +84,7 @@ function Base.intersect(t1::RowType, t2::RowType)
7184
end
7285
end
7386
group = intersect(t1.group, t2.group)
74-
RowType(fields, group)
87+
RowType(fields, group, visible = t1.visible || t2.visible)
7588
end
7689

7790

@@ -98,5 +111,8 @@ function Base.issubset(t1::RowType, t2::RowType)
98111
if !issubset(t1.group, t2.group)
99112
return false
100113
end
114+
if !t1.visible && t2.visible
115+
return false
116+
end
101117
return true
102118
end

0 commit comments

Comments
 (0)