mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-23 00:22:38 +00:00
Use CallerFInfoFunctionCallN infrastructure
Closes #4347 git-svn-id: http://svn.osgeo.org/postgis/trunk@17332 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
0a4a7fa9bd
commit
bf1c0826f9
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue