databendlabs/databend · error
polygon geometry
Error message
polygon geometry
What it means
In geographic overlay's `build_geometry_from_elements`, when all elements are `Geometry::Polygon(_)`, each is converted with `try_into().expect("polygon geometry")` to produce a MultiPolygon. The type guard should guarantee success, so this panic means the Polygon TryFrom impl failed on a guarded value — an internal invariant break or invalid polygon data generated during overlay.
Solutions
- Validate overlay-produced polygons (non-empty valid exterior ring).
- Check the geo crate TryFrom impl for the version in use.
- Propagate conversion failure as `None` per the function's Option contract instead of panicking.
Example fix
// before
.map(|geo| geo.try_into().expect("polygon geometry"))
// after
.map(|geo| geo.try_into().ok())
.collect::<Option<Vec<_>>>()?; Defensive patterns
Strategy: validation
Validate before calling
// before overlay: let valid = geoms.iter().all(|g| matches!(g, Geometry::Polygon(p) if !p.exterior().coords().is_empty()));
Type guard
fn has_valid_exterior(g: &Geometry) -> bool { matches!(g, Geometry::Polygon(p) if p.exterior().coords().count() >= 4) } Try / catch
let result = std::panic::catch_unwind(|| overlay(geoms.clone()));
Prevention
- Pre-validate polygon rings before overlay to avoid degenerate outputs.
- Handle self-intersecting inputs with a validity check (e.g. geo's is_valid) first.
- File a bug with the input geometries if this panic reproduces — the guard should prevent it.
When it happens
Trigger: Overlay results composed entirely of polygons where the `TryFrom<Geometry> for Polygon<f64>` conversion returns Err — e.g. polygons with empty or self-invalid rings produced by the overlay algorithm.
Common situations: Overlaying complex/self-intersecting polygons producing degenerate results; geo crate version drift; floating-point precision issues corrupting rings.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/50bd5d0d3b776c6d.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/expression/src/geographic/overlay.rs:170
if elements
.iter()
.all(|geo| matches!(geo, Geometry::LineString(_)))
{
let lines: Vec<LineString<f64>> = elements
.into_iter()
.map(|geo| geo.try_into().expect("linestring geometry"))
.collect();
return Some(Geometry::MultiLineString(MultiLineString::from_iter(lines)));
}
if elements
.iter()
.all(|geo| matches!(geo, Geometry::Polygon(_)))
{
let polygons: Vec<Polygon<f64>> = elements
.into_iter()
.map(|geo| geo.try_into().expect("polygon geometry"))
.collect();
return Some(Geometry::MultiPolygon(MultiPolygon::from_iter(polygons)));
}
Some(Geometry::GeometryCollection(GeometryCollection::from_iter(
elements,
)))
}
fn apply_union_iter<I>(&self, geos: I) -> Result<Option<Geometry<f64>>>
where I: IntoIterator<Item = Geometry<f64>> {
let mut merged = OverlayParts::default();
let mut has_input = false;
for geo in geos {
let parts = Self::prepare_operand(&geo)?;
Self::extend_parts(&mut merged, parts);
has_input = true;View on GitHub (pinned to 288d84d76e)