From b3ec0167bf49bc0651cbcdbf96552c29e7fe374d Mon Sep 17 00:00:00 2001 From: Miles Cranmer Date: Fri, 20 Oct 2023 10:56:52 +0100 Subject: [PATCH] Fix type instability in `getproperty(::Schema, ::Symbol)` (#340) --- src/Tables.jl | 13 +++++++++++-- test/runtests.jl | 11 +++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Tables.jl b/src/Tables.jl index 195ddd1..9c8a8e2 100644 --- a/src/Tables.jl +++ b/src/Tables.jl @@ -499,8 +499,17 @@ function Base.getproperty(sch::Schema{names, types}, field::Symbol) where {names if field === :names return names === nothing ? getfield(sch, :storednames) : names elseif field === :types - T = getfield(sch, :storedtypes) - return types === nothing ? (T !== nothing ? T : nothing) : Tuple(fieldtype(types, i) for i = 1:fieldcount(types)) + if types === nothing + return getfield(sch, :storedtypes) + else + ncol = fieldcount(types) + if ncol <= 512 + # Type stable, but slower to compile + return ntuple(i -> fieldtype(types, i), Val(ncol)) + else + return Tuple(fieldtype(types, i) for i=1:ncol) + end + end else throw(ArgumentError("unsupported property for Tables.Schema")) end diff --git a/test/runtests.jl b/test/runtests.jl index 7eef20a..2e2aab8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -211,6 +211,17 @@ end # 228 @test Tables.columntable(NamedTuple[]) === NamedTuple() + + @testset "Type stability of schema(x).types" begin + _get_types(X) = Tables.schema(X).types + + x = (a=[1.0], b=[1.0]) + @inferred Tuple{Type{Float64},Type{Float64}} _get_types(x) + + # Trigger other branch which lacks type stability: + x_wide = NamedTuple([Symbol("x$(i)") => [1.0] for i=1:513]) + @inferred NTuple{513,DataType} _get_types(x_wide) + end end @testset "Materializer" begin