[postgis-tickets] r17332 - Use CallerFInfoFunctionCallN infrastructure

Paul Ramsey pramsey at cleverelephant.ca
Mon Mar 11 10:58:07 PDT 2019


Author: pramsey
Date: 2019-03-11 10:58:07 -0700 (Mon, 11 Mar 2019)
New Revision: 17332

Modified:
   trunk/libpgcommon/lwgeom_pg.c
   trunk/libpgcommon/lwgeom_pg.h
   trunk/postgis/geography_measurement.c
   trunk/postgis/lwgeom_geos.c
Log:
Use CallerFInfoFunctionCallN infrastructure
Closes #4347


Modified: trunk/libpgcommon/lwgeom_pg.c
===================================================================
--- trunk/libpgcommon/lwgeom_pg.c	2019-03-11 17:51:00 UTC (rev 17331)
+++ trunk/libpgcommon/lwgeom_pg.c	2019-03-11 17:58:07 UTC (rev 17332)
@@ -321,3 +321,101 @@
 	return 1;
 }
 
+
+#if POSTGIS_PGSQL_VERSION < 100
+Datum
+CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.argnull[0] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
+
+Datum
+CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.arg[1] = arg2;
+	fcinfo.argnull[0] = false;
+	fcinfo.argnull[1] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
+
+#else
+
+#if POSTGIS_PGSQL_VERSION < 120
+Datum
+CallerFInfoFunctionCall3(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3)
+{
+	FunctionCallInfoData fcinfo;
+	Datum		result;
+
+	InitFunctionCallInfoData(fcinfo, flinfo, 3, collation, NULL, NULL);
+
+	fcinfo.arg[0] = arg1;
+	fcinfo.arg[1] = arg2;
+	fcinfo.arg[2] = arg3;
+	fcinfo.argnull[0] = false;
+	fcinfo.argnull[1] = false;
+	fcinfo.argnull[2] = false;
+
+	result = (*func) (&fcinfo);
+
+	/* Check for null result, since caller is clearly not expecting one */
+	if (fcinfo.isnull)
+		elog(ERROR, "function %p returned NULL", (void *) func);
+
+	return result;
+}
+#else
+/* PgSQL 12+ still lacks 3-argument version of these functions */
+Datum
+CallerFInfoFunctionCall3(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3)
+{
+    LOCAL_FCINFO(fcinfo, 3);
+    Datum       result;
+
+    InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, NULL, NULL);
+
+    fcinfo->args[0].value = arg1;
+    fcinfo->args[0].isnull = false;
+    fcinfo->args[1].value = arg2;
+    fcinfo->args[1].isnull = false;
+    fcinfo->args[2].value = arg3;
+    fcinfo->args[2].isnull = false;
+
+    result = (*func) (fcinfo);
+
+    /* Check for null result, since caller is clearly not expecting one */
+    if (fcinfo->isnull)
+        elog(ERROR, "function %p returned NULL", (void *) func);
+
+    return result;
+}
+#endif
+
+#endif

Modified: trunk/libpgcommon/lwgeom_pg.h
===================================================================
--- trunk/libpgcommon/lwgeom_pg.h	2019-03-11 17:51:00 UTC (rev 17331)
+++ trunk/libpgcommon/lwgeom_pg.h	2019-03-11 17:58:07 UTC (rev 17332)
@@ -189,4 +189,12 @@
 void lwpgnotice(const char *fmt, ...);
 void lwpgwarning(const char *fmt, ...);
 
+#if POSTGIS_PGSQL_VERSION < 100
+Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1);
+Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2);
+#endif
+Datum CallerFInfoFunctionCall3(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3);
+
+
+
 #endif /* !defined _LWGEOM_PG_H */

Modified: trunk/postgis/geography_measurement.c
===================================================================
--- trunk/postgis/geography_measurement.c	2019-03-11 17:51:00 UTC (rev 17331)
+++ trunk/postgis/geography_measurement.c	2019-03-11 17:58:07 UTC (rev 17332)
@@ -214,9 +214,11 @@
 	/* Get our geometry objects loaded into memory. */
 	g1 = PG_GETARG_GSERIALIZED_P(0);
 	g2 = PG_GETARG_GSERIALIZED_P(1);
