]> granicus.if.org Git - postgis/commitdiff
Use CallerFInfoFunctionCallN infrastructure
authorPaul Ramsey <pramsey@cleverelephant.ca>
Mon, 11 Mar 2019 17:58:07 +0000 (17:58 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Mon, 11 Mar 2019 17:58:07 +0000 (17:58 +0000)
Closes #4347

git-svn-id: http://svn.osgeo.org/postgis/trunk@17332 b70326c6-7e19-0410-871a-916f4a2858ee

libpgcommon/lwgeom_pg.c
libpgcommon/lwgeom_pg.h
postgis/geography_measurement.c
postgis/lwgeom_geos.c

index 1ee41f0cb442518aae7c1fb4b59beb32acdf97b6..3f69b3b48bdfc6ca1a2f69f9a5bb1d63ded8287c 100644 (file)
@@ -321,3 +321,101 @@ postgis_guc_find_option(const char *name)
        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
index ef89bd9a56153d84e60836f863a594f585f789c6..e12a8a28c71848e44c9e75db9dd8b1e99c74ca05 100644 (file)
@@ -189,4 +189,12 @@ void lwpgerror(const char *fmt, ...);
 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 */
index 818b3af2ba5b6eae3407b02ccb71e8081f1701bd..a9d8e1b497f2addb7ca5b3b08ad769acf5ab2032 100644 (file)
@@ -214,7 +214,9 @@ Datum geography_distance(PG_FUNCTION_ARGS)
        /* 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));
@@ -266,14 +268,29 @@ Datum geography_distance(PG_FUNCTION_ARGS)
        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)
 {
-       double distance;
+       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;
        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 @@ geography_dwithin_impl(FunctionCallInfo fcinfo, GSERIALIZED *g1, GSERIALIZED *g2
 
        /* 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 @@ geography_dwithin_impl(FunctionCallInfo fcinfo, GSERIALIZED *g1, GSERIALIZED *g2
                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 @@ Datum geography_dwithin(PG_FUNCTION_ARGS)
 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)));
 }
 
 /*
index 8b7c0876a06c5c084e304fe81095074ef44b25b0..692afed6a2423de34f4b8e4a04d8d2be853e555c 100644 (file)
@@ -1598,20 +1598,23 @@ Datum overlaps(PG_FUNCTION_ARGS)
        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 @@ containsImpl(FunctionCallInfo fcinfo, GSERIALIZED *geom1, GSERIALIZED *geom2)
            gserialized_get_gbox_p(geom2, &box2))
        {
                if (!gbox_contains_2d(&box1, &box2))
-                       return false;
+                       PG_RETURN_BOOL(false);
        }
 
        /*
@@ -1678,7 +1681,7 @@ containsImpl(FunctionCallInfo fcinfo, GSERIALIZED *geom1, GSERIALIZED *geom2)
                {
                        /* Never get here */
                        elog(ERROR,"Type isn't point or multipoint!");
-                       return false;
+                       PG_RETURN_BOOL(false);
                }
 
                return retval > 0;
@@ -1720,32 +1723,21 @@ containsImpl(FunctionCallInfo fcinfo, GSERIALIZED *geom1, GSERIALIZED *geom2)
 
        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)
 {