I have defined a materialized view in a PostGIS 2.1-enabled database running PostgreSQL 9.3.1:

CREATE MATERIALIZED VIEW canvec_data.contours_m AS 
    contours_original.elevation::integer AS elevation_orig, 
        WHEN "substring"(contours_original.code::text, 1, 3) = '257'::text THEN round(contours_original.elevation::double precision * 0.3048::double precision)
        ELSE contours_original.elevation::double precision
    END AS elevation_m, 
 FROM canvec_data.contours_original

I had, perhaps erroneously, expected that this resultant entity (a table?) would be listed in the public.geometry_columns view, and thus be properly interpreted by GIS viewer software such as QGIS.

The materialized view does not appear in the public.geometry_columns view.

What am I doing wrong?


1 Answer 1


You're not doing anything wrong, you discovered a hole in our support for PostgreSQL 9.3's new materialized view feature. I've patched all the relevant branches, and you can update your definition of geometry_columns yourself (see the change references in this ticket http://trac.osgeo.org/postgis/ticket/2511)

Actually, here's something you can just paste into the SQL window:

CREATE OR REPLACE VIEW geometry_columns AS 
  SELECT current_database()::varchar(256) AS f_table_catalog, 
    n.nspname::varchar(256) AS f_table_schema, 
    c.relname::varchar(256) AS f_table_name, 
    a.attname::varchar(256) AS f_geometry_column, 
             postgis_constraint_dims(n.nspname, c.relname, a.attname),
             2) AS coord_dimension, 
             postgis_constraint_srid(n.nspname, c.relname, a.attname),
             0) AS srid, 
    -- force to be uppercase with no ZM so is backwards compatible
    -- with old geometry_columns
          NULLIF(upper(postgis_typmod_type(a.atttypmod)::text), 'GEOMETRY'),
          postgis_constraint_type(n.nspname, c.relname, a.attname),
        ), 'ZM', ''
      ), 'Z', ''
    )::varchar(30) AS type
  FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n
  WHERE t.typname = 'geometry'::name 
    AND a.attisdropped = false 
    AND a.atttypid = t.oid 
    AND a.attrelid = c.oid 
    AND c.relnamespace = n.oid 
    AND (c.relkind = 'r'::"char" OR c.relkind = 'v'::"char" OR c.relkind = 'm'::"char")
    AND NOT pg_is_other_temp_schema(c.relnamespace)
    AND NOT ( n.nspname = 'public' AND c.relname = 'raster_columns' )
    AND has_table_privilege( c.oid, 'SELECT'::text );
  • 5
    Great reply and fix; that is customer service...
    – D.E.Wright
    Commented Oct 16, 2013 at 23:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.