Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
4356dbc
flag one function that highlights code that needs to change
paleolimbot Sep 2, 2025
31f8579
flag scalar methods
paleolimbot Sep 2, 2025
10f54e8
mark the array unwrapper
paleolimbot Sep 2, 2025
0a568e3
mark wrapper
paleolimbot Sep 2, 2025
760c948
mark array wrapper
paleolimbot Sep 2, 2025
5d79983
mark the arg wrapper
paleolimbot Sep 2, 2025
0ed9bac
mark the schema wrapper
paleolimbot Sep 2, 2025
a588308
mark the unwrapper
paleolimbot Sep 2, 2025
d4e5470
mark batch wrappers
paleolimbot Sep 2, 2025
028ba2d
format
paleolimbot Sep 2, 2025
2f7e477
scalar udf tests passing
paleolimbot Sep 3, 2025
b542c12
create and compare tests
paleolimbot Sep 3, 2025
c151854
fix the st_point tests
paleolimbot Sep 3, 2025
f69e7b3
undo wrap/unwrap in the aggregate udf
paleolimbot Sep 3, 2025
dd574f2
fix aggregators
paleolimbot Sep 3, 2025
8359fe0
fix xyzm
paleolimbot Sep 3, 2025
c82a456
fix setsrid test
paleolimbot Sep 3, 2025
8aa547d
woo sedona functions passes!
paleolimbot Sep 3, 2025
95be2b8
fix intersection aggregator
paleolimbot Sep 4, 2025
29f7e17
fix union aggregator
paleolimbot Sep 4, 2025
720e930
fix sedona-testing tests
paleolimbot Sep 4, 2025
41c656b
passing tests
paleolimbot Sep 4, 2025
d3a21bf
geoparquet tests
paleolimbot Sep 4, 2025
a295e70
start on spatial join
paleolimbot Sep 4, 2025
5de066b
fix geoarrow-c tests
paleolimbot Sep 4, 2025
cb72659
fix sedona-proj tests
paleolimbot Sep 4, 2025
1487e10
fix tg tests
paleolimbot Sep 4, 2025
9ef00f0
remove problematic converters
paleolimbot Sep 4, 2025
d138e17
fix one spatial join test
paleolimbot Sep 4, 2025
798194a
remove unused module
paleolimbot Sep 4, 2025
7c653f9
ffi and show tests
paleolimbot Sep 4, 2025
4699e97
sedona tests passing
paleolimbot Sep 4, 2025
448f395
fix expr tests
paleolimbot Sep 4, 2025
5770ea0
python tests
paleolimbot Sep 4, 2025
cbff4bd
fmt
paleolimbot Sep 4, 2025
45f6a7c
Merge branch 'main' into remove-wrap-unwrap
paleolimbot Sep 4, 2025
6510c96
fix point zm tests
paleolimbot Sep 4, 2025
85f20d7
fix one more test and ensure they all pass
paleolimbot Sep 4, 2025
22a9911
clippy
paleolimbot Sep 4, 2025
e51bd8d
remove unused projectors
paleolimbot Sep 4, 2025
01151d4
remove more code
paleolimbot Sep 4, 2025
0b68d5a
remove unnecessary uses of try_into() sedona type
paleolimbot Sep 4, 2025
a9dba5b
consolidate use of try_into.unwrap() for sedona types
paleolimbot Sep 4, 2025
02ce35e
a few more problems
paleolimbot Sep 4, 2025
4a10fd1
a few more
paleolimbot Sep 4, 2025
a0de0f8
fix doctest
paleolimbot Sep 4, 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
139 changes: 54 additions & 85 deletions c/sedona-geoarrow-c/src/kernels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,12 @@ pub fn st_geogfromwkb_impl() -> ScalarKernelRef {
/// An implementation of WKT writing using geoarrow-c's WKT writer
pub fn st_astext_impl() -> ScalarKernelRef {
Arc::new(GeoArrowCCast::new(
ArgMatcher::new(vec![ArgMatcher::is_geometry_or_geography()], STRING),
Some(STRING),
STRING,
ArgMatcher::new(
vec![ArgMatcher::is_geometry_or_geography()],
SedonaType::Arrow(DataType::Utf8),
),
Some(SedonaType::Arrow(DataType::Utf8)),
SedonaType::Arrow(DataType::Utf8),
))
}

Expand Down Expand Up @@ -139,99 +142,73 @@ impl SedonaScalarKernel for GeoArrowCCast {
}
}

const STRING: SedonaType = SedonaType::Arrow(DataType::Utf8);

