NAME

DBIO::PostgreSQL::PostGIS::Extension - The postgis extension for deploy, introspection and diff (DBIO extension interface)

VERSION

version 0.900004

SYNOPSIS

An application states that its database has PostGIS in the schema's declaration; that is all it writes:

package MyApp::DB;
use DBIO Schema => -pg;
__PACKAGE__->pg_extensions(postgis => { schema => 'gis' });

The driver resolves the name postgis to this class (its table of the family's extensions), so the rules below apply to this schema and to no other.

DESCRIPTION

The model knowledge of PostGIS, as a class of the extension interface of DBIO::Extension (ADR 0066). It replaces the Deploy and Introspect subclasses this distribution used to carry (DBIO::PostgreSQL::PostGIS::Deploy, ::Introspect), which are stubs now: nothing is composed into a Deploy class, no introspector is synthesised, and no hook is registered into a driver registry.

What each method answers

inspect

Nothing. The installed state (version, schema) is the driver's catalog read and is in the extension's entry.

claims

Nothing, by measurement and not by omission. The objects PostGIS puts into a database -- spatial_ref_sys, the views geometry_columns and geography_columns, its types, functions and operators -- are members of the extension in pg_depend, and the driver's base filter keeps members out of the model. PostGIS creates no objects at runtime in the application's namespaces. (The topologies of postgis_topology do; they are claimed by DBIO::PostgreSQL::PostGIS::Topology::Extension. The graph schemas of Apache AGE belong to AGE; phase 2 sees the model after the claims of phase 1, so a geometry column a user put into a label table is gone before PostGIS annotates.)

annotate

base_type (geometry or geography), geometry_type (lower case, point) and srid on each column whose type lives in the PostGIS schema, parsed from the data_type string (geometry(Point,4326)), at the address [ column => $table_key, $column_name ]. See "annotate".

verdict

A column type change between spatial types: another SRID is converted with ST_Transform, anything else is refused. See "verdict".

activation

Nothing. PostGIS needs no LOAD and no search_path entry of its own.

storage_layer

DBIO::PostgreSQL::PostGIS::Storage (ensure_postgis, postgis_version), registered by the driver for a declared postgis.

inflation_component

DBIO::PostgreSQL::PostGIS, the result-class component that inflates geometry/geography columns to DBIO::PostgreSQL::PostGIS::Geometry objects. See "inflation_component".

Peers

PostGIS reads no peer. The graph schemas of AGE are not its model because AGE's claims run in phase 1; no code here depends on AGE being present.

METHODS

extension_interface

Returns 1.

name

Returns postgis, the pg_extension.extname.

driver

Returns DBIO::PostgreSQL, the driver this extension belongs to (an assertion, never a determination of the driver).

storage_layer

Returns DBIO::PostgreSQL::PostGIS::Storage, the runtime layer of the extension.

inflation_component

my $component = DBIO::PostgreSQL::PostGIS::Extension->inflation_component;

The result-side part of PostGIS: the component that gives a geometry or geography column its inflate/deflate handlers and the spatial resultset helpers. ADR 0066 (Decisions, 2) has the extension class name it and the driver apply it for a declared postgis. Core's DBIO::Extension has no method for it (yet): this one is not part of interface version 1, the driver asks for it with ->can.

annotate

my $triples = DBIO::PostgreSQL::PostGIS::Extension->annotate($model, $ctx);

Phase 2. For each column of $model->{columns} whose data_type is geometry or geography, with or without the modifier and with a schema prefix, quoted or not (public.geometry(Point,4326), "My Schema".geometry), the triples base_type, geometry_type (when the type has a modifier) and srid (when it has one), at [ column => $table_key, $column_name ].

A column is annotated only if its type lives in the PostGIS schema -- the type_schema of the column hash, else the prefix of the string -- so a foreign type named geometry in another schema is left alone. The PostGIS schema is the one of the model's extensions section, else the one of the extension's entry. Without it (no PostGIS in the model, no installed state) every type named geometry/geography is annotated, and so is a column with neither type_schema nor a prefix: when the evidence is missing the type is taken as PostGIS's, because staying silent about an unclear case is how this once skipped schema-qualified types unnoticed. A quoted prefix is compared as written, case included.

The model is read, not changed.

verdict

my $answer = DBIO::PostgreSQL::PostGIS::Extension->verdict($change, $ctx);

Phase 3, for a change { kind => 'column_type', table, column_name, old_info, new_info }. The infos carry the annotations of phase 2.

  • the same type (geometry or geography, the same geometry type) under another SRID is converted: { using => 'ST_Transform(column, srid)' }, for a geography through geometry and back. The coordinates are recomputed, not relabelled.

  • any other change between two spatial types -- another geometry type, geometry to geography or back -- is refused: { refuse => ... } naming the column and both types.

  • everything else (not spatial on either side, an unconstrained geometry on either side, an SRID that is not given) is none of this extension's business: undef.

AUTHOR

DBIO Authors

COPYRIGHT AND LICENSE

Copyright (C) 2026 DBIO Authors

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.