Skip to content

Commit 8d14f42

Browse files
committed
Adapt to FunSQL#private-fields
1 parent e8090bd commit 8d14f42

File tree

5 files changed

+1550
-332
lines changed

5 files changed

+1550
-332
lines changed

src/concept.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
concept() = begin
44
from(concept)
5-
as(omop)
5+
into(omop)
66
define(
77
omop.concept_id,
88
omop.concept_name,

src/format.jl

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,40 @@ function _format_thead(df, fmt)
5757
fmt.group_by in names || throw(DomainError(fmt.group_by, "missing grouping column"))
5858
filter!(!=(fmt.group_by), names)
5959
end
60+
cols = [HTTP.URIs.unescapeuri.(split(string(name), '.')) for name in names]
61+
pushfirst!(cols, [""])
62+
w = length(cols)
63+
h = maximum(length.(cols))
64+
headers = Union{String, Nothing}[get(col, i-h+length(col), "") for i = 1:h, col in cols]
65+
for i = 1:h
66+
for j = w:-1:3
67+
if (i == 1 || headers[i-1, j] === nothing) && headers[i, j-1] == headers[i, j]
68+
headers[i, j] = nothing
69+
end
70+
end
71+
end
72+
lines = Vector{Tuple{String, Int, Bool}}[]
73+
for i = 1:h
74+
line = Tuple{String, Int, Bool}[]
75+
j = 1
76+
while j <= w
77+
colspan = 1
78+
while j + colspan <= w && headers[i, j+colspan] === nothing
79+
colspan += 1
80+
end
81+
border =
82+
i > 1 && j > 2 && headers[i-1, j] !== nothing ||
83+
i < h && j > 2 && headers[i, j] !== nothing
84+
push!(line, (headers[i, j], colspan, border))
85+
j += colspan
86+
end
87+
push!(lines, line)
88+
end
6089
@htl """
6190
<thead>
62-
<tr><th></th>$([@htl """<th scope="col">$name</th>""" for name in names])</tr>
91+
$([@htl """<tr>$([@htl """<th scope="col" colspan="$colspan" class="$(border ? "trdw-border" : "")">$header</th>"""
92+
for (header, colspan, border) in lines[i]])</tr>"""
93+
for i = 1:h])
6394
</thead>
6495
"""
6596
end
@@ -171,6 +202,7 @@ function _format_style(df, fmt)
171202
.trdw-format > table { width: max-content; }
172203
.trdw-format > table > caption { padding: .2rem .5rem; }
173204
.trdw-format > table > thead > tr > th { vertical-align; baseline; }
205+
.trdw-format > table > thead > tr > th.trdw-border { border-left: 1px solid var(--table-border-color); }
174206
.trdw-format > table > tbody > tr:first-child > th { border-top: 1px solid var(--table-border-color); }
175207
.trdw-format > table > tbody > tr:first-child > td { border-top: 1px solid var(--table-border-color); }
176208
.trdw-format > table > tbody > tr > th { vertical-align: baseline; }

src/inventory.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ end
1010

1111
array_frequency(expr; name = $(FunSQL.label(expr))) = begin
1212
partition(name = all)
13-
cross_join(from(explode_outer($expr), columns = [$name]))
14-
group($name)
13+
cross_join(explode => from(explode_outer($expr), columns = [$name]))
14+
group(explode.$name)
1515
define(n => count())
1616
define(`%` => floor(100 * n / any_value(all.count()), 1))
1717
order(n.desc())
@@ -114,6 +114,10 @@ validate_foreign_key(source, source_columns, target) =
114114

115115
end
116116

117+
const funsql_tally = funsql_frequency
118+
119+
const funsql_tally_array = funsql_array_frequency
120+
117121
function _primary_key_name(source, columns)
118122
table = FunSQL.label(source)
119123
if length(columns) == 1

src/nodes.jl

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,16 @@ function FunSQL.resolve(n::UndefineNode, ctx)
6161
end
6262
end
6363
fields = FunSQL.FieldTypeMap()
64+
private_fields = copy(t.private_fields)
6465
for (f, ft) in t.fields
6566
if f in keys(n.label_map)
67+
delete!(private_fields, f)
6668
continue
6769
end
6870
fields[f] = ft
6971
end
7072
q′ = FunSQL.Padding(tail = tail′)
71-
FunSQL.Resolved(FunSQL.RowType(fields, t.group), tail = q′)
73+
FunSQL.Resolved(FunSQL.RowType(fields, t.group, private_fields), tail = q′)
7274
end
7375

7476
mutable struct TryGetNode <: FunSQL.AbstractSQLNode
@@ -160,14 +162,15 @@ function FunSQL.resolve(n::ExplainConceptIdNode, ctx)
160162
left_join(
161163
from(concept).define(args = $(n.args)).as($alias),
162164
$f == $alias.concept_id,
163-
optional = true)
165+
optional = true,
166+
private = true)
164167
end
165168
defs = [Symbol("$prefix$label") => @funsql($alias.$label) for label in keys(n.label_map)]
166169
dup_field_aliases = [first(def) for def in defs if haskey(t.fields, first(def))]
167170
if !isempty(dup_field_aliases)
168171
q = q |> Undefine(names = dup_field_aliases)
169172
end
170-
q = q |> FunSQL.Define(args = defs, after = f)
173+
q = q |> FunSQL.Define(args = defs, after = f, private = (f in t.private_fields))
171174
if n.replace
172175
q = q |> Undefine(f)
173176
end
@@ -180,19 +183,21 @@ mutable struct SummaryNode <: FunSQL.TabularNode
180183
type::Bool
181184
top_k::Int
182185
nested::Bool
186+
private::Bool
183187
exact::Bool
184188