#[cfg(test)]
mod tests {
use arrow_array::StringArray;
use arrow_schema::DataType;
use datafusion_common::scalar::ScalarValue;
use rstest::rstest;
use sedona_functions::register::default_function_set;
use sedona_expr::scalar_udf::SedonaScalarUDF;
use sedona_schema::datatypes::{WKB_GEOGRAPHY, WKB_GEOMETRY, WKB_VIEW_GEOMETRY};

use sedona_testing::{
compare::assert_value_equal,
create::{create_array_value, create_scalar_storage, create_scalar_value},
};
use sedona_testing::{create::create_scalar_storage, testers::ScalarUdfTester};

use super::*;

#[rstest]
fn fromwkt(#[values(DataType::Utf8, DataType::Utf8View)] data_type: DataType) {
let mut function_set = default_function_set();
let udf = function_set.scalar_udf_mut("st_geomfromwkt").unwrap();
udf.add_kernel(st_geomfromwkt_impl());

assert_value_equal(
&udf.invoke_batch(
&[
ColumnarValue::Scalar(ScalarValue::Utf8(Some("POINT (1 2)".to_string())))
.cast_to(&data_type, None)
.unwrap(),
],
1,
)
.unwrap(),
&create_scalar_value(Some("POINT (1 2)"), &WKB_GEOMETRY),
);
use sedona_testing::create::create_array;

let udf = SedonaScalarUDF::from_kernel("st_geomfromwkt", st_geomfromwkt_impl());
let tester = ScalarUdfTester::new(udf.into(), vec![SedonaType::Arrow(data_type)]);
tester.assert_return_type(WKB_GEOMETRY);

let result = tester.invoke_scalar("POINT (1 2)").unwrap();
tester.assert_scalar_result_equals(result, "POINT (1 2)");

let utf8_array: StringArray = [Some("POINT (1 2)"), None, Some("POINT (3 4)")]
.iter()
.collect();
let utf8_value = ColumnarValue::Array(Arc::new(utf8_array))
.cast_to(&data_type, None)
.unwrap();
assert_value_equal(
&udf.invoke_batch(&[utf8_value], 1).unwrap(),
&create_array_value(

assert_eq!(
&tester.invoke_array(Arc::new(utf8_array)).unwrap(),
&create_array(
&[Some("POINT (1 2)"), None, Some("POINT (3 4)")],
&WKB_GEOMETRY,
),
)
);
}

#[rstest]
fn fromwkb(#[values(WKB_GEOMETRY, WKB_VIEW_GEOMETRY)] data_type: SedonaType) {
let mut function_set = default_function_set();
let udf = function_set.scalar_udf_mut("st_geomfromwkb").unwrap();
udf.add_kernel(st_geomfromwkb_impl());

assert_value_equal(
&udf.invoke_batch(
&[create_scalar_storage(Some("POINT (1 2)"), &data_type).into()],
1,
)
.unwrap(),
&create_scalar_value(Some("POINT (1 2)"), &WKB_GEOMETRY),
let udf = SedonaScalarUDF::from_kernel("st_geomfromwkb", st_geomfromwkb_impl());
let tester = ScalarUdfTester::new(
udf.into(),
vec![SedonaType::Arrow(data_type.storage_type().clone())],
);
tester.assert_return_type(WKB_GEOMETRY);

let result = tester
.invoke_scalar(create_scalar_storage(Some("POINT (1 2)"), &data_type))
.unwrap();
tester.assert_scalar_result_equals(result, "POINT (1 2)");
}

#[rstest]
fn astext(#[values(WKB_GEOMETRY, WKB_VIEW_GEOMETRY)] data_type: SedonaType) {
let mut function_set = default_function_set();
let udf = function_set.scalar_udf_mut("st_astext").unwrap();
udf.add_kernel(st_astext_impl());

assert_value_equal(
&udf.invoke_batch(&[create_scalar_value(Some("POINT (1 2)"), &data_type)], 1)
.unwrap(),
&ScalarValue::Utf8(Some("POINT (1 2)".to_string())).into(),
);
let udf = SedonaScalarUDF::from_kernel("st_astext", st_astext_impl());
let tester = ScalarUdfTester::new(udf.into(), vec![data_type]);
tester.assert_return_type(DataType::Utf8);

let result = tester.invoke_scalar("POINT (1 2)").unwrap();
assert_eq!(result, ScalarValue::Utf8(Some("POINT (1 2)".to_string())));
}

#[test]
fn errors() {
let mut function_set = default_function_set();
let udf = function_set.scalar_udf_mut("st_geomfromwkt").unwrap();
udf.add_kernel(st_geomfromwkt_impl());

let err = udf
.invoke_batch(
&[ScalarValue::Utf8(Some("this is not valid wkt".to_string())).into()],
1,
)
.unwrap_err();
let udf = SedonaScalarUDF::from_kernel("st_geomfromwkt", st_geomfromwkt_impl());
let tester = ScalarUdfTester::new(udf.into(), vec![SedonaType::Arrow(DataType::Utf8)]);
let err = tester.invoke_scalar("This is not valid wkt").unwrap_err();

assert_eq!(
err.message(),
Expand All @@ -241,28 +218,20 @@ mod tests {

#[test]
fn geog() {
let mut function_set = default_function_set();
let udf = function_set.scalar_udf_mut("st_geogfromwkt").unwrap();
udf.add_kernel(st_geogfromwkt_impl());

assert_value_equal(
&udf.invoke_batch(
&[ScalarValue::Utf8(Some("POINT (1 2)".to_string())).into()],
1,
)
.unwrap(),
&create_scalar_value(Some("POINT (1 2)"), &WKB_GEOGRAPHY),
);
let udf = SedonaScalarUDF::from_kernel("st_geogfromwkt", st_geogfromwkt_impl());
let tester = ScalarUdfTester::new(udf.into(), vec![SedonaType::Arrow(DataType::Utf8)]);
tester.assert_return_type(WKB_GEOGRAPHY);

let udf = function_set.scalar_udf_mut("st_geogfromwkb").unwrap();
udf.add_kernel(st_geogfromwkb_impl());
assert_value_equal(
&udf.invoke_batch(
&[create_scalar_storage(Some("POINT (1 2)"), &WKB_GEOGRAPHY).into()],
1,
)
.unwrap(),
&create_scalar_value(Some("POINT (1 2)"), &WKB_GEOGRAPHY),
);
let result = tester.invoke_scalar("POINT (1 2)").unwrap();
tester.assert_scalar_result_equals(result, "POINT (1 2)");

let udf = SedonaScalarUDF::from_kernel("st_geogfromwkb", st_geogfromwkb_impl());
let tester = ScalarUdfTester::new(udf.into(), vec![SedonaType::Arrow(DataType::Binary)]);
tester.assert_return_type(WKB_GEOGRAPHY);

let result = tester
.invoke_scalar(create_scalar_storage(Some("POINT (1 2)"), &WKB_GEOGRAPHY))
.unwrap();
tester.assert_scalar_result_equals(result, "POINT (1 2)");
}
}
2 changes: 1 addition & 1 deletion c/sedona-geos/src/binary_predicates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl<Op: BinaryPredicate> SedonaScalarKernel for GeosPredicate<Op> {
fn return_type(&self, args: &[SedonaType]) -> Result<Option<SedonaType>> {
let matcher: ArgMatcher = ArgMatcher::new(
vec![ArgMatcher::is_geometry(), ArgMatcher::is_geometry()],
DataType::Boolean.try_into().unwrap(),
SedonaType::Arrow(DataType::Boolean),
);

matcher.match_args(args)
Expand Down
2 changes: 1 addition & 1 deletion c/sedona-geos/src/distance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl SedonaScalarKernel for STDistance {
fn return_type(&self, args: &[SedonaType]) -> Result<Option<SedonaType>> {
let matcher = ArgMatcher::new(
vec![ArgMatcher::is_geometry(), ArgMatcher::is_geometry()],
DataType::Float64.try_into()?,
SedonaType::Arrow(DataType::Float64),
);

matcher.match_args(args)
Expand Down
2 changes: 1 addition & 1 deletion c/sedona-geos/src/st_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl SedonaScalarKernel for STArea {
fn return_type(&self, args: &[SedonaType]) -> Result<Option<SedonaType>> {
let matcher = ArgMatcher::new(
vec![ArgMatcher::is_geometry()],
DataType::Float64.try_into().unwrap(),
SedonaType::Arrow(DataType::Float64),
);

matcher.match_args(args)
Expand Down
2 changes: 1 addition & 1 deletion c/sedona-geos/src/st_dwithin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl SedonaScalarKernel for STDWithin {
ArgMatcher::is_geometry(),
ArgMatcher::is_numeric(),
],
DataType::Boolean.try_into().unwrap(),
SedonaType::Arrow(DataType::Boolean),
);

matcher.match_args(args)
Expand Down
2 changes: 1 addition & 1 deletion c/sedona-geos/src/st_length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl SedonaScalarKernel for STLength {
fn return_type(&self, args: &[SedonaType]) -> Result<Option<SedonaType>> {
let matcher = ArgMatcher::new(
vec![ArgMatcher::is_geometry()],
DataType::Float64.try_into()?,
SedonaType::Arrow(DataType::Float64),
);

matcher.match_args(args)
Expand Down
2 changes: 1 addition & 1 deletion c/sedona-geos/src/st_perimeter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl SedonaScalarKernel for STPerimeter {
fn return_type(&self, args: &[SedonaType]) -> Result<Option<SedonaType>> {
let matcher = ArgMatcher::new(
vec![ArgMatcher::is_geometry()],
DataType::Float64.try_into()?,
SedonaType::Arrow(DataType::Float64),
);

matcher.match_args(args)
Expand Down
4 changes: 2 additions & 2 deletions c/sedona-proj/src/st_transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ mod tests {

let arg_fields: Vec<Arc<Field>> = arg_types
.into_iter()
.map(|arg_type| Arc::new(Field::new("", arg_type.data_type(), true)))
.map(|arg_type| Arc::new(arg_type.to_storage_field("", true).unwrap()))
.collect();
let row_count = wkb.len();

Expand All @@ -433,7 +433,7 @@ mod tests {
};

let return_field = udf.return_field_from_args(return_field_args)?;
let return_type = SedonaType::from_data_type(return_field.data_type())?;
let return_type = SedonaType::from_storage_field(&return_field)?;

let args = ScalarFunctionArgs {
args: arg_vals,
Expand Down
24 changes: 12 additions & 12 deletions c/sedona-s2geography/src/scalar_kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub fn st_area_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::Area,
vec![ArgMatcher::is_geography()],
DataType::Float64.try_into().unwrap(),
SedonaType::Arrow(DataType::Float64),
)
}

Expand All @@ -56,7 +56,7 @@ pub fn st_contains_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::Contains,
vec![ArgMatcher::is_geography(), ArgMatcher::is_geography()],
DataType::Boolean.try_into().unwrap(),
SedonaType::Arrow(DataType::Boolean),
)
}

Expand All @@ -83,7 +83,7 @@ pub fn st_distance_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::Distance,
vec![ArgMatcher::is_geography(), ArgMatcher::is_geography()],
DataType::Float64.try_into().unwrap(),
SedonaType::Arrow(DataType::Float64),
)
}

Expand All @@ -92,7 +92,7 @@ pub fn st_equals_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::Equals,
vec![ArgMatcher::is_geography(), ArgMatcher::is_geography()],
DataType::Boolean.try_into().unwrap(),
SedonaType::Arrow(DataType::Boolean),
)
}

Expand All @@ -110,7 +110,7 @@ pub fn st_intersects_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::Intersects,
vec![ArgMatcher::is_geography(), ArgMatcher::is_geography()],
DataType::Boolean.try_into().unwrap(),
SedonaType::Arrow(DataType::Boolean),
)
}

Expand All @@ -119,7 +119,7 @@ pub fn st_length_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::Length,
vec![ArgMatcher::is_geography()],
DataType::Float64.try_into().unwrap(),
SedonaType::Arrow(DataType::Float64),
)
}

Expand All @@ -137,7 +137,7 @@ pub fn st_line_locate_point_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::LineLocatePoint,
vec![ArgMatcher::is_geography(), ArgMatcher::is_geography()],
DataType::Float64.try_into().unwrap(),
SedonaType::Arrow(DataType::Float64),
)
}

Expand All @@ -146,7 +146,7 @@ pub fn st_max_distance_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::MaxDistance,
vec![ArgMatcher::is_geography(), ArgMatcher::is_geography()],
DataType::Float64.try_into().unwrap(),
SedonaType::Arrow(DataType::Float64),
)
}

