Skip to content

Commit

Permalink
Refactor the postgis 2.1.5 based on gpdb master upgrading [for PR]
Browse files Browse the repository at this point in the history
This commit is same as last commit with code change.
1. enable raster
  Now we can support raster after we backport several necessary
  features from upstream to greenplum-db master repo.

2. refactor patch file
  As more and more new features are backported, we refactor the
  patch file as well as makefiles.

3. add binary I/O for raster
  We add raster_recv/send() funcs to adapt gpdb. This
  part may be removed after further investigation.

Authors: Haozhou Wang and Kuien Liu
  • Loading branch information
HaozhouWang committed May 19, 2016
1 parent 79fbbc0 commit cbb00da
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 65 deletions.
10 changes: 4 additions & 6 deletions postgis/build/postgis-2.1.5/postgis/postgis.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ SET client_min_messages TO warning;
BEGIN;

-- Check that no other postgis is installed
CREATE OR REPLACE FUNCTION _anonymous_function() RETURNS VOID AS $$
DO $$
DECLARE
rec RECORD;
BEGIN
Expand All @@ -41,8 +41,6 @@ BEGIN
END LOOP;
END
$$ LANGUAGE 'plpgsql';
SELECT _anonymous_function();
DROP FUNCTION IF EXISTS _anonymous_function();


-- Let the user know about a deprecated signature and its new name, if any
Expand Down Expand Up @@ -2910,16 +2908,16 @@ CREATE OR REPLACE FUNCTION _ST_Buffer(geometry,float8,cstring)
CREATE OR REPLACE FUNCTION ST_Buffer(geometry,float8,integer)
RETURNS geometry
AS $$ SELECT _ST_Buffer($1, $2,
textout('quad_segs='||CAST($3 AS text)))
CAST('quad_segs='||CAST($3 AS text) as cstring))
$$
LANGUAGE 'sql' IMMUTABLE STRICT;

