Commit 2f3e2783 authored by Paul Ramsey's avatar Paul Ramsey

Use "support function" API in PgSQL 12+ to provide index support for...

Use "support function" API in PgSQL 12+ to provide index support for ST_Intersects and company, in place of old SQL inlining method.
Closes #4341


git-svn-id: http://svn.osgeo.org/postgis/trunk@17298 b70326c6-7e19-0410-871a-916f4a2858ee
parent 8fa7e3f6
Pipeline #50612023 failed with stage
in 4 minutes and 48 seconds
......@@ -31,6 +31,8 @@ PostGIS 3.0.0
- #4311, Introduce `--with-wagyu` as an option for MVT polygons (Raúl Marín)
* Enhancements and fixes *
- #4341, Using "support function" API in PgSQL 12+ to replace SQL inlining
as the mechanism for providing index support under ST_Intersects, et al
- #4322, Support for Proj 6+ API, bringing more accurate datum transforms
and support for WKT projections
- #4153, ST_Segmentize now splits segments proportionally (Darafei
......
......@@ -3072,18 +3072,6 @@ FROM
<parameter>distance_of_srid</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>boolean <function>ST_DWithin</function></funcdef>
<paramdef><type>geography </type>
<parameter>gg1</parameter></paramdef>
<paramdef><type>geography </type>
<parameter>gg2</parameter></paramdef>
<paramdef><type>double precision </type>
<parameter>distance_meters</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>boolean <function>ST_DWithin</function></funcdef>
<paramdef><type>geography </type>
......@@ -3095,7 +3083,7 @@ FROM
<paramdef><type>double precision </type>
<parameter>distance_meters</parameter></paramdef>
<paramdef><type>boolean </type>
<paramdef choice="opt"><type>boolean </type>
<parameter>use_spheroid</parameter></paramdef>
</funcprototype>
</funcsynopsis>
......
......@@ -106,6 +106,7 @@ PG_OBJS= \
gserialized_typmod.o \
gserialized_gist_2d.o \
gserialized_gist_nd.o \
gserialized_supportfn.o \
$(SPGIST_OBJ) \
brin_2d.o \
brin_nd.o \
......
......@@ -520,14 +520,6 @@ CREATE OR REPLACE FUNCTION _ST_Distance(geography, geography, float8, boolean)
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Stop calculation and return immediately once distance is less than tolerance
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION _ST_DWithin(geography, geography, float8, boolean)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_dwithin'
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_Distance(geography, geography, boolean)
RETURNS float8
......@@ -555,24 +547,6 @@ CREATE OR REPLACE FUNCTION _ST_Expand(geography, float8)
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 50;
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_DWithin(geography, geography, float8, boolean)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) @extschema@._ST_Expand($2,$3) AND $2 OPERATOR(@extschema@.&&) @extschema@._ST_Expand($1,$3) AND @extschema@._ST_DWithin($1, $2, $3, $4)'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Currently defaulting to spheroid calculations
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_DWithin(geography, geography, float8)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) @extschema@._ST_Expand($2,$3) AND $2 OPERATOR(@extschema@.&&) @extschema@._ST_Expand($1,$3) AND @extschema@._ST_DWithin($1, $2, $3, true)'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
CREATE OR REPLACE FUNCTION ST_DWithin(text, text, float8)
RETURNS boolean AS
$$ SELECT @extschema@.ST_DWithin($1::@extschema@.geometry, $2::@extschema@.geometry, $3); $$
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- ---------- ---------- ---------- ---------- ---------- ---------- ----------
......@@ -682,40 +656,6 @@ CREATE OR REPLACE FUNCTION _ST_PointOutside(geography)
AS 'MODULE_PATHNAME','geography_point_outside'
LANGUAGE 'c' IMMUTABLE STRICT;
-- Only implemented for polygon-over-point
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION _ST_Covers(geography, geography)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_covers'
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Only implemented for polygon-over-point
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_Covers(geography, geography)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) $2 AND @extschema@._ST_Covers($1, $2)'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
CREATE OR REPLACE FUNCTION ST_Covers(text, text)
RETURNS boolean AS
$$ SELECT @extschema@.ST_Covers($1::@extschema@.geometry, $2::@extschema@.geometry); $$
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Only implemented for polygon-over-point
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_CoveredBy(geography, geography)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) $2 AND @extschema@._ST_Covers($2, $1)'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
CREATE OR REPLACE FUNCTION ST_CoveredBy(text, text)
RETURNS boolean AS
$$ SELECT @extschema@.ST_CoveredBy($1::@extschema@.geometry, $2::@extschema@.geometry); $$
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 2.1.0
CREATE OR REPLACE FUNCTION ST_Segmentize(geog geography, max_segment_length float8)
RETURNS geography
......@@ -723,18 +663,6 @@ CREATE OR REPLACE FUNCTION ST_Segmentize(geog geography, max_segment_length floa
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_Intersects(geography, geography)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) $2 AND @extschema@._ST_Distance($1, $2, 0.0, false) < 0.00001'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
CREATE OR REPLACE FUNCTION ST_Intersects(text, text)
RETURNS boolean AS
$$ SELECT @extschema@.ST_Intersects($1::@extschema@.geometry, $2::@extschema@.geometry); $$
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION _ST_BestSRID(geography, geography)
RETURNS integer
......@@ -863,3 +791,118 @@ CREATE OR REPLACE FUNCTION ST_Centroid(text)
LANGUAGE 'sql' IMMUTABLE STRICT _PARALLEL;
-----------------------------------------------------------------------------
-- Only implemented for polygon-over-point
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION _ST_Covers(geog1 geography, geog2 geography)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_covers'
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Stop calculation and return immediately once distance is less than tolerance
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION _ST_DWithin(geog1 geography, geog2 geography, tolerance float8, use_spheroid boolean DEFAULT true)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_dwithin'
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Only implemented for polygon-over-point
-- Availability: 3.0.0
CREATE OR REPLACE FUNCTION _ST_CoveredBy(geog1 geography, geog2 geography)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_coveredby'
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
#if POSTGIS_PGSQL_VERSION >= 120
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_Covers(geog1 geography, geog2 geography)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_covers'
SUPPORT postgis_index_supportfn
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_DWithin(geog1 geography, geog2 geography, tolerance float8, use_spheroid boolean DEFAULT true)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_dwithin'
SUPPORT postgis_index_supportfn
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Availability: 3.0.0
CREATE OR REPLACE FUNCTION ST_CoveredBy(geog1 geography, geog2 geography)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_coveredby'
SUPPORT postgis_index_supportfn
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_Intersects(geog1 geography, geog2 geography)
RETURNS boolean
AS 'MODULE_PATHNAME','geography_intersects'
SUPPORT postgis_index_supportfn
LANGUAGE 'c' IMMUTABLE STRICT _PARALLEL
COST 100;
#else
-- Only implemented for polygon-over-point
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_Covers(geog1 geography, geog2 geography)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) $2 AND @extschema@._ST_Covers($1, $2)'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Only implemented for polygon-over-point
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_CoveredBy(geog1 geography, geog2 geography)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) $2 AND @extschema@._ST_Covers($2, $1)'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0
CREATE OR REPLACE FUNCTION ST_DWithin(geog1 geography, geog2 geography, tolerance float8, use_spheroid boolean DEFAULT true)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) @extschema@._ST_Expand($2,$3) AND $2 OPERATOR(@extschema@.&&) @extschema@._ST_Expand($1,$3) AND @extschema@._ST_DWithin($1, $2, $3, $4)'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
CREATE OR REPLACE FUNCTION ST_Intersects(geography, geography)
RETURNS boolean
AS 'SELECT $1 OPERATOR(@extschema@.&&) $2 AND @extschema@._ST_Distance($1, $2, 0.0, false) < 0.00001'
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
#endif
-- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
CREATE OR REPLACE FUNCTION ST_Covers(text, text)
RETURNS boolean AS
$$ SELECT @extschema@.ST_Covers($1::@extschema@.geometry, $2::@extschema@.geometry); $$
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
CREATE OR REPLACE FUNCTION ST_CoveredBy(text, text)
RETURNS boolean AS
$$ SELECT @extschema@.ST_CoveredBy($1::@extschema@.geometry, $2::@extschema@.geometry); $$
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
CREATE OR REPLACE FUNCTION ST_DWithin(text, text, float8)
RETURNS boolean AS
$$ SELECT @extschema@.ST_DWithin($1::@extschema@.geometry, $2::@extschema@.geometry, $3); $$
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-- Availability: 1.5.0 - this is just a hack to prevent unknown from causing ambiguous name because of geography
CREATE OR REPLACE FUNCTION ST_Intersects(text, text)
RETURNS boolean AS
$$ SELECT @extschema@.ST_Intersects($1::@extschema@.geometry, $2::@extschema@.geometry); $$
LANGUAGE 'sql' IMMUTABLE _PARALLEL;
-----------------------------------------------------------------------------
......@@ -58,6 +58,7 @@ Datum geography_length(PG_FUNCTION_ARGS);
Datum geography_expand(PG_FUNCTION_ARGS);
Datum geography_point_outside(PG_FUNCTION_ARGS);
Datum geography_covers(PG_FUNCTION_ARGS);
Datum geography_coveredby(PG_FUNCTION_ARGS);
Datum geography_bestsrid(PG_FUNCTION_ARGS);
Datum geography_perimeter(PG_FUNCTION_ARGS);
Datum geography_project(PG_FUNCTION_ARGS);
......@@ -267,33 +268,13 @@ Datum geography_distance(PG_FUNCTION_ARGS)
}
/*
** 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)
static bool
geography_dwithin_impl(FunctionCallInfo fcinfo, GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, bool use_spheroid)
{
GSERIALIZED *g1 = NULL;
GSERIALIZED *g2 = NULL;
double tolerance = 0.0;
double distance;
bool use_spheroid = true;
SPHEROID s;
int dwithin = LW_FALSE;
/* Get our geometry objects loaded into memory. */
g1 = PG_GETARG_GSERIALIZED_P(0);
g2 = PG_GETARG_GSERIALIZED_P(1);
/* 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 */
......@@ -305,11 +286,7 @@ Datum geography_dwithin(PG_FUNCTION_ARGS)
/* Return FALSE on empty arguments. */
if ( gserialized_is_empty(g1) || gserialized_is_empty(g2) )
{
PG_FREE_IF_COPY(g1, 0);
PG_FREE_IF_COPY(g2, 1);
PG_RETURN_BOOL(false);
}
return 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) )
......@@ -325,13 +302,49 @@ Datum geography_dwithin(PG_FUNCTION_ARGS)
lwgeom_free(lwgeom2);
}
/* Clean up */
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);
}
/*
** geography_distance_tree(GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, boolean use_spheroid)
......@@ -769,6 +782,48 @@ Datum geography_covers(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(result);
}
PG_FUNCTION_INFO_V1(geography_coveredby);
Datum geography_coveredby(PG_FUNCTION_ARGS)
{
LWGEOM *lwgeom1 = NULL;
LWGEOM *lwgeom2 = NULL;
GSERIALIZED *g1 = NULL;
GSERIALIZED *g2 = NULL;
int result = LW_FALSE;
/* Get our geometry objects loaded into memory. */
/* Pick them up in reverse order to covers */
g1 = PG_GETARG_GSERIALIZED_P(1);
g2 = PG_GETARG_GSERIALIZED_P(0);
/* Construct our working geometries */
lwgeom1 = lwgeom_from_gserialized(g1);
lwgeom2 = lwgeom_from_gserialized(g2);
error_if_srid_mismatch(lwgeom1->srid, lwgeom2->srid);
/* EMPTY never intersects with another geometry */
if ( lwgeom_is_empty(lwgeom1) || lwgeom_is_empty(lwgeom2) )
{
lwgeom_free(lwgeom1);
lwgeom_free(lwgeom2);
PG_FREE_IF_COPY(g1, 1);
PG_FREE_IF_COPY(g2, 0);
PG_RETURN_BOOL(false);
}
/* Calculate answer */
result = lwgeom_covers_lwgeom_sphere(lwgeom1, lwgeom2);
/* Clean up */
lwgeom_free(lwgeom1);
lwgeom_free(lwgeom2);
PG_FREE_IF_COPY(g1, 1);
PG_FREE_IF_COPY(g2, 0);
PG_RETURN_BOOL(result);
}
/*
** geography_bestsrid(GSERIALIZED *g, GSERIALIZED *g) returns int
** Utility function. Returns negative SRID numbers that match to the
......
......@@ -383,8 +383,13 @@ static bool box2df_within(const BOX2DF *a, const BOX2DF *b)
if ( box2df_is_empty(a) && ! box2df_is_empty(b) )
return true;
POSTGIS_DEBUG(5, "entered function");
return box2df_contains(b,a);
if ( (a->xmin < b->xmin) || (a->xmax > b->xmax) ||
(a->ymin < b->ymin) || (a->ymax > b->ymax) )
{
return false;
}
return true;
}
bool box2df_equals(const BOX2DF *a, const BOX2DF *b)
......@@ -987,7 +992,7 @@ static inline bool gserialized_gist_consistent_leaf_2d(BOX2DF *key, BOX2DF *quer
break;
case RTContainedByStrategyNumber:
case RTOldContainedByStrategyNumber:
retval = (bool) box2df_contains(query, key);
retval = (bool) box2df_within(key, query);
break;
/* To one side */
......
......@@ -73,6 +73,7 @@ Datum touches(PG_FUNCTION_ARGS);
Datum ST_Intersects(PG_FUNCTION_ARGS);
Datum crosses(PG_FUNCTION_ARGS);
Datum contains(PG_FUNCTION_ARGS);
Datum within(PG_FUNCTION_ARGS);
Datum containsproperly(PG_FUNCTION_ARGS);
Datum covers(PG_FUNCTION_ARGS);
Datum overlaps(PG_FUNCTION_ARGS);
......@@ -1610,26 +1611,20 @@ Datum overlaps(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(result);
}
PG_FUNCTION_INFO_V1(contains);
Datum contains(PG_FUNCTION_ARGS)
static bool
containsImpl(FunctionCallInfo fcinfo, GSERIALIZED *geom1, GSERIALIZED *geom2)
{
GSERIALIZED *geom1;
GSERIALIZED *geom2;
GEOSGeometry *g1, *g2;
GBOX box1, box2;
int result;
PrepGeomCache *prep_cache;
geom1 = PG_GETARG_GSERIALIZED_P(0);
geom2 = PG_GETARG_GSERIALIZED_P(1);
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) )
PG_RETURN_BOOL(false);
return false;
POSTGIS_DEBUG(3, "contains called.");
......@@ -1637,10 +1632,11 @@ Datum contains(PG_FUNCTION_ARGS)
** short-circuit 1: if geom2 bounding box is not completely inside
** geom1 bounding box we can return FALSE.
*/
if ( gserialized_get_gbox_p(geom1, &box1) &&
gserialized_get_gbox_p(geom2, &box2) )
if (gserialized_get_gbox_p(geom1, &box1) &&
gserialized_get_gbox_p(geom2, &box2))
{
if (!gbox_contains_2d(&box1, &box2)) PG_RETURN_BOOL(false);
if (!gbox_contains_2d(&box1, &box2))
return false;
}
/*
......@@ -1695,12 +1691,10 @@ Datum contains(PG_FUNCTION_ARGS)
{
/* Never get here */
elog(ERROR,"Type isn't point or multipoint!");
PG_RETURN_NULL();
return false;
}
PG_FREE_IF_COPY(geom1, 0);
PG_FREE_IF_COPY(geom2, 1);
PG_RETURN_BOOL(retval);
return retval > 0;
}
else
{
......@@ -1739,13 +1733,32 @@ Datum contains(PG_FUNCTION_ARGS)
if (result == 2) HANDLE_GEOS_ERROR("GEOSContains");
PG_FREE_IF_COPY(geom1, 0);
PG_FREE_IF_COPY(geom2, 1);
return 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_FUNCTION_INFO_V1(containsproperly);
Datum containsproperly(PG_FUNCTION_ARGS)
{
......
This diff is collapsed.
......@@ -104,6 +104,7 @@ DROP FUNCTION IF EXISTS st_box(box3d);
DROP FUNCTION IF EXISTS st_box3d(geometry);
DROP FUNCTION IF EXISTS st_box(geometry);
DROP FUNCTION IF EXISTS ST_ConcaveHull(geometry,float); -- this one changed to use default parameters
DROP FUNCTION IF EXISTS ST_DWithin(geography, geography, float8); -- this one changed to use default parameters
DROP FUNCTION IF EXISTS st_text(geometry);
DROP FUNCTION IF EXISTS st_geometry(box2d);
DROP FUNCTION IF EXISTS st_geometry(box3d);
......@@ -177,6 +178,7 @@ DROP FUNCTION IF EXISTS _ST_DistanceRectTree(g1 geometry, g2 geometry);
DROP FUNCTION IF EXISTS _ST_DistanceRectTreeCached(g1 geometry, g2 geometry);
-- pgis_abs type was increased from 8 bytes in 2.1 to 16 bytes in 2.2
-- See #3460
UPDATE pg_type SET typlen=16 WHERE typname='pgis_abs' AND typlen=8;
......
......@@ -597,7 +597,7 @@ with inp as (
select ST_Collect('POLYGON EMPTY', 'POLYGON EMPTY') as mp,
'POINT(0 0)'::geometry as p
)
select '#1578', _st_within(p, mp), _st_intersects(p, mp) FROM inp;
select '#1578', st_within(p, mp), st_intersects(p, mp) FROM inp;
-- #1580
select '#1580.1', ST_Summary(ST_Transform('SRID=4326;POINT(0 0)'::geometry, 3395));
......
......@@ -37,7 +37,8 @@ my @casts = ();
my @funcs = ();
my @types = ();
my %type_funcs = ();
my @type_funcs= (); # function to drop _after_ type drop
my @type_funcs = (); # function to drop _after_ type drop
my @supp_funcs = ();
my @ops = ();
my @opcs = ();
my @views = ();
......@@ -82,11 +83,16 @@ open( INPUT, $ARGV[0] ) || die "Couldn't open file: $ARGV[0]\n";
while( my $line = <INPUT>)
{
if ($line =~ /^create (or replace )?function/i) {
my $supp = 0;
my $defn = $line;
while( not $defn =~ /\)/ ) {
$defn .= <INPUT>;
}
push (@funcs, $defn)
if ($defn =~ /_supportfn /) {
$supp = 1;
}
push (@funcs, $defn) if ! $supp;
push (@supp_funcs, $defn) if $supp;
}
elsif ($line =~ /^create or replace view\s*(\w+)/i) {
push (@views, $1);
......@@ -283,6 +289,24 @@ EOF
}
print "-- Drop all support functions.\n";
foreach my $fn (@supp_funcs)
{
if ($fn =~ /.* function ([^(]+)\((.*)\)/i )
{
my $fn_nm = $1;
my $fn_arg = $2;
$fn_arg =~ s/DEFAULT [\w']+//ig;
print "DROP FUNCTION IF EXISTS $fn_nm ($fn_arg);\n";
}
else
{
die "Couldn't parse line: $fn\n";
}
}
print "-- Drop all functions needed for types definition.\n";
foreach my $fn (@type_funcs)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment