Skip to content

Commit d9c40f8

Browse files
author
Pietro Vertechi
committed
check very rigorously before appending table
1 parent 1cb9b72 commit d9c40f8

File tree

3 files changed

+21
-23
lines changed

3 files changed

+21
-23
lines changed

src/StructArrays.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
module StructArrays
22

33
using Base: tuple_type_cons, tuple_type_head, tuple_type_tail, tail
4-
using Tables: getcolumn, Tables
54

65
export StructArray, StructVector, LazyRow, LazyRows
76
export collect_structarray, fieldarrays

src/tables.jl

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
1+
import Tables
2+
13
Tables.isrowtable(::Type{<:StructArray}) = true
24

35
Tables.columnaccess(::Type{<:StructArray}) = true
46
Tables.columns(s::StructArray) = fieldarrays(s)
5-
Tables.schema(s::StructArray) = Tables.Schema(staticschema(eltype(s)))
7+
Tables.schema(s::StructArray) = _schema(staticschema(eltype(s)))
8+
9+
_schema(::Type{NT}) where {NT<:NamedTuple} = Tables.Schema(NT)
10+
# make schema for unnamed case
11+
function _schema(::Type{T}) where {T<:NTuple{N, Any}} where N
12+
return Tables.Schema{ntuple(identity, N), T}
13+
end
14+
15+
function try_compatible_columns(rows::R, s::StructArray) where {R}
16+
Tables.isrowtable(rows) && Tables.columnaccess(rows) || return nothing
17+
T = eltype(rows)
18+
hasfields(T) || return nothing
19+
NT = staticschema(T)
20+
_schema(NT) == Tables.schema(rows) || return nothing
21+
table = Tables.columns(rows)
22+
fieldnames(NT) == propertynames(table) ? table : nothing
23+
end
624

725
function Base.append!(s::StructVector, rows)
8-
if Tables.isrowtable(rows) && Tables.columnaccess(rows)
26+
table = try_compatible_columns(rows, s)
27+
if table !== nothing
928
# Input `rows` is a container of rows _and_ satisfies column
1029
# table interface. Thus, we can add the input column-by-column.
11-
table = Tables.columns(rows)
12-
isempty(_setdiff(propertynames(s), Tables.columnnames(rows))) ||
13-
_invalid_columns_error(s, rows)
1430
foreachfield(append!, s, table)
1531
return s
1632
else
@@ -19,12 +35,3 @@ function Base.append!(s::StructVector, rows)
1935
return foldl(push!, rows; init = s)
2036
end
2137
end
22-
23-
@noinline function _invalid_columns_error(s, rows)
24-
missingnames = setdiff!(collect(Tables.columnnames(rows)), propertynames(s))
25-
throw(ArgumentError(string(
26-
"Cannot append rows from `$(typeof(rows))` to `$(typeof(s))` due to ",
27-
"missing column(s):\n",
28-
join(missingnames, ", "),
29-
)))
30-
end

src/utils.jl

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,3 @@ hasfields(::Type{<:NTuple{N, Any}}) where {N} = true
133133
hasfields(::Type{<:NamedTuple{names}}) where {names} = true
134134
hasfields(::Type{T}) where {T} = !isabstracttype(T)
135135
hasfields(::Union) = false
136-
137-
_setdiff(a, b) = setdiff(a, b)
138-
139-
@inline _setdiff(::Tuple{}, ::Tuple{}) = ()
140-
@inline _setdiff(::Tuple{}, ::Tuple) = ()
141-
@inline _setdiff(a::Tuple, ::Tuple{}) = a
142-
@inline _setdiff(a::Tuple, b::Tuple) = _setdiff(_exclude(a, b[1]), Base.tail(b))
143-
@inline _exclude(a, b) = foldl((ys, x) -> x == b ? ys : (ys..., x), a; init = ())

0 commit comments

Comments
 (0)