-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_Buffer(geometry,float8,text)
RETURNS geometry
AS $$ SELECT _ST_Buffer($1, $2,
textout( regexp_replace($3, '^[0123456789]+$',
'quad_segs='||$3))
CAST( regexp_replace($3, '^[0123456789]+$',
'quad_segs='||$3) AS cstring)
)
$$
LANGUAGE 'sql' IMMUTABLE STRICT;
Expand Down
6 changes: 2 additions & 4 deletions postgis/build/postgis-2.1.5/postgis/postgis_drop_before.sql
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ DROP FUNCTION IF EXISTS UpdateGeometrySRID(varchar,varchar,varchar,varchar,integ
-- We can't just drop it since its bound to opclass
-- See ticket 2279 for why we need to do this
-- We can get rid of this DO code when 3.0 comes along
CREATE OR REPLACE FUNCTION _anonymous_function() RETURNS VOID AS $$
DO language 'plpgsql' $$
BEGIN
-- fix geometry ops --
IF EXISTS(SELECT oprname from pg_operator where oprname = '&&' AND oprrest::text = 'geometry_gist_sel_2d') THEN
Expand All @@ -58,6 +58,4 @@ BEGIN
ALTER FUNCTION geography_gist_join_selectivity(internal, oid, internal, smallint) RENAME TO gserialized_gist_joinsel_nd;
END IF;
END;
$$ LANGUAGE 'plpgsql';
SELECT _anonymous_function();
DROP FUNCTION IF EXISTS _anonymous_function();
$$ ;
110 changes: 96 additions & 14 deletions postgis/build/postgis-2.1.5/raster/rt_pg/rt_pg.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,9 @@ Datum RASTER_minPossibleValue(PG_FUNCTION_ARGS);
Datum RASTER_in(PG_FUNCTION_ARGS);
Datum RASTER_out(PG_FUNCTION_ARGS);

Datum RASTER_recv(PG_FUNCTION_ARGS);
Datum RASTER_send(PG_FUNCTION_ARGS);

Datum RASTER_to_bytea(PG_FUNCTION_ARGS);
Datum RASTER_to_binary(PG_FUNCTION_ARGS);

Expand Down Expand Up @@ -847,7 +850,7 @@ rtpg_getSR(int srid)
HeapTuple tuple;
char *tmp = NULL;
char *srs = NULL;
char query[256];
char query[256];

/*
SELECT
Expand All @@ -865,20 +868,20 @@ WHERE srid = X
LIMIT 1
*/

//Greenplum
if (getSRSbySRIDbyRule(srid, true, query) != NULL) {
len = strlen(query) + 1;
srs = SPI_palloc(len);
/* Greenplum tends to use in-memory hash instead of SPI query */
if (getSRSbySRIDbyRule(srid, true, query) != NULL) {
len = strlen(query) + 1;
srs = SPI_palloc(len);

if (NULL == srs) {
elog(ERROR, "rtpg_getSR: Could not allocate memory for spatial reference text\n");
return NULL;
}
if (NULL == srs) {
elog(ERROR, "rtpg_getSR: Could not allocate memory for spatial reference text\n");
return NULL;
}

memcpy(srs, query, len);
return srs;
}

memcpy(srs, query, len);
return srs;
}

len = sizeof(char) * (strlen("SELECT CASE WHEN (upper(auth_name) = 'EPSG' OR upper(auth_name) = 'EPSGA') AND length(COALESCE(auth_srid::text, '')) > 0 THEN upper(auth_name) || ':' || auth_srid WHEN length(COALESCE(auth_name, '') || COALESCE(auth_srid::text, '')) > 0 THEN COALESCE(auth_name, '') || COALESCE(auth_srid::text, '') ELSE '' END, proj4text, srtext FROM spatial_ref_sys WHERE srid = LIMIT 1") + MAX_INT_CHARLEN + 1);
sql = (char *) palloc(len);
if (NULL == sql) {
Expand Down Expand Up @@ -1112,6 +1115,81 @@ Datum RASTER_out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(hexwkb);
}

/**
* Given a wkb string, convert it to a RASTER structure
*/
PG_FUNCTION_INFO_V1(RASTER_recv);
Datum RASTER_recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
rt_raster raster;
void *result = NULL;

POSTGIS_RT_DEBUG(3, "Starting");

raster = rt_raster_from_wkb((uint8_t*)buf->data, buf->len);
if (raster == NULL)
PG_RETURN_NULL();

/* Set cursor to the end of buffer (so the backend is happy) */
buf->cursor = buf->len;

result = rt_raster_serialize(raster);
rt_raster_destroy(raster);
if (result == NULL)
PG_RETURN_NULL();

SET_VARSIZE(result, ((rt_pgraster*)result)->size);
PG_RETURN_POINTER(result);
}

/**
* Given a RASTER structure, convert it to a wkb object
*/
PG_FUNCTION_INFO_V1(RASTER_send);
Datum RASTER_send(PG_FUNCTION_ARGS)
{
rt_pgraster *pgraster = NULL;
rt_raster raster = NULL;
uint8_t *wkb = NULL;
uint32_t wkb_size = 0;
bytea *result = NULL;
int result_size = 0;

if (PG_ARGISNULL(0)) PG_RETURN_NULL();
pgraster = (rt_pgraster *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));

/* Get raster object */
raster = rt_raster_deserialize(pgraster, FALSE);
if (!raster) {
PG_FREE_IF_COPY(pgraster, 0);
elog(ERROR, "RASTER_to_bytea: Could not deserialize raster");
PG_RETURN_NULL();
}

/* Parse raster to wkb object */
wkb = rt_raster_to_wkb(raster, FALSE, &wkb_size);
if (!wkb) {
rt_raster_destroy(raster);
PG_FREE_IF_COPY(pgraster, 0);
elog(ERROR, "RASTER_to_bytea: Could not allocate and generate WKB data");
PG_RETURN_NULL();
}

/* Create varlena object */
result_size = wkb_size + VARHDRSZ;
result = (bytea *)palloc(result_size);
SET_VARSIZE(result, result_size);
memcpy(VARDATA(result), wkb, VARSIZE(result) - VARHDRSZ);

/* Free raster objects used */
rt_raster_destroy(raster);
pfree(wkb);
PG_FREE_IF_COPY(pgraster, 0);

PG_RETURN_POINTER(result);
}