-	use_spheroid = PG_GETARG_BOOL(2);
 
+	if (PG_NARGS() > 2)
+		use_spheroid = PG_GETARG_BOOL(2);
 
+
 	error_if_srid_mismatch(gserialized_get_srid(g1), gserialized_get_srid(g2));
 
 	/* Initialize spheroid */
@@ -266,14 +268,29 @@
 	PG_RETURN_FLOAT8(distance);
 }
 
-
-static bool
-geography_dwithin_impl(FunctionCallInfo fcinfo, GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, bool use_spheroid)
+/*
+** geography_dwithin(GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, boolean use_spheroid)
+** returns double distance in meters
+*/
+PG_FUNCTION_INFO_V1(geography_dwithin);
+Datum geography_dwithin(PG_FUNCTION_ARGS)
 {
+	GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
+	GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
+	SPHEROID s;
+	double tolerance = 0.0;
+	bool use_spheroid = true;
 	double distance;
-	SPHEROID s;
 	int dwithin = LW_FALSE;
 
+	/* Read our tolerance value. */
+	if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
+		tolerance = PG_GETARG_FLOAT8(2);
+
+	/* Read our calculation type. */
+	if ( PG_NARGS() > 3 && ! PG_ARGISNULL(3) )
+		use_spheroid = PG_GETARG_BOOL(3);
+
 	error_if_srid_mismatch(gserialized_get_srid(g1), gserialized_get_srid(g2));
 
 	/* Initialize spheroid */
@@ -285,7 +302,7 @@
 
 	/* Return FALSE on empty arguments. */
 	if ( gserialized_is_empty(g1) || gserialized_is_empty(g2) )
-		return false;
+		PG_RETURN_BOOL(false);
 
 	/* Do the brute force calculation if the cached calculation doesn't tick over */
 	if ( LW_FAILURE == geography_dwithin_cache(fcinfo, g1, g2, &s, tolerance, &dwithin) )
@@ -301,32 +318,6 @@
 		lwgeom_free(lwgeom2);
 	}
 
-	return dwithin;
-}
-
-/*
-** geography_dwithin(GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, boolean use_spheroid)
-** returns double distance in meters
-*/
-PG_FUNCTION_INFO_V1(geography_dwithin);
-Datum geography_dwithin(PG_FUNCTION_ARGS)
-{
-	GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
-	GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
-	double tolerance = 0.0;
-	bool use_spheroid = true;
-	bool dwithin = false;
-
-	/* Read our tolerance value. */
-	if ( PG_NARGS() > 2 && ! PG_ARGISNULL(2) )
-		tolerance = PG_GETARG_FLOAT8(2);
-
-	/* Read our calculation type. */
-	if ( PG_NARGS() > 3 && ! PG_ARGISNULL(3) )
-		use_spheroid = PG_GETARG_BOOL(3);
-
-	dwithin = geography_dwithin_impl(fcinfo, g1, g2, tolerance, use_spheroid);
-
 	PG_FREE_IF_COPY(g1, 0);
 	PG_FREE_IF_COPY(g2, 1);
 	PG_RETURN_BOOL(dwithin);
@@ -335,14 +326,9 @@
 PG_FUNCTION_INFO_V1(geography_intersects);
 Datum geography_intersects(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *g1 = PG_GETARG_GSERIALIZED_P(0);
-	GSERIALIZED *g2 = PG_GETARG_GSERIALIZED_P(1);
-	double tolerance = 0.0;
-	bool use_spheroid = true;
-	bool dwithin = geography_dwithin_impl(fcinfo, g1, g2, tolerance, use_spheroid);
-	PG_FREE_IF_COPY(g1, 0);
-	PG_FREE_IF_COPY(g2, 1);
-	PG_RETURN_BOOL(dwithin);
+	PG_RETURN_BOOL(CallerFInfoFunctionCall2(
+		geography_dwithin, fcinfo->flinfo, InvalidOid,
+		PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)));
 }
 
 /*

Modified: trunk/postgis/lwgeom_geos.c
===================================================================
--- trunk/postgis/lwgeom_geos.c	2019-03-11 17:51:00 UTC (rev 17331)
+++ trunk/postgis/lwgeom_geos.c	2019-03-11 17:58:07 UTC (rev 17332)
@@ -1598,20 +1598,23 @@
 	PG_RETURN_BOOL(result);
 }
 
-static bool
-containsImpl(FunctionCallInfo fcinfo, GSERIALIZED *geom1, GSERIALIZED *geom2)
+
+PG_FUNCTION_INFO_V1(contains);
+Datum contains(PG_FUNCTION_ARGS)
 {
+	GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P(0);
+	GSERIALIZED *geom2 = PG_GETARG_GSERIALIZED_P(1);
+	int result;
 	GEOSGeometry *g1, *g2;
 	GBOX box1, box2;
-	int result;
 	PrepGeomCache *prep_cache;
 
-	errorIfGeometryCollection(geom1,geom2);
+	errorIfGeometryCollection(geom1, geom2);
 	error_if_srid_mismatch(gserialized_get_srid(geom1), gserialized_get_srid(geom2));
 
 	/* A.Contains(Empty) == FALSE */
