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
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 */
/* 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));
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 */
/* 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) )
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);
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)));
}
/*
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.");
gserialized_get_gbox_p(geom2, &box2))
{
if (!gbox_contains_2d(&box1, &box2))
- return false;
+ PG_RETURN_BOOL(false);
}
/*
{
/* Never get here */
elog(ERROR,"Type isn't point or multipoint!");
- return false;
+ PG_RETURN_BOOL(false);
}
return retval > 0;
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)
{