/**
* Return bytea object with raster in Well-Known-Binary form.
*/
Expand Down Expand Up @@ -2766,7 +2844,10 @@ static rtpg_dumpvalues_arg rtpg_dumpvalues_arg_init() {
static void rtpg_dumpvalues_arg_destroy(rtpg_dumpvalues_arg arg) {
int i = 0;

/* Here we found a bug of PostGIS Raster */
/*
* Here we found a critical bug of PostGIS Raster which leads
* to upstream early release of 2.1.7 to fix it.
*/
if (arg->numbands) {
if (arg->nbands != NULL)
pfree(arg->nbands);
Expand Down Expand Up @@ -3552,6 +3633,7 @@ Datum RASTER_setPixelValuesArray(PG_FUNCTION_ARGS)
pfree(nulls);
}
/* hasnosetvalue and nosetvalue */
/* Here we found a trivial bug of PostGIS Raster */
else if (!PG_ARGISNULL(6) && PG_GETARG_BOOL(6)) {
hasnosetval = TRUE;
if (PG_ARGISNULL(7))
Expand Down
56 changes: 33 additions & 23 deletions postgis/build/postgis-2.1.5/raster/rt_pg/rtpostgis.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,23 @@ CREATE OR REPLACE FUNCTION raster_out(raster)
AS 'MODULE_PATHNAME','RASTER_out'
LANGUAGE 'c' IMMUTABLE STRICT;

CREATE OR REPLACE FUNCTION raster_recv(internal)
RETURNS raster
AS 'MODULE_PATHNAME','RASTER_recv'
LANGUAGE 'c' IMMUTABLE STRICT;

CREATE OR REPLACE FUNCTION raster_send(raster)
RETURNS bytea
AS 'MODULE_PATHNAME','RASTER_send'
LANGUAGE 'c' IMMUTABLE STRICT;

CREATE TYPE raster (
alignment = double,
internallength = variable,
input = raster_in,
output = raster_out,
send = raster_send,
receive = raster_recv,
storage = extended
);

Expand Down Expand Up @@ -248,7 +260,7 @@ CREATE OR REPLACE FUNCTION st_summary(rast raster)
ELSE
msg := msg || 'bands ';
END IF;
msg := msg || 'and extent of ' || text(box2d_out(extent));
msg := msg || 'and extent of ' || extent::text;

IF
metadata.skewx::numeric(16, 10) <> 0::numeric(16, 10) OR
Expand Down Expand Up @@ -6301,34 +6313,32 @@ CREATE OR REPLACE FUNCTION st_intersection(geomin geometry, rast raster, band in
RETURNS SETOF geomval AS $$
DECLARE
intersects boolean := FALSE;
gv_r geomval;
BEGIN
intersects := ST_Intersects(geomin, rast, band);
IF intersects THEN
-- Return the intersections of the geometry with the vectorized parts of
-- the raster and the values associated with those parts, if really their
-- intersection is not empty.
FOR gv_r IN
SELECT intgeom, val
RETURN QUERY
SELECT
intgeom,
val
FROM (
SELECT ST_Intersection((gv).geom, geomin) AS intgeom, (gv).val
FROM ST_DumpAsPolygons(rast, band) gv
WHERE ST_Intersects((gv).geom, geomin)
SELECT
ST_Intersection((gv).geom, geomin) AS intgeom,
(gv).val
FROM ST_DumpAsPolygons(rast, band) gv
WHERE ST_Intersects((gv).geom, geomin)
) foo
WHERE NOT ST_IsEmpty(intgeom)
LOOP
RETURN NEXT gv_r;
END LOOP;

WHERE NOT ST_IsEmpty(intgeom);
ELSE
-- If the geometry does not intersect with the raster, return an empty
-- geometry and a null value
FOR gv_r IN
SELECT emptygeom, NULL::float8 from
ST_GeomCollFromText('GEOMETRYCOLLECTION EMPTY', ST_SRID($1))
LOOP
RETURN NEXT gv_r;
END LOOP;
RETURN QUERY
SELECT
emptygeom,
NULL::float8
FROM ST_GeomCollFromText('GEOMETRYCOLLECTION EMPTY', ST_SRID($1)) emptygeom;
END IF;
END;
$$
Expand Down Expand Up @@ -7448,7 +7458,7 @@ CREATE OR REPLACE FUNCTION _raster_constraint_info_nodata_values(rastschema name
-- Greenplum will replace operator '=' as 'OPERATOR(pg_catalog.=)', hence original method will fail.
--
SELECT
trim(both ' ''' from split_part(replace(replace(split_part(s.consrc, '=', 2), ')', ''), '(', ''), '::', 1))::text[]::double precision[]
trim(both ' ''' from split_part(replace(replace(split_part(s.consrc, '=', 2), ')', ''), '(', ''), '::', 1))::double precision[]
FROM pg_class c, pg_namespace n, pg_attribute a, pg_constraint s
WHERE n.nspname = $1
AND c.relname = $2
Expand Down Expand Up @@ -7531,7 +7541,7 @@ CREATE OR REPLACE FUNCTION _raster_constraint_info_out_db(rastschema name, rastt
-- Greenplum will replace operator '=' as 'OPERATOR(pg_catalog.=)', hence original method will fail.
--
SELECT
trim(both ' ''' from split_part(replace(replace(split_part(s.consrc, '=', 2), ')', ''), '(', ''), '::', 1))::text[]::boolean[]
trim(both ' ''' from split_part(replace(replace(split_part(s.consrc, '=', 2), ')', ''), '(', ''), '::', 1))::boolean[]
FROM pg_class c, pg_namespace n, pg_attribute a, pg_constraint s
WHERE n.nspname = $1
AND c.relname = $2
Expand Down Expand Up @@ -8147,13 +8157,13 @@ CREATE OR REPLACE FUNCTION _overview_constraint(ov raster, factor integer, refsc
LANGUAGE 'sql' STABLE
COST 100;

-- We re-write this function, otherwise Greenplum will complain:
-- We re-write this function, otherwise Greenplum will complain:
-- function cannot execute on segment because it accesses relation "public.raster_columns"
CREATE OR REPLACE FUNCTION _overview_constraint(ov raster, factor integer, refschema name, reftable name, refcolumn name)
RETURNS boolean AS
$$
$$
SELECT COALESCE((
SELECT TRUE
SELECT TRUE
FROM
pg_class c,
pg_attribute a,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ DELETE FROM test_raster_columns;

-- NOTICE:
-- Greenplum doesn't support EXCLUDE (exclusion constraint) now,
-- so we can't claim EXLUCDE(UNIQUE) on UDTs, which is invoked in
-- so we can't claim EXLUCDE(UNIQUE) on UDTs, which is invoked in
-- the constraint of 'regular_blocking'.


Expand All @@ -115,7 +115,7 @@ SELECT AddRasterConstraints(current_schema(), 'test_raster_columns', 'rast'::nam

--The textual result of ST_Union() relys on the sort of inputs, so we try to verifty it in semantic domain
SELECT r_table_name, r_raster_column, srid, scale_x, scale_y, blocksize_x, blocksize_y, same_alignment, regular_blocking, num_bands, pixel_types, nodata_values,
CASE WHEN ST_Equals(extent,'POLYGON((3 0,0 0,0 3,0 6,3 6,6 6,6 3,6 0,3 0))'::geometry)
CASE WHEN ST_Equals(extent,'POLYGON((3 0,0 0,0 3,0 6,3 6,6 6,6 3,6 0,3 0))'::geometry)
THEN 'POLYGON((3 0,0 0,0 3,0 6,3 6,6 6,6 3,6 0,3 0))'
ELSE ST_AsEWKT(extent)
END
Expand All @@ -131,7 +131,7 @@ SELECT DropRasterConstraints(current_schema(), 'test_raster_columns', 'rast'::na

--The textual result of ST_Union() relays on the sort of inputs, so we try to verify it in semantic domain
SELECT r_table_name, r_raster_column, srid, scale_x, scale_y, blocksize_x, blocksize_y, same_alignment, regular_blocking, num_bands, pixel_types, nodata_values,
CASE WHEN ST_Equals(extent,'POLYGON((3 0,0 0,0 3,0 6,3 6,6 6,6 3,6 0,3 0))'::geometry)
CASE WHEN ST_Equals(extent,'POLYGON((3 0,0 0,0 3,0 6,3 6,6 6,6 3,6 0,3 0))'::geometry)
THEN 'POLYGON((3 0,0 0,0 3,0 6,3 6,6 6,6 3,6 0,3 0))'
ELSE ST_AsEWKT(extent)
END
Expand Down
Loading

0 comments on commit cbb00da

Please sign in to comment.