-	if ( gserialized_is_empty(geom1) || gserialized_is_empty(geom2) )
-		return false;
+	if (gserialized_is_empty(geom1) || gserialized_is_empty(geom2))
+		PG_RETURN_BOOL(false);
 
 	POSTGIS_DEBUG(3, "contains called.");
 
@@ -1623,7 +1626,7 @@
 	    gserialized_get_gbox_p(geom2, &box2))
 	{
 		if (!gbox_contains_2d(&box1, &box2))
-			return false;
+			PG_RETURN_BOOL(false);
 	}
 
 	/*
@@ -1678,7 +1681,7 @@
 		{
 			/* Never get here */
 			elog(ERROR,"Type isn't point or multipoint!");
-			return false;
+			PG_RETURN_BOOL(false);
 		}
 
 		return retval > 0;
@@ -1720,32 +1723,21 @@
 
 	if (result == 2) HANDLE_GEOS_ERROR("GEOSContains");
 
-	return result > 0;
+	PG_FREE_IF_COPY(geom1, 0);
+	PG_FREE_IF_COPY(geom2, 1);
+	PG_RETURN_BOOL(result > 0);
 }
 
-PG_FUNCTION_INFO_V1(contains);
-Datum contains(PG_FUNCTION_ARGS)
-{
-	GSERIALIZED *geom0 = PG_GETARG_GSERIALIZED_P(0);
-	GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P(1);
-	bool result = containsImpl(fcinfo, geom0, geom1);
-	PG_FREE_IF_COPY(geom0, 0);
-	PG_FREE_IF_COPY(geom1, 1);
-	PG_RETURN_BOOL(result);
-}
 
 PG_FUNCTION_INFO_V1(within);
 Datum within(PG_FUNCTION_ARGS)
 {
-	GSERIALIZED *geom0 = PG_GETARG_GSERIALIZED_P(0);
-	GSERIALIZED *geom1 = PG_GETARG_GSERIALIZED_P(1);
-	bool result = containsImpl(fcinfo, geom1, geom0);
-	PG_FREE_IF_COPY(geom0, 0);
-	PG_FREE_IF_COPY(geom1, 1);
-	PG_RETURN_BOOL(result);
+	PG_RETURN_DATUM(CallerFInfoFunctionCall2(contains, fcinfo->flinfo, InvalidOid,
+		PG_GETARG_DATUM(1), PG_GETARG_DATUM(0)));
 }
 
 
+
 PG_FUNCTION_INFO_V1(containsproperly);
 Datum containsproperly(PG_FUNCTION_ARGS)
 {



More information about the postgis-tickets mailing list