[postgis-tickets] [SCM] PostGIS branch master updated. 3.1.0alpha1-100-g39adc44

git at osgeo.org git at osgeo.org
Fri May 1 08:00:13 PDT 2020


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, master has been updated
       via  39adc44a3f4ecdd4200e5bccf6dec429eeb39cf9 (commit)
       via  83c62dbf8fedcaf16ccecd416922345184fc7a67 (commit)
      from  07ca520a78c4c12fe94c5f0541887b4a15eeca16 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 39adc44a3f4ecdd4200e5bccf6dec429eeb39cf9
Author: Raúl Marín <git at rmr.ninja>
Date:   Fri May 1 14:47:41 2020 +0200

    Optimize geometry_to_point
    
    References #4676

diff --git a/NEWS b/NEWS
index 9da2c0a..e893b8e 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Only tickets not included in 3.1.0alpha1
   - #4490, Tweak function costs (Raúl Marín)
   - #4672, Cache getSRSbySRID and getSRIDbySRS (Raúl Marín)
   - #4676, Avoid decompressing toasted geometries to read only the header (Raúl Marín)
+           Optimize cast to Postgresql point type (Raúl Marín)
 
 * Bug fixes *
   - #4652, Fix several memory related bugs in ST_GeomFromGML (Raúl Marín)
diff --git a/postgis/geometry_inout.c b/postgis/geometry_inout.c
index c5c2561..c1622c5 100644
--- a/postgis/geometry_inout.c
+++ b/postgis/geometry_inout.c
@@ -72,33 +72,22 @@ PG_FUNCTION_INFO_V1(geometry_to_point);
 Datum geometry_to_point(PG_FUNCTION_ARGS)
 {
 	Point *point;
-	LWGEOM *lwgeom;
-	LWPOINT *lwpoint;
+	POINT4D pt;
 	GSERIALIZED *geom;
 
-	POSTGIS_DEBUG(2, "geometry_to_point called");
-
-	if ( PG_ARGISNULL(0) )
+	if (PG_ARGISNULL(0))
 		PG_RETURN_NULL();
-
 	geom = PG_GETARG_GSERIALIZED_P(0);
 
-	if ( gserialized_get_type(geom) != POINTTYPE )
+	if (gserialized_get_type(geom) != POINTTYPE)
 		elog(ERROR, "geometry_to_point only accepts Points");
 
-	lwgeom = lwgeom_from_gserialized(geom);
-
-	if ( lwgeom_is_empty(lwgeom) )
+	if (gserialized_peek_first_point(geom, &pt) == LW_FAILURE)
 		PG_RETURN_NULL();
 
-	lwpoint = lwgeom_as_lwpoint(lwgeom);
-
-	point = (Point*)palloc(sizeof(Point));
-	point->x = lwpoint_get_x(lwpoint);
-	point->y = lwpoint_get_y(lwpoint);
-
-	lwpoint_free(lwpoint);
-	PG_FREE_IF_COPY(geom,0);
+	point = (Point *)palloc(sizeof(Point));
+	point->x = pt.x;
+	point->y = pt.y;
 
 	PG_RETURN_POINT_P(point);
 }

commit 83c62dbf8fedcaf16ccecd416922345184fc7a67
Author: Raúl Marín <git at rmr.ninja>
Date:   Fri May 1 12:36:10 2020 +0200

    Avoid decompressing toasted geometries to read only the header
    
    Closes #4676
    Closes https://github.com/postgis/postgis/pull/558

diff --git a/NEWS b/NEWS
index 4edb5b1..9da2c0a 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ Only tickets not included in 3.1.0alpha1
   - #4657: Avoid De-TOASTing where possible (Paul Ramsey)
   - #4490, Tweak function costs (Raúl Marín)
   - #4672, Cache getSRSbySRID and getSRIDbySRS (Raúl Marín)
+  - #4676, Avoid decompressing toasted geometries to read only the header (Raúl Marín)
 
 * Bug fixes *
   - #4652, Fix several memory related bugs in ST_GeomFromGML (Raúl Marín)
diff --git a/libpgcommon/gserialized_gist.c b/libpgcommon/gserialized_gist.c
index c5cf7db..a1329ae 100644
--- a/libpgcommon/gserialized_gist.c
+++ b/libpgcommon/gserialized_gist.c
@@ -70,7 +70,7 @@ GIDX* gidx_new(int ndims)
 static lwflags_t
 gserialized_datum_get_flags(Datum gsdatum)
 {
-	GSERIALIZED *gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 40);
+	GSERIALIZED *gpart = (GSERIALIZED *)PG_DETOAST_DATUM_SLICE(gsdatum, 0, gserialized_max_header_size());
 	return gserialized_get_lwflags(gpart);
 }
 
