Skip to content

Commit 0551583

Browse files
feat(sql): Implement ST_StartPoint() and ST_EndPoint() (#245)
Co-authored-by: Dewey Dunnington <[email protected]>
1 parent c67484c commit 0551583

File tree

7 files changed

+477
-1
lines changed

7 files changed

+477
-1
lines changed

benchmarks/test_functions.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,39 @@ def queries():
203203
eng.execute_and_collect(f"SELECT ST_Perimeter(geom1) from {table}")
204204

205205
benchmark(queries)
206+
207+
@pytest.mark.parametrize(
208+
"eng", [SedonaDBSingleThread, PostGISSingleThread, DuckDBSingleThread]
209+
)
210+
@pytest.mark.parametrize(
211+
"table",
212+
[
213+
"collections_simple",
214+
"segments_large",
215+
],
216+
)
217+
def test_st_start_point(self, benchmark, eng, table):
218+
eng = self._get_eng(eng)
219+
220+
def queries():
221+
eng.execute_and_collect(f"SELECT ST_StartPoint(geom1) from {table}")
222+
223+
benchmark(queries)
224+
225+
@pytest.mark.parametrize(
226+
"eng", [SedonaDBSingleThread, PostGISSingleThread, DuckDBSingleThread]
227+
)
228+
@pytest.mark.parametrize(
229+
"table",
230+
[
231+
"collections_simple",
232+
"segments_large",
233+
],
234+
)
235+
def test_st_end_point(self, benchmark, eng, table):
236+
eng = self._get_eng(eng)
237+
238+
def queries():
239+
eng.execute_and_collect(f"SELECT ST_EndPoint(geom1) from {table}")
240+
241+
benchmark(queries)

python/sedonadb/tests/functions/test_functions.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,71 @@ def test_st_pointm(eng, x, y, m, expected):
10161016
)
10171017

10181018

1019+
@pytest.mark.parametrize("eng", [SedonaDB, PostGIS])
1020+
@pytest.mark.parametrize(
1021+
("geometry", "expected"),
1022+
[
1023+
(None, None),
1024+
("POINT EMPTY", None),
1025+
("LINESTRING EMPTY", None),
1026+
("POLYGON EMPTY", None),
1027+
("MULTIPOINT EMPTY", None),
1028+
("MULTILINESTRING EMPTY", None),
1029+
("MULTIPOLYGON EMPTY", None),
1030+
("GEOMETRYCOLLECTION EMPTY", None),
1031+
("LINESTRING (1 2, 3 4, 5 6)", "POINT (1 2)"),
1032+
("LINESTRING Z (1 2 3, 3 4 5, 5 6 7)", "POINT Z (1 2 3)"),
1033+
("LINESTRING M (1 2 3, 3 4 5, 5 6 7)", "POINT M (1 2 3)"),
1034+
("LINESTRING ZM (1 2 3 4, 3 4 5 6, 5 6 7 8)", "POINT ZM (1 2 3 4)"),
1035+
("POINT (1 2)", "POINT (1 2)"),
1036+
("POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", "POINT (0 0)"),
1037+
("MULTIPOINT (0 0, 10 0, 10 10, 0 10, 0 0)", "POINT (0 0)"),
1038+
("MULTILINESTRING ((1 2, 3 4), (5 6, 7 8))", "POINT (1 2)"),
1039+
("MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0)))", "POINT (0 0)"),
1040+
("GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (3 4, 5 6))", "POINT (1 2)"),
1041+
(
1042+
"GEOMETRYCOLLECTION (GEOMETRYCOLLECTION (GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (3 4, 5 6))))",
1043+
"POINT (1 2)",
1044+
),
1045+
],
1046+
)
1047+
def test_st_start_point(eng, geometry, expected):
1048+
eng = eng.create_or_skip()
1049+
eng.assert_query_result(
1050+
f"SELECT ST_StartPoint({geom_or_null(geometry)})",
1051+
expected,
1052+
)
1053+
1054+
1055+
@pytest.mark.parametrize("eng", [SedonaDB, PostGIS])
1056+
@pytest.mark.parametrize(
1057+
("geometry", "expected"),
1058+
[
1059+
(None, None),
1060+
("POINT EMPTY", None),
1061+
("LINESTRING EMPTY", None),
1062+
("POLYGON EMPTY", None),
1063+
("MULTIPOINT EMPTY", None),
1064+
("MULTILINESTRING EMPTY", None),
1065+
("MULTIPOLYGON EMPTY", None),
1066+
("GEOMETRYCOLLECTION EMPTY", None),
1067+
("LINESTRING (1 2, 3 4, 5 6)", "POINT (5 6)"),
1068+
("LINESTRING Z (1 2 3, 3 4 5, 5 6 7)", "POINT Z (5 6 7)"),
1069+
("LINESTRING M (1 2 3, 3 4 5, 5 6 7)", "POINT M (5 6 7)"),
1070+
("LINESTRING ZM (1 2 3 4, 3 4 5 6, 5 6 7 8)", "POINT ZM (5 6 7 8)"),
1071+
("POINT (1 2)", None),
1072+
("POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))", None),
1073+
("MULTILINESTRING ((1 2, 3 4), (5 6, 7 8))", None),
1074+
],
1075+
)
1076+
def test_st_end_point(eng, geometry, expected):
1077+
eng = eng.create_or_skip()
1078+
eng.assert_query_result(
1079+
f"SELECT ST_EndPoint({geom_or_null(geometry)})",
1080+
expected,
1081+
)
1082+
1083+
10191084
@pytest.mark.parametrize("eng", [SedonaDB, PostGIS])
10201085
@pytest.mark.parametrize(
10211086
("x", "y", "z", "m", "expected"),

rust/sedona-functions/benches/native-functions.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,22 @@ fn criterion_benchmark(c: &mut Criterion) {
126126
),
127127
);
128128

129+
benchmark::scalar(
130+
c,
131+
&f,
132+
"native",
133+
"st_startpoint",
134+
BenchmarkArgs::Array(LineString(10)),
135+
);
136+
137+
benchmark::scalar(
138+
c,
139+
&f,
140+
"native",
141+
"st_endpoint",
142+
BenchmarkArgs::Array(LineString(10)),
143+
);
144+
129145
benchmark::scalar(c, &f, "native", "st_x", Point);
130146
benchmark::scalar(c, &f, "native", "st_y", Point);
131147
benchmark::scalar(c, &f, "native", "st_z", Point);

rust/sedona-functions/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ mod st_point;
4949
mod st_pointzm;
5050
mod st_setsrid;
5151
mod st_srid;
52+
mod st_start_point;
5253
mod st_transform;
5354
pub mod st_union_aggr;
5455
mod st_xyzm;

rust/sedona-functions/src/register.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ pub fn default_function_set() -> FunctionSet {
9292
crate::st_setsrid::st_set_srid_udf,
9393
crate::st_srid::st_crs_udf,
9494
crate::st_srid::st_srid_udf,
95+
crate::st_start_point::st_end_point_udf,
96+
crate::st_start_point::st_start_point_udf,
9597
crate::st_xyzm::st_m_udf,
9698
crate::st_xyzm::st_x_udf,
9799
crate::st_xyzm::st_y_udf,

0 commit comments

Comments
 (0)