@Description("Returns true if the input geometry is well formed")
    @ScalarFunction("ST_IsValid")
    @SqlType(BOOLEAN)
    public static boolean stIsValid(@SqlType(GEOMETRY_TYPE_NAME) Slice input)
    {
        try {
            return deserialize(input).isValid();
        }
        catch (PrestoException e) {
            if (e.getCause() instanceof TopologyException) {
                return false;
            }
            throw e;
        }
    }
@Test
    public void testSTIsValid()
    {
        // empty geometries are valid
        assertValidGeometry("POINT EMPTY");
        assertValidGeometry("MULTIPOINT EMPTY");
        assertValidGeometry("LINESTRING EMPTY");
        assertValidGeometry("MULTILINESTRING EMPTY");
        assertValidGeometry("POLYGON EMPTY");
        assertValidGeometry("MULTIPOLYGON EMPTY");
        assertValidGeometry("GEOMETRYCOLLECTION EMPTY");

        // valid geometries
        assertValidGeometry("POINT (1 2)");
        assertValidGeometry("MULTIPOINT (1 2, 3 4)");
        assertValidGeometry("LINESTRING (0 0, 1 2, 3 4)");
        assertValidGeometry("MULTILINESTRING ((1 1, 5 1), (2 4, 4 4))");
        assertValidGeometry("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))");
        assertValidGeometry("MULTIPOLYGON (((1 1, 1 3, 3 3, 3 1, 1 1)), ((2 4, 2 6, 6 6, 6 4, 2 4)))");
        assertValidGeometry("GEOMETRYCOLLECTION (POINT (1 2), LINESTRING (0 0, 1 2, 3 4), POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0)))");
        assertValidGeometry("MULTIPOINT ((0 0), (0 1), (1 1), (0 1))");
        // JTS considers LineStrings with repeated points valid/simple (it drops the dups)
        assertValidGeometry("LINESTRING (0 0, 0 1, 0 1, 1 1, 1 0, 0 0)");
        // Valid but not simple
        assertValidGeometry("LINESTRING (0 0, -1 0.5, 0 1, 1 1, 1 0, 0 1, 0 0)");

        // invalid geometries
        assertInvalidGeometry("POLYGON ((0 0, 1 1, 0 1, 1 0, 0 0))");
        assertInvalidGeometry("POLYGON ((0 0, 0 1, 0 1, 1 1, 1 0, 0 0), (2 2, 2 3, 3 3, 3 2, 2 2))");
        assertInvalidGeometry("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0), (2 2, 2 3, 3 3, 3 2, 2 2))");
        assertInvalidGeometry("POLYGON ((0 0, 0 1, 2 1, 1 1, 1 0, 0 0))");
        assertInvalidGeometry("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0), (0 1, 1 1, 0.5 0.5, 0 1))");
        assertInvalidGeometry("POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0), (0 0, 0.5 0.7, 1 1, 0.5 0.4, 0 0))");
        assertInvalidGeometry("POLYGON ((0 0, -1 0.5, 0 1, 1 1, 1 0, 0 1, 0 0))");
        assertInvalidGeometry("MULTIPOLYGON (((0 0, 0 1, 1 1, 1 0, 0 0)), ((0.5 0.5, 0.5 2, 2 2, 2 0.5, 0.5 0.5)))");
        assertInvalidGeometry("GEOMETRYCOLLECTION (POINT (1 2), POLYGON ((0 0, 0 1, 2 1, 1 1, 1 0, 0 0)))");

        // corner cases
        assertFunction("ST_IsValid(ST_GeometryFromText(null))", BOOLEAN, null);
        assertFunction("geometry_invalid_reason(ST_GeometryFromText(null))", VARCHAR, null);
    }