[postgis-tickets] [SCM] PostGIS branch stable-3.0 updated. 36bcfa1737a9a6c6ee2d9a8710eba6be4c51769b
git at osgeo.org
git at osgeo.org
Tue Jan 7 04:20:15 PST 2020
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".
The branch, stable-3.0 has been updated
via 36bcfa1737a9a6c6ee2d9a8710eba6be4c51769b (commit)
from 41475b02d27ab752cd03d95a5dbc33df6dcccbed (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 36bcfa1737a9a6c6ee2d9a8710eba6be4c51769b
Author: Raúl Marín <git at rmr.ninja>
Date: Tue Jan 7 13:08:57 2020 +0100
PG12: Fix several bugs in the index support function
- ST_Covers and ST_CoveredBy for geography were using the wrong strategy (which didn't exist).
- ST_ContainsProperly for geometry was using the wrong strategy.
- ST_3DIntersects was duplicated.
Closes #4608
diff --git a/NEWS b/NEWS
index 18bae40..2bab8e8 100644
--- a/NEWS
+++ b/NEWS
@@ -11,8 +11,9 @@ XXXX/XX/XX
- #4606, Respect user's LDFLAGS in postgis module build (Sandro Santilli)
- #4610, Add in logic to install postgis_tiger_geocoder from unpackaged (Regina obe)
- #4581, installing postgis_raster from unpackaged tries to use wrong schema
- - #4596, The script to generate nation_script_load.sh is missing
+ - #4596, The script to generate nation_script_load.sh is missing
a trailing quote (Bill Mill)
+ - #4608, PG12: Fix several bugs in the index support function (Raúl Marín)
PostGIS 3.0.0
2019/10/20
diff --git a/postgis/gserialized_supportfn.c b/postgis/gserialized_supportfn.c
index 4af5a1d..ff018a8 100644
--- a/postgis/gserialized_supportfn.c
+++ b/postgis/gserialized_supportfn.c
@@ -45,6 +45,7 @@
/* PostGIS */
#include "liblwgeom.h"
+#include "lwgeom_pg.h"
/* Local prototypes */
Datum postgis_index_supportfn(PG_FUNCTION_ARGS);
@@ -53,6 +54,83 @@ Datum postgis_index_supportfn(PG_FUNCTION_ARGS);
float8 gserialized_joinsel_internal(PlannerInfo *root, List *args, JoinType jointype, int mode);
float8 gserialized_sel_internal(PlannerInfo *root, List *args, int varRelid, int mode);
+enum ST_FUNCTION_IDX
+{
+ ST_INTERSECTS_IDX = 0,
+ ST_DWITHIN_IDX = 1,
+ ST_CONTAINS_IDX = 2,
+ ST_WITHIN_IDX = 3,
+ ST_TOUCHES_IDX = 4,
+ ST_3DINTERSECTS_IDX = 5,
+ ST_CONTAINSPROPERLY_IDX = 6,
+ ST_COVEREDBY_IDX = 7,
+ ST_OVERLAPS_IDX = 8,
+ ST_COVERS_IDX = 9,
+ ST_CROSSES_IDX = 10,
+ ST_DFULLYWITHIN_IDX = 11,
+ ST_3DDWITHIN_IDX = 12,
+ ST_3DDFULLYWITHIN_IDX = 13,
+ ST_LINECROSSINGDIRECTION_IDX = 14,
+ ST_ORDERINGEQUALS_IDX = 15,
+ ST_EQUALS_IDX = 16
+};
+
+static const int16 GeometryStrategies[] = {
+ [ST_INTERSECTS_IDX] = RTOverlapStrategyNumber,
+ [ST_DWITHIN_IDX] = RTOverlapStrategyNumber,
+ [ST_CONTAINS_IDX] = RTContainsStrategyNumber,
+ [ST_WITHIN_IDX] = RTContainedByStrategyNumber,
+ [ST_TOUCHES_IDX] = RTOverlapStrategyNumber,
+ [ST_3DINTERSECTS_IDX] = RTOverlapStrategyNumber,
+ [ST_CONTAINSPROPERLY_IDX] = RTContainsStrategyNumber,
+ [ST_COVEREDBY_IDX] = RTContainedByStrategyNumber,
+ [ST_OVERLAPS_IDX] = RTOverlapStrategyNumber,
+ [ST_COVERS_IDX] = RTContainsStrategyNumber,
+ [ST_CROSSES_IDX] = RTOverlapStrategyNumber,
+ [ST_DFULLYWITHIN_IDX] = RTOverlapStrategyNumber,
+ [ST_3DDWITHIN_IDX] = RTOverlapStrategyNumber,
+ [ST_3DDFULLYWITHIN_IDX] = RTOverlapStrategyNumber,
+ [ST_LINECROSSINGDIRECTION_IDX] = RTOverlapStrategyNumber,
+ [ST_ORDERINGEQUALS_IDX] = RTSameStrategyNumber,
+ [ST_EQUALS_IDX] = RTSameStrategyNumber
+};
+
+/* We use InvalidStrategy for the functions that don't currently exist for geography */
+static const int16 GeographyStrategies[] = {
+ [ST_INTERSECTS_IDX] = RTOverlapStrategyNumber,
+ [ST_DWITHIN_IDX] = RTOverlapStrategyNumber,
+ [ST_CONTAINS_IDX] = InvalidStrategy,
+ [ST_WITHIN_IDX] = InvalidStrategy,
+ [ST_TOUCHES_IDX] = InvalidStrategy,
+ [ST_3DINTERSECTS_IDX] = InvalidStrategy,
+ [ST_CONTAINSPROPERLY_IDX] = InvalidStrategy,
+ [ST_COVEREDBY_IDX] = RTOverlapStrategyNumber, /* This is different than geometry */
+ [ST_OVERLAPS_IDX] = InvalidStrategy,
+ [ST_COVERS_IDX] = RTOverlapStrategyNumber, /* This is different than geometry */
+ [ST_CROSSES_IDX] = InvalidStrategy,
+ [ST_DFULLYWITHIN_IDX] = InvalidStrategy,
+ [ST_3DDWITHIN_IDX] = InvalidStrategy,
+ [ST_3DDFULLYWITHIN_IDX] = InvalidStrategy,
+ [ST_LINECROSSINGDIRECTION_IDX] = InvalidStrategy,
+ [ST_ORDERINGEQUALS_IDX] = InvalidStrategy,
+ [ST_EQUALS_IDX] = InvalidStrategy
+};
+
+static int16
+get_strategy_by_type(Oid first_type, uint16_t index)
+{
+ if (first_type == postgis_oid(GEOMETRYOID))
+ {
+ return GeometryStrategies[index];
+ }
+
+ if (first_type == postgis_oid(GEOGRAPHYOID))
+ {
+ return GeographyStrategies[index];
+ }
+
+ return InvalidStrategy;
+}
/*
* Depending on the function, we will deploy different
@@ -66,9 +144,9 @@ float8 gserialized_sel_internal(PlannerInfo *root, List *args, int varRelid, int
typedef struct
{
const char *fn_name;
- int strategy_number; /* Index strategy to add */
- int nargs; /* Expected number of function arguments */
- int expand_arg; /* Radius argument for "within distance" search */
+ uint16_t index; /* Position of the strategy in the arrays */
+ uint8_t nargs; /* Expected number of function arguments */
+ uint8_t expand_arg; /* Radius argument for "within distance" search */
} IndexableFunction;
/*
@@ -76,25 +154,24 @@ typedef struct
* so most common functions first. Could be sorted
* and searched with binary search.
*/
-const IndexableFunction IndexableFunctions[] = {
- {"st_intersects", RTOverlapStrategyNumber, 2, 0},
- {"st_dwithin", RTOverlapStrategyNumber, 3, 3},
- {"st_contains", RTContainsStrategyNumber, 2, 0},
- {"st_within", RTContainedByStrategyNumber, 2, 0},
- {"st_touches", RTOverlapStrategyNumber, 2, 0},
- {"st_3dintersects", RTOverlapStrategyNumber, 2, 0},
- {"st_containsproperly", RTOverlapStrategyNumber, 2, 0},
- {"st_coveredby", RTContainedByStrategyNumber, 2, 0},
- {"st_overlaps", RTOverlapStrategyNumber, 2, 0},
- {"st_covers", RTContainsStrategyNumber, 2, 0},
- {"st_crosses", RTOverlapStrategyNumber, 2, 0},
- {"st_dfullywithin", RTOverlapStrategyNumber, 3, 3},
- {"st_3dintersects", RTOverlapStrategyNumber, 3, 3},
- {"st_3ddwithin", RTOverlapStrategyNumber, 3, 3},
- {"st_3ddfullywithin", RTOverlapStrategyNumber, 3, 3},
- {"st_linecrossingdirection", RTOverlapStrategyNumber, 2, 0},
- {"st_orderingequals", RTSameStrategyNumber, 2, 0},
- {"st_equals", RTSameStrategyNumber, 2, 0},
+static const IndexableFunction IndexableFunctions[] = {
+ {"st_intersects", ST_INTERSECTS_IDX, 2, 0},
+ {"st_dwithin", ST_DWITHIN_IDX, 3, 3},
+ {"st_contains", ST_CONTAINS_IDX, 2, 0},
+ {"st_within", ST_WITHIN_IDX, 2, 0},
+ {"st_touches", ST_TOUCHES_IDX, 2, 0},
+ {"st_3dintersects", ST_3DINTERSECTS_IDX, 2, 0},
+ {"st_containsproperly", ST_CONTAINSPROPERLY_IDX, 2, 0},
+ {"st_coveredby", ST_COVEREDBY_IDX, 2, 0},
+ {"st_overlaps", ST_OVERLAPS_IDX, 2, 0},
+ {"st_covers", ST_COVERS_IDX, 2, 0},
+ {"st_crosses", ST_CROSSES_IDX, 2, 0},
+ {"st_dfullywithin", ST_DFULLYWITHIN_IDX, 3, 3},
+ {"st_3ddwithin", ST_3DDWITHIN_IDX, 3, 3},
+ {"st_3ddfullywithin", ST_3DDFULLYWITHIN_IDX, 3, 3},
+ {"st_linecrossingdirection", ST_LINECROSSINGDIRECTION_IDX, 2, 0},
+ {"st_orderingequals", ST_ORDERINGEQUALS_IDX, 2, 0},
+ {"st_equals", ST_EQUALS_IDX, 2, 0},
{NULL, 0, 0, 0}
};
@@ -302,9 +379,16 @@ Datum postgis_index_supportfn(PG_FUNCTION_ARGS)
* desired strategy number we can now lookup the operator
* we want (usually && or &&&).
*/
- oproid = get_opfamily_member(opfamilyoid, leftdatatype, rightdatatype, idxfn.strategy_number);
+ oproid = get_opfamily_member(opfamilyoid,
+ leftdatatype,
+ rightdatatype,
+ get_strategy_by_type(leftdatatype, idxfn.index));
if (!OidIsValid(oproid))
- elog(ERROR, "no spatial operator found for opfamily %u strategy %d", opfamilyoid, idxfn.strategy_number);
+ elog(ERROR,
+ "no spatial operator found for '%s': opfamily %u type %d",
+ idxfn.fn_name,
+ opfamilyoid,
+ leftdatatype);
/*
* For the ST_DWithin variants we need to build a more complex return.
diff --git a/regress/core/regress_brin_index_geography.sql b/regress/core/regress_brin_index_geography.sql
index 8df9f07..697547c 100644
--- a/regress/core/regress_brin_index_geography.sql
+++ b/regress/core/regress_brin_index_geography.sql
@@ -50,6 +50,9 @@ SELECT 'scan_idx', qnodes('select * from test where the_geog && ST_GeographyFrom
SELECT 'scan_idx', qnodes('SELECT * FROM test WHERE the_geog IS NULL');
SELECT COUNT(num) FROM test WHERE the_geog IS NULL;
+SELECT '#4608-1', count(*) FROM test where ST_Covers(ST_GeogFromText('POLYGON((0 0, 45 0, 45 45, 0 45, 0 0))'), the_geog);
+SELECT '#4608-2', count(*) FROM test where ST_CoveredBy(the_geog, ST_GeogFromText('POLYGON((0 0, 45 0, 45 45, 0 45, 0 0))'));
+
DROP INDEX brin_geog;
-- cleanup
diff --git a/regress/core/regress_brin_index_geography_expected b/regress/core/regress_brin_index_geography_expected
index b427a5f..c83d7b9 100644
--- a/regress/core/regress_brin_index_geography_expected
+++ b/regress/core/regress_brin_index_geography_expected
@@ -168,3 +168,5 @@ scan_idx|Bitmap Heap Scan,Bitmap Index Scan
42.99|POINT Z (42.99 42.99 42.99)
scan_idx|Bitmap Heap Scan,Bitmap Index Scan
1001
+#4608-1|3681
+#4608-2|3681
-----------------------------------------------------------------------
Summary of changes:
NEWS | 3 +-
postgis/gserialized_supportfn.c | 132 +++++++++++++++++----
regress/core/regress_brin_index_geography.sql | 3 +
regress/core/regress_brin_index_geography_expected | 2 +
4 files changed, 115 insertions(+), 25 deletions(-)
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list