Expand All @@ -155,7 +155,7 @@ pub fn st_perimeter_impl() -> ScalarKernelRef {
S2ScalarKernel::new_ref(
S2ScalarUDF::Perimeter,
vec![ArgMatcher::is_geography()],
DataType::Float64.try_into().unwrap(),
SedonaType::Arrow(DataType::Float64),
)
}

Expand Down Expand Up @@ -274,7 +274,7 @@ mod test {
let tester = ScalarUdfTester::new(udf.into(), vec![sedona_type]);
assert_eq!(
tester.return_type().unwrap(),
DataType::Float64.try_into().unwrap()
SedonaType::Arrow(DataType::Float64)
);

// Array -> Array
Expand Down Expand Up @@ -308,7 +308,7 @@ mod test {
ScalarUdfTester::new(udf.into(), vec![sedona_type.clone(), sedona_type.clone()]);
assert_eq!(
tester.return_type().unwrap(),
DataType::Boolean.try_into().unwrap()
SedonaType::Arrow(DataType::Boolean)
);

let point_array = create_array(
Expand Down Expand Up @@ -463,7 +463,7 @@ mod test {
);
let tester = ScalarUdfTester::new(
udf.into(),
vec![WKB_GEOGRAPHY, DataType::Float64.try_into().unwrap()],
vec![WKB_GEOGRAPHY, SedonaType::Arrow(DataType::Float64)],
);
tester.assert_return_type(WKB_GEOGRAPHY);
let result = tester
Expand Down
Loading