Chapter 38. Install/Import/Default Database/Schema, Extensions and Role Handling

A model does not define a specific catalog, since in practice a model can be installed into any catalog. A model may define a default catalog name and the default live profile will be created from this. The default name is stored in pgcat_catalog_name. Otherwise the live profile in context (which may be the default of course) is used to define the installation catalog.

On install if the catalog does not exist it will be created. If the catalog does exist it will be destroyed (after prompting) and recreated. The assumption is the catalog contains one model and that model defines the entirety of the catalog. The database is installed into the default schema of that catalog but see below. This is the behaviour if the model is defined with no (empty) default schema.

A model does not need to define a specific schema, in which case the current default schema in the installation catalog will be used - in this context the model must be fully relocatable (as for an extension), i.e. able to work in any schema - it must not contain specific schema references for itself (unqualified names not validated on load, e.g. in functions, must be able to be found via the search path, although see below). A model can also define a default installation schema. The name is stored in pgcat_schema_name. This works much like the default installation catalog. In this case on installation the search path is first set to this schema (as for extensions) and all objects are created under that schema. The model can include self references qualified by schema as long as they are consistent with that schema name. The live profile can alter this installation schema, in the same way as the catalog (although note that any qualified schema references would break if not in search path and then may clash, although see below). A model can only represent/hold one schema, a model cannot be split across multiple schemas, although it would in principle be possible for a model to create additional schemas (as entitys), however this has not been implemented (each must be a distinct model).

On install where a non-empty installation schema has been set behaves differently. If the installation catalog does not exist it will be created, if it does exist it will not be destroyed first (the assumption is it may contain other structures and/or other models). It may be manually destroyed first if necessary using destroy. If the schema does not exist it will be created, if it does exist it will be destroyed with cascade (after prompting) and recreated.

On upgrade the catalog as defined by LiveProfile will be altered, either the default schema if no installation schema defined for the model or the specific installation schema will be set first prior to upgrade.

In summary:

An import can load any catalog and any schema into a model. The catalog and schema are both defined by the LiveProfile. The model to load into and optionally a schema are defined in the import command as model[.schema]. If no schema is specified an import is carried out against the current schema in the catalog. The imported catalog and schema are held in pgcat_name in model and pgcat_database_name in other tables and are the transient (most recently imported) catalog and schema for that model. If there has been no import they will be the default catalog and installation schema (if any). On import these will change to the imported catalog and schema. They are not used other than as an import handle. Note that any catalog/schema could be imported - it is up to the user to ensure that the one that is is appropriate to the specified model.

In summary:

On importing a new model (not currently defined) - the models default catalog will be set to that used for import. The installation schema will be left empty, unless a specific schema was given on import, in which case it will be set to that.

Roles are cross-catalog and cross-schema so cannot be handled as above, despite being defined against a model. Roles are named (in PostgreSQL) with the MODEL_PREFIX (normally _th_ and the default catalog (note that this may differ from that actual installation catalog), for example _th_mydb_ROLENAME. The use of any other name starting with the MODEL_PREFIX should be avoided, much as the use of pg\_ should be avoided as that may clash in a search path with the pg_catalog schema objects. If an installation schema is defined all roles will also be qualified with the schema name, as in \_th\_mydb\_SCHEMANAME\_ROLENAME. The catalog name and schema name and role name should be kept short to avoid overflow of the fixed name length (63 characters) when combined. The roles while installation wide will be created and deleted with the catalog and schema as if they were owned by that catalog or schema - they should not be used outside of that context.

A model may be installed/upgraded as an extension. In this case the toolkit install/upgrade actions are not used - standard PostgreSQL extension handling is used. An extension can be produced by setting the name in extension_name and version in extension_version and then using the ddlext derivation - which effectively turns the install ddl directory into a single .sql file and adds a .config file. If no name is specified the model name is used as the extension name and 1.0.0 as the version. When put in the correct location the CREATE EXTENSION command can then be used to load. Tables can be given a property (ExtensionConfig) in the model that will define them as configuration tables in the extension ddl. The extension will be set as fully relocatable if no installation schema is defined, but if one is set then the extension will be created against that schema (the schema is fixed and set before load). So while installation schema defines the default load schema normally, for an extension it defines a fixed schema. Note that any model requirements (external extensions) are added to the extension config and must be manually satisfied prior to loading the extension on a schema that is the same as qualified references in the model extension (normally public)..

A model loaded as an extension can still be live upgraded by the toolkit upgrade command.

A model defined as an extension will have DDL with a rewrite function that allows schema references using @myschema@ to be substituted with CURRENT_SCHEMA on load - this allows function definitions to be relocatable when used as an extension or on normal load. The actual search_path substitution includes public (after CURRENT_SCHEMA) and this must be where any pre-requisite extensions should always be installed (unless fully qualified in the model).

An extension that has an installation schema will need to ensure that any elements not rewritten on load have that schema used explicitly to qualify (e.g. anywhere used in function definitons). Alternatively @extschema@ can be used - however that precludes the use of the model as anything other than an extension. To get around this factory template files can use #SCHEMA_PREFIX() in front of any element to be qualified (without the dot) and this will be rewritten as @extschema on "gather" when the model has an installation schema defined and as "" when not.