Note that if you work with database-level settings, as in @nick-barnes his answer, these will be set as session defaults when the user connects to that database, but can be overridden for that session (or a transaction).
If you wish to enforce a database setting, you can do so by going directly to the pg_db_role_setting system catalog, as done by this function from my pg_safer_settings extension (copied here with my explicit permission 😉):
create function pg_db_setting(pg_setting_name$ text, pg_role$ regrole = 0)
returns text
stable
-- security definer
return (
select
regexp_replace(expanded_settings.raw_setting, E'^[^=]+=', '')
from
pg_catalog.pg_db_role_setting
inner join
pg_catalog.pg_database
on pg_database.oid = pg_db_role_setting.setdatabase
cross join lateral
unnest(pg_db_role_setting.setconfig) as expanded_settings(raw_setting)
where
pg_database.datname = current_database()
and pg_db_role_setting.setrole = coalesce(
pg_role$,
0 -- 0 means “not role-specific”
)
and expanded_settings.raw_setting like pg_setting_name$ || '=%'
limit 1
);
Here's an example to illustrate the difference between the semantics of the pg_catalog.current_setting() function and my pg_db_role_setting() function:
CREATE DATABASE mydb;
CONNECT TO mydb
CREATE ROLE myrole;
ALTER DATABASE mydb
SET app.settings.bla = 1::text;
ALTER ROLE myrole
IN DATABASE mydb
SET app.settings.bla = 2::text;
SET ROLE myrole;
SET app.settings.bla TO 3::text;
SELECT current_setting('app.settings.bla', true); -- '3'
SELECT pg_db_role_setting('app.settings.bla'); -- '1'
SELECT pg_db_role_setting('app.settings.bla', current_user); -- '2'
Another common pattern is to store settings as IMMUTABLE functions or in a table. If you store them in a table, do me a favor and store them as columns, not rows. My pg_safer_settings extension features a pg_safer_settings_table which combines these 2 paradigms, by allowing you to store your settings as columns, and automatically maintaining a current_<col_name>() function for each of these columns. (The current_ prefix is configurable.)
RAISE EXCEPTIONand reasonably recent versions up allow you to specify the code that you raise.