Skip to content

Commit 00f34cd

Browse files
authored
Allow any TableTraits source to satisfy the Tables interface (#45)
* Allow any TableTraits source to satisfy the Tables interface * Remove Manifest * Add tests for new TableTraits integration
1 parent 0d0ca87 commit 00f34cd

File tree

5 files changed

+35
-47
lines changed

5 files changed

+35
-47
lines changed

Manifest.toml

Lines changed: 0 additions & 44 deletions
This file was deleted.

Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ version = "0.1.9"
55

66
[deps]
77
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
8+
TableTraits = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
9+
IteratorInterfaceExtensions = "82899510-4779-5014-852e-03e436cf321d"
810
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

src/Tables.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ module Tables
22

33
using Requires
44

5+
using TableTraits, IteratorInterfaceExtensions
6+
57
export rowtable, columntable
68

79
function __init__()
@@ -116,7 +118,8 @@ Obviously every table type is different, but via a combination of `Tables.rows`
116118
abstract type Table end
117119

118120
# default definitions
119-
istable(x::T) where {T} = istable(T)
121+
istable(x::T) where {T} = istable(T) || TableTraits.isiterabletable(x) === true ||
122+
TableTraits.isiterabletable(x) === missing
120123
istable(::Type{T}) where {T} = false
121124
rowaccess(x::T) where {T} = rowaccess(T)
122125
rowaccess(::Type{T}) where {T} = false

src/fallbacks.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ function rows(x::T) where {T}
5959
cols = columns(x)
6060
return RowIterator(cols, rowcount(cols))
6161
else
62+
it = TableTraits.isiterabletable(x)
63+
if it === true || it === missing
64+
return DataValueUnwrapper(IteratorInterfaceExtensions.getiterator(x))
65+
end
6266
throw(ArgumentError("no default `Tables.rows` implementation for type: $T"))
6367
end
6468
end
@@ -146,7 +150,17 @@ end
146150
if rowaccess(T)
147151
r = rows(x)
148152
return buildcolumns(schema(r), r)
153+
elseif TableTraits.supports_get_columns_copy_using_missing(x)
154+
return TableTraits.get_columns_copy_using_missing(x)
149155
else
156+
it = TableTraits.isiterabletable(x)
157+
y = IteratorInterfaceExtensions.getiterator(x)
158+
if it === true
159+
return columns(DataValueUnwrapper(y))
160+
elseif it === missing
161+
# non-NamedTuple or EltypeUnknown
162+
return buildcolumns(nothing, DataValueUnwrapper(y))
163+
end
150164
throw(ArgumentError("no default `Tables.columns` implementation for type: $T"))
151165
end
152166
end

test/runtests.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Test, Tables
1+
using Test, Tables, TableTraits
22

33
@testset "utils.jl" begin
44

@@ -223,6 +223,19 @@ end
223223
@test sortperm([a, b, c, d]) == [3, 1, 2, 4]
224224
end
225225

226+
struct ColumnSource
227+
end
228+
229+
TableTraits.supports_get_columns_copy_using_missing(::ColumnSource) = true
230+
231+
function TableTraits.get_columns_copy_using_missing(x::ColumnSource)
232+
return (a=[1,2,3], b=[4.,5.,6.], c=["A", "B", "C"])
233+
end
234+
235+
let x=ColumnSource()
236+
@test Tables.columns(x) == TableTraits.get_columns_copy_using_missing(x)
237+
end
238+
226239
@static if :Query in Symbol.(Base.loaded_modules_array())
227240
rt = (a = Real[1, 2.0, 3], b = Union{Missing, Float64}[4.0, missing, 6.0], c = ["7", "8", "9"])
228241

@@ -250,4 +263,4 @@ end
250263
rt = (a = Missing[missing, missing], b=[1,2])
251264
dv = Tables.datavaluerows(rt)
252265
@test eltype(dv) == NamedTuple{(:a, :b), Tuple{DataValue{Union{}}, Int}}
253-
end
266+
end

0 commit comments

Comments
 (0)