Schema Collision (orafce_mail)¶
A separate, unrelated extension — orafce_mail, by the maintainer of the well-known orafce Oracle-compatibility project (though not bundled inside base orafce itself) — also creates a schema named utl_mail, implementing the same three function names via libcurl and direct SMTP rather than a durable queue. Any shop migrating from Oracle is a genuinely plausible candidate to already have orafce_mail installed for exactly this reason. The two cannot coexist — CREATE SCHEMA utl_mail would collide outright if both tried to run.
What the install script actually checks¶
The naive check — "does a schema named utl_mail already exist?" — doesn't work, and building it that way would have made pg_relay_notifier_utl_mail fail on every ordinary install, collision or not. PostgreSQL's CREATE EXTENSION auto-creates the schema named in the control file's schema = utl_mail declaration before the install script body even runs, whenever that schema doesn't already exist — so by the time the script's own logic executes, utl_mail already exists, empty, on a perfectly ordinary fresh install. Checking mere existence would treat that normal, expected state as a collision.
The actual check looks for pre-existing objects inside the schema, not the schema's existence:
SELECT count(*) FROM (
SELECT 1 FROM pg_proc WHERE pronamespace = to_regnamespace('utl_mail')
UNION ALL
SELECT 1 FROM pg_class WHERE relnamespace = to_regnamespace('utl_mail')
) existing_objects;
A freshly auto-created schema (the ordinary case) has zero objects in it at this point — proceeds normally. A schema pre-populated by orafce_mail (or a stale, incompletely-removed previous pg_relay_notifier_utl_mail install) has real functions already in it — the install raises immediately, naming both possible causes, rather than silently layering functions into a schema someone else owns:
schema "utl_mail" already contains objects this extension did not create
HINT: Most likely causes: the separate orafce_mail extension ..., which cannot
coexist with this one; or a stale pg_relay_notifier_utl_mail install left
behind by an incomplete DROP EXTENSION ... Resolve by dropping whichever is
unwanted (DROP SCHEMA utl_mail CASCADE, or DROP EXTENSION orafce_mail) before
retrying.
No explicit CREATE SCHEMA in the extension's own SQL¶
For the same reason, pg_relay_notifier_utl_mail--1.0.sql contains no CREATE SCHEMA statement of its own — not even a defensive CREATE SCHEMA IF NOT EXISTS. Adding one, even the IF NOT EXISTS form, produces a different, equally real failure: PostgreSQL refuses to let an extension's own install script claim ownership of a schema via IF NOT EXISTS unless the schema is already a tracked member of that same extension — and on a fresh install, the schema was only just auto-created moments earlier by CREATE EXTENSION itself, so it isn't yet tracked as anything from the script's own point of view. (pg_relay_notifier's own install script follows the identical pattern for its pgrelay_notifier schema, for the same reason.)
The managed-PostgreSQL install path has no such auto-creation machinery at all (there's no CREATE EXTENSION involved), so the generated managed script has its own CREATE SCHEMA utl_mail; prepended by make managed — see Installation.
If you hit the collision¶
Decide which of the two you actually want in this database — they can't both be there:
-- keep pg_relay_notifier_utl_mail, remove orafce_mail
DROP EXTENSION orafce_mail;
-- keep orafce_mail, don't install pg_relay_notifier_utl_mail
-- (use pg_relay_notifier's own UTL_MAIL-shaped functions instead — see the User Guide)