Skip to content

feat(rust/sedona-functions): Implement ST_GeomFromEWKT#498

Merged
paleolimbot merged 15 commits intoapache:mainfrom
yutannihilation:feat/geom_from_ewkt
Jan 10, 2026
Merged

feat(rust/sedona-functions): Implement ST_GeomFromEWKT#498
paleolimbot merged 15 commits intoapache:mainfrom
yutannihilation:feat/geom_from_ewkt

Conversation

@yutannihilation
Copy link
Contributor

Now that we have item-level CRS, I think ST_GeomFromEWKT can be implemented. Unlike ST_GeomFromEWKB (#490), if I understand correctly, EWKT doesn't need a dedicated parser except for spliting SRID=...; and pass the rest to the existing WKT parser.

It seems to work. I think I still don't understand how the item-level CRS should be handled, so this pull request takes some more time to finish.

> select st_geomfromewkt('SRID=3857;POINT (1 1)');
┌────────────────────────────────────────────────┐
│ st_geomfromewkt(Utf8("SRID=3857;POINT (1 1)")) │
│                     struct                     │
╞════════════════════════════════════════════════╡
│ {item: POINT(1 1), crs: EPSG:3857}             │
└────────────────────────────────────────────────┘
> select st_geomfromewkt('POINT (1 1)');
┌──────────────────────────────────────┐
│ st_geomfromewkt(Utf8("POINT (1 1)")) │
│                struct                │
╞══════════════════════════════════════╡
│ {item: POINT(1 1), crs: }            │
└──────────────────────────────────────┘

Copy link
Member

@paleolimbot paleolimbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only minor nits from me...this looks great!

I think I still don't understand how the item-level CRS should be handled

Me too! Supporting both type-level and item-level CRS is new territory and feel free to flag anything that doesn't make sense.

Comment on lines +178 to +179
// TODO
// engine: Option<Arc<dyn CrsEngine + Send + Sync>>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to leave this out for now...the CRS engine variants of some of the other functions aren't currently used with an engine and we probably need a more reliable way to inject support for validation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, thanks. Then, I remove this. I noticed engine is currently unused, but wondered if this is somehow useful for testing.

Comment on lines +254 to +257
let srid: u16 = match srid_str.parse() {
Ok(srid) => srid,
Err(_) => return None,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be a U32?

Comment on lines +401 to +410
DataType::Utf8View => arrow_array::create_array!(
Utf8View,
[
Some("SRID=4326;POINT (1 2)"),
Some("SRID=3857;POINT (1 2)"),
None,
Some("POINT (3 4)"),
Some("SRID=0;POINT (5 6)")
]
) as ArrayRef,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need the repeated case here (I'm pretty sure tester.invoke_array() will do that cast for you).

Copy link
Member

@paleolimbot paleolimbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

I opened #501 to track CRS validation. There are a number of places where the situation can and should be improved 🙂

Co-authored-by: Dewey Dunnington <dewey@dunnington.ca>
@yutannihilation yutannihilation marked this pull request as ready for review January 9, 2026 22:54
@yutannihilation
Copy link
Contributor Author

I kept this pull request draft as I was wondering if I should add Python tests. However, since the output is different from PostGIS, probably it's not worth...? If I should add some, I can do.

@paleolimbot
Copy link
Member

I kept this pull request draft as I was wondering if I should add Python tests.

In this case you probably could check ST_SRID(ST_GeomFromEWKT(...)) and ST_AsText(ST_GeomFromEWKT(...)), which I think should be the same in both PostGIS and SedonaDB now, although I wasn't personally expecting anybody to try this yet (there's no helpers for this in Python land at the moment!)

@yutannihilation
Copy link
Contributor Author

Thanks, I added some tests, but I found ST_AsText() doesn't work on per-item-CRS geometry yet. So, I think testing only the SRID is enough for now.

> SELECT ST_AsText(ST_GeomFromEWKT('POINT(0 0)'));
This feature is not implemented: st_astext([Arrow(Struct([Field { data_type: Binary, nullable: true, metadata: {"ARROW:extension:name": "geoarrow.wkb", "ARROW:extension:metadata": "{}"} }, Field { name: "crs", data_type: Utf8View, nullable: true }]))]): No kernel matching arguments

Comment on lines +1312 to +1316
# TODO: currently, a per-item-CRS geometry cannot be cast to string
# eng.assert_query_result(
# f"SELECT ST_GeomFromEWKT({val_or_null(ewkt)})",
# expected,
# )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you rebase or merge in the main branch I think this will work:

Suggested change
# TODO: currently, a per-item-CRS geometry cannot be cast to string
# eng.assert_query_result(
# f"SELECT ST_GeomFromEWKT({val_or_null(ewkt)})",
# expected,
# )
eng.assert_query_result(
f"SELECT ST_AsWKT(ST_GeomFromEWKT({val_or_null(ewkt)}))",
expected,
)

ItemCrsKernel::wrap_impl(vec![Arc::new(STAsText {})]),

Also feel free to remove this bit and I can follow up when I do ST_GeomFromEKWB() (FWIW I prefer not to merge TODOs that don't have an tracker link associated with them, since TODOs in the code base are much harder to prioritize than issues.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough! Then, I remove this for now as ST_AsWKT() doesn't work either.

@yutannihilation
Copy link
Contributor Author

Sorry, I just didn't notice ST_AsText() needs #492 to work. Added the test again.

Copy link
Member

@paleolimbot paleolimbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@paleolimbot paleolimbot merged commit edcb909 into apache:main Jan 10, 2026
15 checks passed
@yutannihilation yutannihilation deleted the feat/geom_from_ewkt branch January 10, 2026 04:02
pwrliang pushed a commit to pwrliang/sedona-db that referenced this pull request Jan 15, 2026
Co-authored-by: Dewey Dunnington <dewey@dunnington.ca>
pwrliang pushed a commit to pwrliang/sedona-db that referenced this pull request Jan 15, 2026
Co-authored-by: Dewey Dunnington <dewey@dunnington.ca>
@paleolimbot paleolimbot added this to the 0.3.0 milestone Jan 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants