diff --git a/Cargo.lock b/Cargo.lock
index 94550ec3..4ce2405e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4975,6 +4975,7 @@ dependencies = [
"geo-types",
"lru",
"rstest",
+ "sedona-testing",
"serde",
"serde_json",
"serde_with",
diff --git a/benchmarks/test_functions.py b/benchmarks/test_functions.py
index d8ec0083..ac77c145 100644
--- a/benchmarks/test_functions.py
+++ b/benchmarks/test_functions.py
@@ -167,6 +167,42 @@ def queries():
benchmark(queries)
+ @pytest.mark.parametrize(
+ "eng", [SedonaDBSingleThread, PostGISSingleThread, DuckDBSingleThread]
+ )
+ @pytest.mark.parametrize(
+ "table",
+ [
+ "collections_simple",
+ "collections_complex",
+ ],
+ )
+ def test_st_hasm(self, benchmark, eng, table):
+ eng = self._get_eng(eng)
+
+ def queries():
+ eng.execute_and_collect(f"SELECT ST_HasM(geom1) from {table}")
+
+ benchmark(queries)
+
+ @pytest.mark.parametrize(
+ "eng", [SedonaDBSingleThread, PostGISSingleThread, DuckDBSingleThread]
+ )
+ @pytest.mark.parametrize(
+ "table",
+ [
+ "collections_simple",
+ "collections_complex",
+ ],
+ )
+ def test_st_hasz(self, benchmark, eng, table):
+ eng = self._get_eng(eng)
+
+ def queries():
+ eng.execute_and_collect(f"SELECT ST_HasZ(geom1) from {table}")
+
+ benchmark(queries)
+
@pytest.mark.parametrize(
"eng", [SedonaDBSingleThread, PostGISSingleThread, DuckDBSingleThread]
)
diff --git a/python/sedonadb/tests/functions/test_functions.py b/python/sedonadb/tests/functions/test_functions.py
index 67cb81cd..86bb1ea1 100644
--- a/python/sedonadb/tests/functions/test_functions.py
+++ b/python/sedonadb/tests/functions/test_functions.py
@@ -561,8 +561,13 @@ def test_st_geomfromwkb(eng, geom):
("LINESTRING Z (0 0 0, 1 1 1)", True),
("POLYGON EMPTY", False),
("MULTIPOINT ((0 0), (1 1))", False),
+ ("MULTIPOINT Z ((0 0 0))", True),
+ ("MULTIPOINT ZM ((0 0 0 0))", True),
("GEOMETRYCOLLECTION EMPTY", False),
+ # Z-dim specified only in the nested geometry
("GEOMETRYCOLLECTION (POINT Z (0 0 0))", True),
+ # Z-dim specified on both levels
+ ("GEOMETRYCOLLECTION Z (POINT Z (0 0 0))", True),
("GEOMETRYCOLLECTION (GEOMETRYCOLLECTION (POINT Z (0 0 0)))", True),
],
)
diff --git a/rust/sedona-functions/src/st_haszm.rs b/rust/sedona-functions/src/st_haszm.rs
index a4a20fff..28320131 100644
--- a/rust/sedona-functions/src/st_haszm.rs
+++ b/rust/sedona-functions/src/st_haszm.rs
@@ -16,19 +16,17 @@
// under the License.
use std::sync::Arc;
-use crate::executor::WkbExecutor;
+use crate::executor::WkbBytesExecutor;
use arrow_array::builder::BooleanBuilder;
use arrow_schema::DataType;
-use datafusion_common::error::Result;
+use datafusion_common::{error::Result, DataFusionError};
use datafusion_expr::{
scalar_doc_sections::DOC_SECTION_OTHER, ColumnarValue, Documentation, Volatility,
};
-use geo_traits::GeometryCollectionTrait;
-use geo_traits::{Dimensions, GeometryTrait};
-use sedona_common::sedona_internal_err;
+use geo_traits::Dimensions;
use sedona_expr::scalar_udf::{SedonaScalarKernel, SedonaScalarUDF};
+use sedona_geometry::wkb_header::WkbHeader;
use sedona_schema::{datatypes::SedonaType, matchers::ArgMatcher};
-use wkb::reader::Wkb;
pub fn st_hasz_udf() -> SedonaScalarUDF {
SedonaScalarUDF::new(
@@ -91,13 +89,13 @@ impl SedonaScalarKernel for STHasZm {
_ => unreachable!(),
};
- let executor = WkbExecutor::new(arg_types, args);
+ let executor = WkbBytesExecutor::new(arg_types, args);
let mut builder = BooleanBuilder::with_capacity(executor.num_iterations());
executor.execute_wkb_void(|maybe_item| {
match maybe_item {
Some(item) => {
- builder.append_option(invoke_scalar(&item, dim_index)?);
+ builder.append_option(invoke_scalar(item, dim_index)?);
}
None => builder.append_null(),
}
@@ -108,27 +106,34 @@ impl SedonaScalarKernel for STHasZm {
}
}
-fn invoke_scalar(item: &Wkb, dim_index: usize) -> Result