presto-geospatial/src/main/java/io/prestosql/plugin/geospatial/GeoFunctions.java/GeoFunctions/invalidReason
class GeoFunctions:    @Description("Returns the reason for why the input geometry is not valid. Returns null if the input is valid.")
    @ScalarFunction("geometry_invalid_reason")
    @SqlType(VARCHAR)
    @SqlNullable
    public static Slice invalidReason(@SqlType(GEOMETRY_TYPE_NAME) Slice input)
    {
        GeometryCursor cursor = deserialize(input).getEsriGeometryCursor();
        NonSimpleResult result = new NonSimpleResult();
        while (true) {
            com.esri.core.geometry.Geometry geometry = cursor.next();
            if (geometry == null) {
                return null;
            }

            if (!OperatorSimplifyOGC.local().isSimpleOGC(geometry, null, true, result, null)) {
                String reasonText = NON_SIMPLE_REASONS.getOrDefault(result.m_reason, result.m_reason.name());

                if (!(geometry instanceof MultiVertexGeometry)) {
                    return utf8Slice(reasonText);
                }

                MultiVertexGeometry multiVertexGeometry = (MultiVertexGeometry) geometry;
                if (result.m_vertexIndex1 >= 0 && result.m_vertexIndex2 >= 0) {
                    Point point1 = multiVertexGeometry.getPoint(result.m_vertexIndex1);
                    Point point2 = multiVertexGeometry.getPoint(result.m_vertexIndex2);
                    return utf8Slice(format("%s at or near (%s %s) and (%s %s)", reasonText, point1.getX(), point1.getY(), point2.getX(), point2.getY()));
                }

                if (result.m_vertexIndex1 >= 0) {
                    Point point = multiVertexGeometry.getPoint(result.m_vertexIndex1);
                    return utf8Slice(format("%s at or near (%s %s)", reasonText, point.getX(), point.getY()));
                }

                return utf8Slice(reasonText);
            }
        }
    }