Skip to content

Commit 2e0a4a7

Browse files
authored
Fix Tables schema for empty layers (#441)
* Fix empty layer handling. * Add tests. Fix macro escaping.
1 parent 4f7a7d6 commit 2e0a4a7

File tree

4 files changed

+68
-9
lines changed

4 files changed

+68
-9
lines changed

src/tables.jl

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
1-
function Tables.schema(layer::AbstractFeatureLayer)::Nothing
2-
return nothing
1+
function Tables.schema(
2+
layer::AbstractFeatureLayer,
3+
)::Union{Nothing,Tables.Schema}
4+
# If the layer has no features, calculate the schema from the layer
5+
# otherwise let the features build the schema on the fly
6+
# If we always build the schema, all isnullable (by default true) fields
7+
# will result in columns with Union{Missing}.
8+
nfeature(layer) == 0 || return nothing
9+
ld = layerdefn(layer)
10+
geom_names, field_names, _, fielddefns = schema_names(ld)
11+
names = (geom_names..., field_names...)
12+
types = Type[_datatype(getgeomdefn(ld, i - 1)) for i in 1:ngeom(ld)]
13+
append!(types, map(_datatype, fielddefns))
14+
return Tables.Schema(names, types)
15+
end
16+
17+
function _datatype(fielddefn::IFieldDefnView)
18+
return T = convert(DataType, getfieldtype(fielddefn))
19+
end
20+
21+
function _datatype(fielddefn::IGeomFieldDefnView)
22+
return IGeometry{gettype(fielddefn)}
323
end
424

525
Tables.istable(::Type{<:AbstractFeatureLayer})::Bool = true

src/utils.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,23 @@ macro ogrerr(code, message)
207207
"Unknown error."
208208
end
209209

210-
error($message * " ($detailmsg)")
210+
error($(esc(message)) * " ($detailmsg)")
211211
end
212212
end
213213
end
214214

215215
macro cplerr(code, message)
216216
return quote
217217
if $(esc(code)) != GDAL.CE_None
218-
error($message)
218+
error($(esc(message)))
219219
end
220220
end
221221
end
222222

223223
macro cplwarn(code, message)
224224
return quote
225225
if $(esc(code)) != GDAL.CE_None
226-
@warn $message
226+
@warn $(esc(message))
227227
end
228228
end
229229
end

test/test_tables.jl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,45 @@ using Tables
786786
)
787787
end
788788
end
789+
@testset "Handle empty layers" begin
790+
AG.read(
791+
joinpath(@__DIR__, "data/multi_geom.csv"),
792+
options = [
793+
"GEOM_POSSIBLE_NAMES=point,linestring",
794+
"KEEP_GEOM_COLUMNS=NO",
795+
],
796+
) do ds
797+
layer = AG.copy(AG.getlayer(ds, 0))
798+
799+
# With features, no schema is defined
800+
@test isnothing(Tables.schema(layer))
801+
# And tables are built up from features
802+
table = Tables.columntable(layer)
803+
@test Tables.columnnames(table) ==
804+
(:point, :linestring, :id, :zoom, :location)
805+
@test Tables.rowcount(table) == 2
806+
807+
for i in 1:AG.nfeature(layer)
808+
AG.deletefeature!(layer, i)
809+
end
810+
811+
# Without features, schema is still defined and table is empty
812+
@test Tables.schema(layer) == Tables.Schema(
813+
(:point, :linestring, :id, :zoom, :location),
814+
(
815+
AG.IGeometry{AG.wkbUnknown},
816+
AG.IGeometry{AG.wkbUnknown},
817+
String,
818+
String,
819+
String,
820+
),
821+
)
822+
table = Tables.columntable(layer)
823+
@test Tables.rowcount(table) == 0
824+
@test Tables.columnnames(table) ==
825+
(:point, :linestring, :id, :zoom, :location)
826+
end
827+
end
789828

790829
clean_test_dataset_files()
791830
end

test/test_utils.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import GDAL
33
import ArchGDAL as AG
44

55
"Test both that an ErrorException is thrown and that the message is as expected"
6-
function eval_ogrerr(err, expected_message)
7-
@test (@test_throws ErrorException AG.@ogrerr err "e:").value.msg ==
8-
"e: ($expected_message)"
6+
function eval_ogrerr(err, expected_message, placeholder = "")
7+
@test (@test_throws ErrorException AG.@ogrerr err "e $(placeholder):").value.msg ==
8+
"e $(placeholder): ($expected_message)"
99
end
1010

1111
@testset "test_utils.jl" begin
@@ -18,7 +18,7 @@ end
1818

1919
@testset "OGR Errors" begin
2020
@test isnothing(AG.@ogrerr GDAL.OGRERR_NONE "not an error")
21-
eval_ogrerr(GDAL.OGRERR_NOT_ENOUGH_DATA, "Not enough data.")
21+
eval_ogrerr(GDAL.OGRERR_NOT_ENOUGH_DATA, "Not enough data.", "foo")
2222
eval_ogrerr(GDAL.OGRERR_NOT_ENOUGH_MEMORY, "Not enough memory.")
2323
eval_ogrerr(
2424
GDAL.OGRERR_UNSUPPORTED_GEOMETRY_TYPE,

0 commit comments

Comments
 (0)