Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions contrib/babelfishpg_common/sql/geography.sql
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,60 @@ CREATE OR REPLACE FUNCTION sys.Geography__stgeomfromtext(sys.NVARCHAR, integer)
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.Geography__STMPointFromText(sys.NVARCHAR, srid integer)
RETURNS sys.GEOGRAPHY
AS $$
DECLARE
Geomtype text;
geog sys.GEOGRAPHY;
BEGIN
IF $2 IS NULL THEN
RAISE EXCEPTION '''geography::STMPointFromText'' failed because parameter 2 is not allowed to be null.';
ELSIF $1 IS NULL THEN
RETURN NULL;
END IF;

geog = sys.geogfromtext_helper($1::text, $2);
Geomtype = sys.ST_GeometryType(geog);

IF Geomtype = 'ST_MultiPoint' THEN
RETURN geog;
ELSE
RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', $1;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;


CREATE OR REPLACE FUNCTION sys.Geography__STMPointFromWKB(sys.VARBINARY, srid integer)
RETURNS sys.GEOGRAPHY
AS $$
DECLARE
Geomtype text;
geog sys.GEOGRAPHY;
BEGIN
IF $2 IS NULL THEN
RAISE EXCEPTION '''geography::STMPointFromWKB'' failed because parameter 2 is not allowed to be null.';
ELSIF $1 IS NULL THEN
RETURN NULL;
END IF;

geog = sys.geogfromwkb_helper($1::bytea, $2);
Geomtype = sys.ST_GeometryType(geog);

IF Geomtype = 'ST_MultiPoint' THEN
RETURN geog;
ELSE
RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', Geomtype;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.geogfromwkb_helper(bytea, integer)
RETURNS sys.GEOGRAPHY
AS 'babelfishpg_common', 'get_geography_from_wkb'
LANGUAGE 'c' IMMUTABLE PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.STAsText(sys.GEOGRAPHY)
RETURNS sys.NVARCHAR
AS $$
Expand Down
54 changes: 54 additions & 0 deletions contrib/babelfishpg_common/sql/geometry.sql
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,60 @@ CREATE OR REPLACE FUNCTION sys.Geometry__STPolyFromText(sys.NVARCHAR,srid intege
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.Geometry__STMPointFromText(sys.NVARCHAR, srid integer)
RETURNS sys.GEOMETRY
AS $$
DECLARE
Geomtype text;
geom sys.GEOMETRY;
BEGIN
IF $2 IS NULL THEN
RAISE EXCEPTION '''geometry::STMPointFromText'' failed because parameter 2 is not allowed to be null.';
ELSIF $1 IS NULL THEN
RETURN NULL;
END IF;

geom = sys.geomfromtext_helper($1::text, $2);
Geomtype = sys.ST_GeometryType(geom);

IF Geomtype = 'ST_MultiPoint' THEN
RETURN geom;
ELSE
RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', $1;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.Geometry__STMPointFromWKB(sys.VARBINARY, srid integer)
RETURNS sys.GEOMETRY
AS $$
DECLARE
Geomtype text;
geom sys.GEOMETRY;
BEGIN
IF $2 IS NULL THEN
RAISE EXCEPTION '''geometry::STMPointFromWKB'' failed because parameter 2 is not allowed to be null.';
ELSIF $1 IS NULL THEN
RETURN NULL;
END IF;

geom = sys.geomfromwkb_helper($1::bytea, $2);
Geomtype = sys.ST_GeometryType(geom);

IF Geomtype = 'ST_MultiPoint' THEN
RETURN geom;
ELSE
RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', Geomtype;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;


CREATE OR REPLACE FUNCTION sys.geomfromwkb_helper(bytea, integer)
RETURNS sys.GEOMETRY
AS 'babelfishpg_common', 'get_geometry_from_wkb'
LANGUAGE 'c' IMMUTABLE PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.ST_GeometryType(sys.GEOMETRY)
RETURNS text
AS '$libdir/postgis-3', 'geometry_geometrytype'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,119 @@ CREATE OR REPLACE FUNCTION sys.STGeometryType(geog sys.GEOGRAPHY)
RAISE EXCEPTION 'Unexpected geometry type format: %. Expected ST_* prefix.', geom_type;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;

--geometry
--STMPointFromText

CREATE OR REPLACE FUNCTION sys.Geometry__STMPointFromText(sys.NVARCHAR, srid integer)
RETURNS sys.GEOMETRY
AS $$
DECLARE
Geomtype text;
geom sys.GEOMETRY;
BEGIN
IF $2 IS NULL THEN
RAISE EXCEPTION '''geometry::STMPointFromText'' failed because parameter 2 is not allowed to be null.';
ELSIF $1 IS NULL THEN
RETURN NULL;
END IF;

geom = sys.geomfromtext_helper($1::text, $2);
Geomtype = sys.ST_GeometryType(geom);

IF Geomtype = 'ST_MultiPoint' THEN
RETURN geom;
ELSE
RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', $1;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;

--Geography
--STMPointFromText

CREATE OR REPLACE FUNCTION sys.Geography__STMPointFromText(sys.NVARCHAR, srid integer)
RETURNS sys.GEOGRAPHY
AS $$
DECLARE
Geomtype text;
geog sys.GEOGRAPHY;
BEGIN
IF $2 IS NULL THEN
RAISE EXCEPTION '''geography::STMPointFromText'' failed because parameter 2 is not allowed to be null.';
ELSIF $1 IS NULL THEN
RETURN NULL;
END IF;

geog = sys.geogfromtext_helper($1::text, $2);
Geomtype = sys.ST_GeometryType(geog);

IF Geomtype = 'ST_MultiPoint' THEN
RETURN geog;
ELSE
RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', $1;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;


CREATE OR REPLACE FUNCTION sys.Geography__STMPointFromWKB(sys.VARBINARY, srid integer)
RETURNS sys.GEOGRAPHY
AS $$
DECLARE
Geomtype text;
geog sys.GEOGRAPHY;
BEGIN
IF $2 IS NULL THEN
RAISE EXCEPTION '''geography::STMPointFromWKB'' failed because parameter 2 is not allowed to be null.';
ELSIF $1 IS NULL THEN
RETURN NULL;
END IF;

geog = sys.geogfromwkb_helper($1::bytea, $2);
Geomtype = sys.ST_GeometryType(geog);

IF Geomtype = 'ST_MultiPoint' THEN
RETURN geog;
ELSE
RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', Geomtype;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;

CREATE OR REPLACE FUNCTION sys.geogfromwkb_helper(bytea, integer)
RETURNS sys.GEOGRAPHY
AS 'babelfishpg_common', 'get_geography_from_wkb'
LANGUAGE 'c' IMMUTABLE PARALLEL SAFE;



CREATE OR REPLACE FUNCTION sys.Geometry__STMPointFromWKB(sys.VARBINARY, srid integer)
RETURNS sys.GEOMETRY
AS $$
DECLARE
Geomtype text;
geom sys.GEOMETRY;
BEGIN
IF $2 IS NULL THEN
RAISE EXCEPTION '''geometry::STMPointFromWKB'' failed because parameter 2 is not allowed to be null.';
ELSIF $1 IS NULL THEN
RETURN NULL;
END IF;

geom = sys.geomfromwkb_helper($1::bytea, $2);
Geomtype = sys.ST_GeometryType(geom);

IF Geomtype = 'ST_MultiPoint' THEN
RETURN geom;
ELSE
RAISE EXCEPTION 'Expected "MULTIPOINT" at Position 1. The input has %s', Geomtype;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;


CREATE OR REPLACE FUNCTION sys.geomfromwkb_helper(bytea, integer)
RETURNS sys.GEOMETRY
AS 'babelfishpg_common', 'get_geometry_from_wkb'
LANGUAGE 'c' IMMUTABLE PARALLEL SAFE;
91 changes: 91 additions & 0 deletions contrib/babelfishpg_common/src/geo.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#define FLAGS_GET_Z(flags) ((flags) & POINTFLAG_Z)
#define FLAGS_GET_M(flags) ((flags) & POINTFLAG_M)

typedef void (*PointFormatter)(StringInfoData *, POINT);

text*
geo_wkt_rewrite(text* input_text)
{
Expand Down Expand Up @@ -389,6 +391,36 @@ format_postgis_point_coordinates(StringInfoData *output, POINT p)
}
}

