Skip to main content
Rollback to Revision 3
Link
das-g
  • 163
  • 10

Finding out which source row has Can I let PostgreSQL report the offending rows when a different PostGIS subtypemulti-row INSERT fails because of mismatched geometry types?

Tweeted twitter.com/StackDBAs/status/846379894485536769
edited title
Link
Evan Carroll
  • 64.7k
  • 49
  • 251
  • 496

Can I let PostgreSQL report the offending rows when Finding out which source row has a multi-row INSERT fails because of mismatched geometry types?different PostGIS subtype

Remove real-world example that isn't that illustrative. The question is long enough without it, so let's not clutter it with that.
Source Link
das-g
  • 163
  • 10
A real-world example:

(Table definition and insert statement from a project working on OpenStreetMap data imported with osm2pgsql.)

DROP TABLE if exists osmaxx.building_a;
CREATE TABLE osmaxx.building_a (
    osm_id bigint,
    lastchange timestamp without time zone,
    geomtype char(1),
    geom geometry(MULTIPOLYGON, 4326),
    type text,
    name text,
    name_en text,
    name_fr text,
    name_es text,
    name_de text,
    int_name text,
    label text,
    tags text,
    height float
);

INSERT INTO osmaxx.building_a
  SELECT osm_id as osm_id,
    osm_timestamp as lastchange ,
    CASE
     WHEN osm_id<0 THEN 'R' -- R=Relation
     ELSE 'W'               -- W=Way
     END AS geomtype,
    ST_Multi(way) AS geom,
    building as type,
    name as name,
    "name:en" as name_en,
    "name:fr" as name_fr,
    "name:es" as name_es,
    "name:de" as name_de,
    int_name as name_int,
    case
        when name is not null AND name = osml10n_translit(name) then name
        when "name:en" is not null then "name:en"
        when "name:fr" is not null then "name:fr"
        when "name:es" is not null then "name:es"
        when "name:de" is not null then "name:de"
        when int_name is not null then osml10n_translit(int_name)
        when name is not null then osml10n_translit(name)
        else NULL
    end as label,
    cast(tags as text) as tags,
    cast_to_float_null_if_failed(height) as height
  FROM osm_polygon
WHERE building is not null;

When analyzing this bug it would have been really useful to know the osm_id of to-be-inserted rows that could not be inserted due to

Geometry type (MultiLineString) does not match column type (MultiPolygon)
A real-world example:

(Table definition and insert statement from a project working on OpenStreetMap data imported with osm2pgsql.)

DROP TABLE if exists osmaxx.building_a;
CREATE TABLE osmaxx.building_a (
    osm_id bigint,
    lastchange timestamp without time zone,
    geomtype char(1),
    geom geometry(MULTIPOLYGON, 4326),
    type text,
    name text,
    name_en text,
    name_fr text,
    name_es text,
    name_de text,
    int_name text,
    label text,
    tags text,
    height float
);

INSERT INTO osmaxx.building_a
  SELECT osm_id as osm_id,
    osm_timestamp as lastchange ,
    CASE
     WHEN osm_id<0 THEN 'R' -- R=Relation
     ELSE 'W'               -- W=Way
     END AS geomtype,
    ST_Multi(way) AS geom,
    building as type,
    name as name,
    "name:en" as name_en,
    "name:fr" as name_fr,
    "name:es" as name_es,
    "name:de" as name_de,
    int_name as name_int,
    case
        when name is not null AND name = osml10n_translit(name) then name
        when "name:en" is not null then "name:en"
        when "name:fr" is not null then "name:fr"
        when "name:es" is not null then "name:es"
        when "name:de" is not null then "name:de"
        when int_name is not null then osml10n_translit(int_name)
        when name is not null then osml10n_translit(name)
        else NULL
    end as label,
    cast(tags as text) as tags,
    cast_to_float_null_if_failed(height) as height
  FROM osm_polygon
WHERE building is not null;

When analyzing this bug it would have been really useful to know the osm_id of to-be-inserted rows that could not be inserted due to

Geometry type (MultiLineString) does not match column type (MultiPolygon)
link to example sources
Source Link
das-g
  • 163
  • 10
Loading
Source Link
das-g
  • 163
  • 10
Loading