Skip to content

Align polygon orientation predicates with PostGIS in Sedona 2.0.0 #3174

Description

@jiayuasu

Expected behavior

In Sedona 2.0.0, or another major release, ST_IsPolygonCW and ST_IsPolygonCCW should align with the full PostGIS polygonal-component semantics:

  • Recursively inspect polygonal components inside geometry collections.
  • Ignore non-polygonal components.
  • Return true when an input has no polygonal components, including points, line strings, and empty geometry collections.
  • Return NULL for SQL NULL inputs across all engines.

This follows the documented PostGIS behavior:

Actual behavior

Sedona currently returns false for non-polygonal inputs such as points and line strings. It also returns false for geometry collections instead of recursively evaluating their polygonal members.

Changing these results from false to true is user-visible and potentially breaking. PR #3173 should therefore remain scoped to fixing empty Polygon and MultiPolygon handling without changing established results for other geometry types.

The Flink wrappers also currently use primitive boolean return types, so matching PostGIS SQL null propagation requires changing them to nullable Boolean.

Steps to reproduce the problem

-- PostGIS returns true from both predicates because there are no polygonal components.
SELECT
    ST_IsPolygonCW(ST_GeomFromWKT('POINT (0 0)')),
    ST_IsPolygonCCW(ST_GeomFromWKT('POINT (0 0)'));

SELECT
    ST_IsPolygonCW(ST_GeomFromWKT('LINESTRING (0 0, 1 0, 0 0)')),
    ST_IsPolygonCCW(ST_GeomFromWKT('LINESTRING (0 0, 1 0, 0 0)'));

-- PostGIS ignores the point and recursively checks the clockwise polygon.
SELECT
    ST_IsPolygonCW(
        ST_GeomFromWKT(
            'GEOMETRYCOLLECTION (
                POINT (2 2),
                GEOMETRYCOLLECTION (
                    POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))
                )
            )'
        )
    );

Sedona returns false for these cases. The corresponding PostGIS results are true.

Because this change alters existing predicate results, it should include migration notes and be released only with a major-version compatibility boundary.

Settings

Sedona version = 1.9.1-SNAPSHOT

Apache Spark version = 3.4

Apache Flink version = 1.19

API type = Common Java functions, Spark SQL, Flink SQL, Snowflake UDFs

Scala version = 2.12

JRE version = 11 and 17

Python version = N/A

Environment = Standalone

Related issues and pull requests: #3171, #3173

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions