Intersects error on filtered and casted geometry type
Regina Obe
lr at pcorp.us
Fri Feb 7 10:07:33 PST 2025
> Hello,
>
> Bellow my case and the steps to reproduce :
>
> /* About my database */
> SELECT VERSION();
> -- PostgreSQL 16.4, compiled by Visual C++ build 1941, 64-bit SELECT
> POSTGIS_VERSION();
> -- 3.4 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
>
> /* Create a table with a generic geometry column with french CC48 3948
SRID */
> CREATE TEMP TABLE temp_geometry_tab (
> id INTEGER NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
> geom GEOMETRY(GEOMETRY, 3948)
> );
> -- CREATE TABLE
> -- Query returned successfully in 117 msec.
>
> /* Add two rows, one with a point geometry and another with multipolygon
*/
> INSERT INTO temp_geometry_tab (geom) VALUES ('POINT (2049346
> 7276066)'), ('MULTIPOLYGON (((2049302 7274650,2050712
> 7276342,2051981 7276013,2050865 7275954,2049795 7274791,2049948
> 7274050,2049302 7274650)))') ;
> -- INSERT 0 2
> -- Query returned successfully in 71 msec.
>
> /* Create a view to filter the point geometries and cast them into points
*/
> CREATE TEMP VIEW temp_geometry_view AS SELECT
> id,
> geom::GEOMETRY(POINT, 3948)
> FROM temp_geometry_tab
> WHERE ST_GeometryType(geom) IN ('ST_Point') ;
> -- CREATE VIEW
> -- Query returned successfully in 83 msec.
>
> /* When I try to intersect the view geometry, an error occurs as if I
query the
> base table */ SELECT id FROM temp_geometry_view WHERE geom &&
> ST_MakeEnvelope(2041534,7271489,2059551,7281479,3948)
> ;
> -- ERROR: Geometry type (MultiPolygon) does not match column type (Point)
> -- SQL state: 22023
>
> /* When I try to query the first view with and additional filter it works
*/ SELECT
> id,
> geom::GEOMETRY(POINT, 3948)
> FROM temp_geometry_tab
> WHERE
> ST_GeometryType(geom) IN ('ST_Point')
> AND geom &&
> ST_MakeEnvelope(2041534,7271489,2059551,7281479,3948)
> ;
> -- id: 1 | geom:
> 01010000206C0F00000000000042453F410000008088C15B41
>
>
> Is-it normal that the filter consider the whole base table with
multipolygon
> geometries while only point type geometries are filtered in the queried
view?
>
> Regards,
> Julien Monticolo
>
I think in the past it might not have been possible but I don't think there
is a guarantee that the WHERE clause always gets checked before the SELECT
part is applied.
I suppose you could get around it, not nice by doing this
CREATE TEMP VIEW temp_geometry_view AS SELECT
id,
CASE WHEN ST_GeometryType(geom) IN ('ST_Point') THEN geom ELSE NULL
END::GEOMETRY(POINT, 3948)
FROM temp_geometry_tab
WHERE ST_GeometryType(geom) IN ('ST_Point') ;
I think adding in a pointless OFFSET also forces WHERE clause to be
processed first, though that is a very oldish hack too
CREATE TEMP VIEW temp_geometry_view AS SELECT
id,
geom::GEOMETRY(POINT, 3948)
FROM temp_geometry_tab
WHERE ST_GeometryType(geom) IN ('ST_Point')
OFFSET 0;
I think also using a CHECK option on the view might work though that
designed to prevent updates that would prevent a record from being filtered
out of the view by updating the condition that makes it a member and not for
this situation:
Something like
CREATE TEMP VIEW temp_geometry_view AS SELECT
id,
geom::GEOMETRY(POINT, 3948)
FROM temp_geometry_tab
WHERE ST_GeometryType(geom) IN ('ST_Point')
WITH CHECK OPTION ;
More information about the postgis-users
mailing list