diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index ee08d08..0000000 --- a/Manifest.toml +++ /dev/null @@ -1,44 +0,0 @@ -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[Distributed]] -deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[InteractiveUtils]] -deps = ["LinearAlgebra", "Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[Requires]] -deps = ["Test"] -git-tree-sha1 = "f6fbf4ba64d295e146e49e021207993b6b48c7d1" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "0.5.2" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/Project.toml b/Project.toml index 6ddd4cc..90f4742 100644 --- a/Project.toml +++ b/Project.toml @@ -5,4 +5,6 @@ version = "0.1.9" [deps] Requires = "ae029012-a4dd-5104-9daa-d747884805df" +TableTraits = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +IteratorInterfaceExtensions = "82899510-4779-5014-852e-03e436cf321d" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/Tables.jl b/src/Tables.jl index ea7f8cf..debcb87 100644 --- a/src/Tables.jl +++ b/src/Tables.jl @@ -2,6 +2,8 @@ module Tables using Requires +using TableTraits, IteratorInterfaceExtensions + export rowtable, columntable function __init__() @@ -116,7 +118,8 @@ Obviously every table type is different, but via a combination of `Tables.rows` abstract type Table end # default definitions -istable(x::T) where {T} = istable(T) +istable(x::T) where {T} = istable(T) || TableTraits.isiterabletable(x) === true || + TableTraits.isiterabletable(x) === missing istable(::Type{T}) where {T} = false rowaccess(x::T) where {T} = rowaccess(T) rowaccess(::Type{T}) where {T} = false diff --git a/src/fallbacks.jl b/src/fallbacks.jl index 915995b..2472ef0 100644 --- a/src/fallbacks.jl +++ b/src/fallbacks.jl @@ -59,6 +59,10 @@ function rows(x::T) where {T} cols = columns(x) return RowIterator(cols, rowcount(cols)) else + it = TableTraits.isiterabletable(x) + if it === true || it === missing + return DataValueUnwrapper(IteratorInterfaceExtensions.getiterator(x)) + end throw(ArgumentError("no default `Tables.rows` implementation for type: $T")) end end @@ -146,7 +150,17 @@ end if rowaccess(T) r = rows(x) return buildcolumns(schema(r), r) + elseif TableTraits.supports_get_columns_copy_using_missing(x) + return TableTraits.get_columns_copy_using_missing(x) else + it = TableTraits.isiterabletable(x) + y = IteratorInterfaceExtensions.getiterator(x) + if it === true + return columns(DataValueUnwrapper(y)) + elseif it === missing + # non-NamedTuple or EltypeUnknown + return buildcolumns(nothing, DataValueUnwrapper(y)) + end throw(ArgumentError("no default `Tables.columns` implementation for type: $T")) end end diff --git a/test/runtests.jl b/test/runtests.jl index 5a52c7d..a2ba625 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,4 +1,4 @@ -using Test, Tables +using Test, Tables, TableTraits @testset "utils.jl" begin @@ -223,6 +223,19 @@ end @test sortperm([a, b, c, d]) == [3, 1, 2, 4] end +struct ColumnSource +end + +TableTraits.supports_get_columns_copy_using_missing(::ColumnSource) = true + +function TableTraits.get_columns_copy_using_missing(x::ColumnSource) + return (a=[1,2,3], b=[4.,5.,6.], c=["A", "B", "C"]) +end + +let x=ColumnSource() + @test Tables.columns(x) == TableTraits.get_columns_copy_using_missing(x) +end + @static if :Query in Symbol.(Base.loaded_modules_array()) rt = (a = Real[1, 2.0, 3], b = Union{Missing, Float64}[4.0, missing, 6.0], c = ["7", "8", "9"]) @@ -250,4 +263,4 @@ end rt = (a = Missing[missing, missing], b=[1,2]) dv = Tables.datavaluerows(rt) @test eltype(dv) == NamedTuple{(:a, :b), Tuple{DataValue{Union{}}, Int}} -end \ No newline at end of file +end