/* pfree(pa->points); pfree(pa); pattern */
static void
free_point_array(PointArray *pa)
{
if (!pa)
return;
if (pa->points)
pfree(pa->points);
pfree(pa);
}

/* Replaces the repeated for-loop that formats points */
static void
append_formatted_points(StringInfoData *output, PointArray *pa, bool wrap_each, PointFormatter formatter)
{
for (int i = 0; i < pa->count; i++)
{
if (wrap_each)
appendStringInfoChar(output, '(');

formatter(output, pa->points[i]);

if (wrap_each)
appendStringInfoChar(output, ')');

if (i < pa->count - 1)
appendStringInfoString(output, ", ");
}
}

/*
* Converts a PointArray to a PostGIS-compatible LINESTRING WKT representation
* Determines the appropriate dimension type (Z, M, ZM, etc.) based on the points,
Expand Down Expand Up @@ -667,3 +699,62 @@ rewrite_dim_polygon_query(PointArrayList *pal)

return output.data;
}

char*
rewrite_multipoint_wkt(PointArray *pa)
{
DimensionType type;
StringInfoData output;

if (!pa || pa->count == 0)
{
free_point_array(pa);
return pstrdup("MULTIPOINT EMPTY");
}

initStringInfo(&output);

type = determine_ptarray_type(pa);

appendStringInfoString(&output, "MULTIPOINT");

if (type == M)
appendStringInfoString(&output, " M");

appendStringInfoChar(&output, '(');

transform_points(pa, type);

append_formatted_points(&output, pa, true, format_tsql_point_coordinates);

appendStringInfoChar(&output, ')');

free_point_array(pa);

return output.data;
}


char*
rewrite_dim_multipoint_wkt(PointArray *pa)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This and the above function share a lot of common code, can we extract the logic to helper function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

{
StringInfoData output;

if (!pa || pa->count == 0)
{
free_point_array(pa);
return pstrdup("MULTIPOINT EMPTY");
}

initStringInfo(&output);

appendStringInfoString(&output, "MULTIPOINT(");

append_formatted_points(&output, pa, true, format_postgis_point_coordinates);

appendStringInfoChar(&output, ')');

free_point_array(pa);

return output.data;
}
4 changes: 4 additions & 0 deletions contrib/babelfishpg_common/src/geo_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,9 @@ char* rewrite_polygon_query(PointArrayList *pal);
char* rewrite_dim_polygon_query(PointArrayList *pal);
DimensionType determine_ring_type(PointArrayList *pal);

char* rewrite_multipoint_wkt(PointArray *pa);
char* rewrite_dim_multipoint_wkt(PointArray *pa);


#endif /* GEO_DATA_H */

Loading
Loading