@@ -182,7 +182,7 @@ gserialized_datum_get_gidx_p(Datum gsdatum, GIDX *gidx)
 	** of floats necessary to hold the 8 floats of the largest XYZM index
 	** bounding box, so 40 bytes.
 	*/
-	gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 40);
+	gpart = (GSERIALIZED *)PG_DETOAST_DATUM_SLICE(gsdatum, 0, gserialized_max_header_size());
 
 	/* Do we even have a serialized bounding box? */
 	if (gserialized_has_bbox(gpart))
@@ -212,19 +212,24 @@ gserialized_datum_get_gidx_p(Datum gsdatum, GIDX *gidx)
 	else
 	{
 		/* No, we need to calculate it from the full object. */
-		GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum);
-		LWGEOM *lwgeom = lwgeom_from_gserialized(g);
+		LWGEOM *lwgeom;
 		GBOX gbox;
+		/* If we haven't, read the whole gserialized object */
+		if (LWSIZE_GET(gpart->size) >= gserialized_max_header_size())
+		{
+			POSTGIS_FREE_IF_COPY_P(gpart, gsdatum);
+			gpart = (GSERIALIZED *)PG_DETOAST_DATUM(gsdatum);
+		}
+
+		lwgeom = lwgeom_from_gserialized(gpart);
 		if (lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE)
 		{
 			POSTGIS_DEBUG(4, "could not calculate bbox, returning failure");
 			lwgeom_free(lwgeom);
 			POSTGIS_FREE_IF_COPY_P(gpart, gsdatum);
-			POSTGIS_FREE_IF_COPY_P(g, gsdatum);
 			return LW_FAILURE;
 		}
 		lwgeom_free(lwgeom);
-		POSTGIS_FREE_IF_COPY_P(g, gsdatum);
 		gidx_from_gbox_p(gbox, gidx);
 	}
 	POSTGIS_FREE_IF_COPY_P(gpart, gsdatum);
diff --git a/libpgcommon/lwgeom_pg.h b/libpgcommon/lwgeom_pg.h
index 2009eff..64e35ae 100644
--- a/libpgcommon/lwgeom_pg.h
+++ b/libpgcommon/lwgeom_pg.h
@@ -90,6 +90,8 @@ void pg_install_lwgeom_handlers(void);
 #define PG_GETARG_GSERIALIZED_P(varno) ((GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(varno)))
 #define PG_GETARG_GSERIALIZED_P_COPY(varno) ((GSERIALIZED *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(varno)))
 #define PG_GETARG_GSERIALIZED_P_SLICE(varno, start, size) ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), start, size))
+#define PG_GETARG_GSERIALIZED_HEADER(varno) \
+	((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), 0, gserialized_max_header_size()))
 
 /* Debugging macros */
 #if POSTGIS_DEBUG_LEVEL > 0
diff --git a/postgis/gserialized_gist_2d.c b/postgis/gserialized_gist_2d.c
index 086aa22..b6ce9a5 100644
--- a/postgis/gserialized_gist_2d.c
+++ b/postgis/gserialized_gist_2d.c
@@ -464,7 +464,7 @@ gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df)
 	** (though we still need to fully retrieve it from TOAST)
 	** which makes slicing worthwhile.
 	*/
-	gpart = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum);
+	gpart = (GSERIALIZED *)PG_DETOAST_DATUM_SLICE(gsdatum, 0, gserialized_max_header_size());
 
 	POSTGIS_DEBUGF(4, "got flags %d", gpart->gflags);
 
@@ -485,6 +485,13 @@ gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df)
 		GBOX gbox;
 		gbox_init(&gbox);
 
