Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a33c48b
WIP
yutannihilation Nov 1, 2025
1a66e6c
Fix clippy warning
yutannihilation Nov 1, 2025
d400c3e
Apply suggestions from code review
yutannihilation Nov 1, 2025
5b5cb00
Merge branch 'feat/st_dump' of https://github.com/yutannihilation/sed…
yutannihilation Nov 1, 2025
8f40443
Use executor.num_iterations() for capacity
yutannihilation Nov 1, 2025
a78fbe2
Return { path: [int], geom: GEOMETRY }
yutannihilation Nov 1, 2025
ea79541
Fix return type
yutannihilation Nov 1, 2025
2e99f43
Fix bug and add test
yutannihilation Nov 2, 2025
f68e553
Add test util
yutannihilation Nov 2, 2025
fd0bacf
Wrap with builder
yutannihilation Nov 2, 2025
be35ff9
Implement
yutannihilation Nov 2, 2025
28c1cf7
Do not use raw
yutannihilation Nov 2, 2025
ec25bf5
Tweak
yutannihilation Nov 2, 2025
c9187a9
Reject unsupported types
yutannihilation Nov 2, 2025
df817b6
Fix clippy warning
yutannihilation Nov 2, 2025
709da97
Use u32 instead of i64
yutannihilation Nov 3, 2025
5e2dedc
Merge remote-tracking branch 'upstream/main' into feat/st_dump
yutannihilation Nov 3, 2025
485064c
Add Python test
yutannihilation Nov 3, 2025
a1a9049
Reuse Vec to avoid allocation
yutannihilation Nov 3, 2025
955baf6
Tweak
yutannihilation Nov 3, 2025
1f4818c
Add Python test
yutannihilation Nov 3, 2025
6c29d3d
Add benchmark
yutannihilation Nov 4, 2025
c16a294
Fix clippy and typo
yutannihilation Nov 4, 2025
8936ddd
Remove STDumpStructBuilder
yutannihilation Nov 4, 2025
ff760ba
Fix clippy warning
yutannihilation Nov 5, 2025
07874ac
Use NullBuffer
yutannihilation Nov 5, 2025
6de1952
Clean up
yutannihilation Nov 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions benchmarks/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,24 @@ def queries():

benchmark(queries)

@pytest.mark.parametrize(
"eng", [SedonaDBSingleThread, PostGISSingleThread, DuckDBSingleThread]
)
@pytest.mark.parametrize(
"table",
[
"collections_simple",
"collections_complex",
],
)
def test_st_dump(self, benchmark, eng, table):
eng = self._get_eng(eng)

def queries():
eng.execute_and_collect(f"SELECT ST_Dump(geom1) from {table}")

benchmark(queries)

@pytest.mark.parametrize(
"eng", [SedonaDBSingleThread, PostGISSingleThread, DuckDBSingleThread]
)
Expand Down
136 changes: 136 additions & 0 deletions python/sedonadb/tests/functions/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,142 @@ def test_st_dimension(eng, geom, expected):
eng.assert_query_result(f"SELECT ST_Dimension({geom_or_null(geom)})", expected)


@pytest.mark.parametrize("eng", [SedonaDB, PostGIS])
def test_st_dump(eng):
is_postgis = eng == PostGIS
eng = eng.create_or_skip()