185-
SummaryNode(; names = Symbol[], type = true, top_k = 0, nested = false, exact = false) =
186-
new(names, type, top_k, nested, exact)
189+
SummaryNode(; names = Symbol[], type = true, top_k = 0, nested = false, private = false, exact = false) =
190+
new(names, type, top_k, nested, private, exact)
187191
end
188192

189-
SummaryNode(names...; type = true, top_k = 0, nested = false, exact = false) =
190-
SummaryNode(names = Symbol[names...], type = type, top_k = top_k, nested = nested, exact = exact)
193+
SummaryNode(names...; type = true, top_k = 0, nested = false, private = false, exact = false) =
194+
SummaryNode(names = Symbol[names...], type = type, top_k = top_k, nested = nested, private = private, exact = exact)
191195

192196
const Summary = FunSQL.SQLQueryCtor{SummaryNode}(:Summary)
193197

194198
const funsql_summary = Summary
195199
const funsql_density = Summary
200+
const funsql_summarize = Summary
196201

197202
function FunSQL.PrettyPrinting.quoteof(n::SummaryNode, ctx::FunSQL.QuoteContext)
198203
ex = Expr(:call, :Summary, FunSQL.quoteof(n.names, ctx)...)
@@ -205,6 +210,9 @@ function FunSQL.PrettyPrinting.quoteof(n::SummaryNode, ctx::FunSQL.QuoteContext)
205210
if n.nested
206211
push!(ex.args, Expr(:kw, :nested, n.nested))
207212
end
213+
if n.private
214+
push!(ex.args, Expr(:kw, :private, n.private))
215+
end
208216
if n.exact
209217
push!(ex.args, Expr(:kw, :exact, n.exact))
210218
end
@@ -224,7 +232,7 @@ function FunSQL.resolve(n::SummaryNode, ctx)
224232
end
225233
end
226234
names = isempty(n.names) ? Set(keys(t.fields)) : Set(n.names)
227-
cases = _summary_cases(t, names, n.nested)
235+
cases = _summary_cases(t, names, n.nested || n.private)
228236
if isempty(cases) && !n.nested
229237
cases = _summary_cases(t, names, true)
230238
end
@@ -255,20 +263,23 @@ function FunSQL.resolve(n::SummaryNode, ctx)
255263
q = @funsql begin
256264
$tail′
257265
group()
258-
cross_join(summary_case => from(explode(sequence(1, $max_i)), columns = [index]))
266+
cross_join(
267+
summary_case => from(explode(sequence(1, $max_i)), columns = [index]),
268+
private = true)
259269
define(args = $args)
260270
end
261271
FunSQL.resolve(q, ctx)
262272
end
263273

264-
function _summary_cases(t, name_set, nested)
274+
function _summary_cases(t, name_set, private)
265275
cases = Tuple{String, FunSQL.SQLQuery}[]
266276
for (f, ft) in t.fields
267277
f in name_set || continue
278+
!(f in t.private_fields) || private || continue
268279
if ft isa FunSQL.ScalarType
269280
push!(cases, (String(f), FunSQL.Get(f)))
270-
elseif ft isa FunSQL.RowType && nested
271-
subcases = _summary_cases(ft, Set(keys(ft.fields)), nested)
281+
elseif ft isa FunSQL.RowType
282+
subcases = _summary_cases(ft, Set(keys(ft.fields)), private)
272283
for (n, q) in subcases
273284
push!(cases, ("$f.$n", FunSQL.Get(f) |> q))
274285
end
@@ -507,7 +518,7 @@ function resolve_concept_id(cat::FunSQL.SQLCatalog, n::AssertValidConceptNode)
507518
m !== nothing && m.concept_cache !== nothing || return
508519
(conn, dir) = m.concept_cache
509520
db = FunSQL.SQLConnection(conn, catalog = cat)
510-
q = @funsql concept($(n.condition)).order(concept_id).limit(3)
521+
q = @funsql concept().filter($(n.condition)).order(concept_id).limit(3)
511522
sql = FunSQL.render(db, q)
512523
key = bytes2hex(sha256(sql))
513524
filename = joinpath(dir, key * ".arrow")

0 commit comments

Comments
 (0)