+		/* If we haven't, read the whole gserialized object */
+		if (LWSIZE_GET(gpart->size) >= gserialized_max_header_size())
+		{
+			POSTGIS_FREE_IF_COPY_P(gpart, gsdatum);
+			gpart = (GSERIALIZED *)PG_DETOAST_DATUM(gsdatum);
+		}
+
 		result = gserialized_get_gbox_p(gpart, &gbox);
 		if ( result == LW_SUCCESS )
 		{
diff --git a/postgis/lwgeom_functions_basic.c b/postgis/lwgeom_functions_basic.c
index e955d0c..8ed3302 100644
--- a/postgis/lwgeom_functions_basic.c
+++ b/postgis/lwgeom_functions_basic.c
@@ -1963,7 +1963,7 @@ Datum ST_Normalize(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(LWGEOM_zmflag);
 Datum LWGEOM_zmflag(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *in = PG_GETARG_GSERIALIZED_P(0);
+	GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
 	int ret = 0;
 
 	if (gserialized_has_z(in))
@@ -1977,21 +1977,21 @@ Datum LWGEOM_zmflag(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(LWGEOM_hasz);
 Datum LWGEOM_hasz(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *in = PG_GETARG_GSERIALIZED_P(0);
+	GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
 	PG_RETURN_BOOL(gserialized_has_z(in));
 }
 
 PG_FUNCTION_INFO_V1(LWGEOM_hasm);
 Datum LWGEOM_hasm(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *in = PG_GETARG_GSERIALIZED_P(0);
+	GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
 	PG_RETURN_BOOL(gserialized_has_m(in));
 }
 
 PG_FUNCTION_INFO_V1(LWGEOM_hasBBOX);
 Datum LWGEOM_hasBBOX(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *in = PG_GETARG_GSERIALIZED_P(0);
+	GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
 	char res = gserialized_has_bbox(in);
 	PG_FREE_IF_COPY(in, 0);
 	PG_RETURN_BOOL(res);
@@ -2001,7 +2001,7 @@ Datum LWGEOM_hasBBOX(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(LWGEOM_ndims);
 Datum LWGEOM_ndims(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *in = PG_GETARG_GSERIALIZED_P(0);
+	GSERIALIZED *in = PG_GETARG_GSERIALIZED_HEADER(0);
 	int ret = gserialized_ndims(in);
 	PG_FREE_IF_COPY(in, 0);
 	PG_RETURN_INT16(ret);
@@ -2143,17 +2143,8 @@ Datum ST_TileEnvelope(PG_FUNCTION_ARGS)
 PG_FUNCTION_INFO_V1(ST_IsCollection);
 Datum ST_IsCollection(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *geom;
-	int type;
-	size_t size;
-
-	/* Pull only a small amount of the tuple, enough to get the type. */
-	/* header + srid/flags + bbox? + type number */
-	size = VARHDRSZ + 8 + 32 + 4;
-
-	geom = PG_GETARG_GSERIALIZED_P_SLICE(0, 0, size);
-
-	type = gserialized_get_type(geom);
+	GSERIALIZED *geom = PG_GETARG_GSERIALIZED_HEADER(0);
+	int type = gserialized_get_type(geom);
 	PG_RETURN_BOOL(lwtype_is_collection(type));
 }
 
diff --git a/postgis/lwgeom_ogc.c b/postgis/lwgeom_ogc.c
index 3898432..6b692b8 100644
--- a/postgis/lwgeom_ogc.c
+++ b/postgis/lwgeom_ogc.c
@@ -95,7 +95,7 @@ Datum LWGEOM_isclosed(PG_FUNCTION_ARGS);
 PG_FUNCTION_INFO_V1(LWGEOM_get_srid);
 Datum LWGEOM_get_srid(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *geom=PG_GETARG_GSERIALIZED_P(0);
+	GSERIALIZED *geom = PG_GETARG_GSERIALIZED_HEADER(0);
 	int32_t srid = gserialized_get_srid(geom);
 	PG_FREE_IF_COPY(geom,0);
 	PG_RETURN_INT32(srid);
@@ -121,7 +121,7 @@ Datum LWGEOM_getTYPE(PG_FUNCTION_ARGS)
 	uint8_t type;
 	static int maxtyplen = 20;
 
-	gser = PG_GETARG_GSERIALIZED_P_SLICE(0, 0, gserialized_max_header_size());
+	gser = PG_GETARG_GSERIALIZED_HEADER(0);
 	text_ob = palloc0(VARHDRSZ + maxtyplen);
 	result = VARDATA(text_ob);
 
@@ -196,7 +196,7 @@ Datum geometry_geometrytype(PG_FUNCTION_ARGS)
 	text *type_text;
 
 	/* Read just the header from the toasted tuple */
-	gser = PG_GETARG_GSERIALIZED_P_SLICE(0, 0, gserialized_max_header_size());
+	gser = PG_GETARG_GSERIALIZED_HEADER(0);
 
 	/* Build a text type to store things in */
 	type_text = cstring_to_text(stTypeName[gserialized_get_type(gser)]);

-----------------------------------------------------------------------

Summary of changes:
 NEWS                             |  2 ++
 libpgcommon/gserialized_gist.c   | 17 +++++++++++------
 libpgcommon/lwgeom_pg.h          |  2 ++
 postgis/geometry_inout.c         | 25 +++++++------------------
 postgis/gserialized_gist_2d.c    |  9 ++++++++-
 postgis/lwgeom_functions_basic.c | 23 +++++++----------------
 postgis/lwgeom_ogc.c             |  6 +++---
 7 files changed, 40 insertions(+), 44 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list