cases = [
{"input": "POINT (1 2)", "expected": [{"path": [], "geom": "POINT (1 2)"}]},
{
"input": "LINESTRING (1 1, 2 2)",
"expected": [{"path": [], "geom": "LINESTRING (1 1, 2 2)"}],
},
{
"input": "POLYGON ((1 1, 2 2, 2 1, 1 1))",
"expected": [{"path": [], "geom": "POLYGON ((1 1, 2 2, 2 1, 1 1))"}],
},
{
"input": "MULTIPOINT (0 1, 1 2)",
"expected": [
{
"path": [1],
"geom": "POINT (0 1)",
},
{
"path": [2],
"geom": "POINT (1 2)",
},
],
},
{
"input": "MULTILINESTRING ((1 1, 2 2), EMPTY, (3 3, 4 4))",
"expected": [
{
"path": [1],
"geom": "LINESTRING (1 1, 2 2)",
},
{
"path": [2],
"geom": "LINESTRING EMPTY",
},
{
"path": [3],
"geom": "LINESTRING (3 3, 4 4)",
},
],
},
{
"input": "MULTIPOLYGON (((1 1, 2 2, 2 1, 1 1)), EMPTY, ((3 3, 4 4, 4 3, 3 3)))",
"expected": [
{
"path": [1],
"geom": "POLYGON ((1 1, 2 2, 2 1, 1 1))",
},
{
"path": [2],
"geom": "POLYGON EMPTY",
},
{
"path": [3],
"geom": "POLYGON ((3 3, 4 4, 4 3, 3 3))",
},
],
},
{
"input": "GEOMETRYCOLLECTION (POINT (1 2), MULTILINESTRING ((1 1, 2 2), EMPTY, (3 3, 4 4)), LINESTRING (1 1, 2 2))",
"expected": [
{
"path": [1],
"geom": "POINT (1 2)",
},
{
"path": [2, 1],
"geom": "LINESTRING (1 1, 2 2)",
},
{
"path": [2, 2],
"geom": "LINESTRING EMPTY",
},
{
"path": [2, 3],
"geom": "LINESTRING (3 3, 4 4)",
},
{
"path": [3],
"geom": "LINESTRING (1 1, 2 2)",
},
],
},
{
"input": "GEOMETRYCOLLECTION (POINT (1 2), GEOMETRYCOLLECTION (MULTILINESTRING ((1 1, 2 2), EMPTY, (3 3, 4 4)), LINESTRING (1 1, 2 2)))",
"expected": [
{
"path": [1],
"geom": "POINT (1 2)",
},
{
"path": [2, 1, 1],
"geom": "LINESTRING (1 1, 2 2)",
},
{
"path": [2, 1, 2],
"geom": "LINESTRING EMPTY",
},
{
"path": [2, 1, 3],
"geom": "LINESTRING (3 3, 4 4)",
},
{
"path": [2, 2],
"geom": "LINESTRING (1 1, 2 2)",
},
],
},
]

for case in cases:
if is_postgis:
result = eng.execute_and_collect(
f"SELECT ST_Dump({geom_or_null(case['input'])})"
)
else:
result = eng.execute_and_collect(
f"SELECT unnest(ST_Dump({geom_or_null(case['input'])}))"
)
df = eng.result_to_pandas(result)

for i in df.index:
actual = df.iat[i, 0]
expected = case["expected"][i]
assert list(actual.keys()) == ["path", "geom"]
if actual["path"].size == 0:
assert len(expected["path"]) == 0
else:
actual["path"] == expected["path"]
assert actual["geom"] == shapely.from_wkt(expected["geom"]).wkb


@pytest.mark.parametrize("eng", [SedonaDB, PostGIS])
@pytest.mark.parametrize(
("geom", "expected"),
Expand Down
1 change: 1 addition & 0 deletions rust/sedona-functions/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mod st_buffer;
mod st_centroid;
mod st_collect;
mod st_dimension;
mod st_dump;
mod st_dwithin;
pub mod st_envelope;
pub mod st_envelope_aggr;
Expand Down
1 change: 1 addition & 0 deletions rust/sedona-functions/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub fn default_function_set() -> FunctionSet {
crate::st_buffer::st_buffer_udf,
crate::st_centroid::st_centroid_udf,
crate::st_dimension::st_dimension_udf,
crate::st_dump::st_dump_udf,
crate::st_dwithin::st_dwithin_udf,
crate::st_envelope::st_envelope_udf,
crate::st_flipcoordinates::st_flipcoordinates_udf,
Expand Down
Loading