5

I have a large set of user-defined procedures which need to be used on several separate catalogs (databases).

The built-in procedures normally seen in pg_catalog.pg_proc appear to be reflected in the pg_catalog schemas of all the databases. I was hoping that creating a function in the postgres database might make it accessible universally, but no, whether created in the postgres.pg_catalog or postgres.public schema.

Does anyone know how I can make user-defined procedures available universally?

I've tried faking namespace and owner, granting execute to public, and holding a black cat over my left shoulder (but not during a full moon).

Will setting it up as an extension work? (That may take some negotiating and finagling for my environment is the only reason I haven't tried it yet.)

Thanks in advance

5
  • you can put the function in the template db and any new databases would have it. otherwise an extension is your best bet Commented Aug 10, 2017 at 19:02
  • Having it in the template would get it half way there, but leaves the maintenance headache of updating so many copies of the same thing. I'll try the extension. Thanks, Neil. Commented Aug 10, 2017 at 20:21
  • Successfully installed my first postgres extension, but it still has the same problem. I created it in the postgres schema, and can call it successfully there, but calling from sandbox schema evokes the 'ERROR: function...does not exist.' complaint. I can't help but think I'm missing something else that needs to be done. In postgres.pg_catalog.pg_available_extensions, plpgsql is listed with 1.0 as the value of 'installed_version'--which makes me think the plpgsql itself is loaded this way. (And obviously it's available everywhere.) Any suggestions? Commented Aug 10, 2017 at 21:37
  • plpgsql is available by default because the extension is installed in template1; there's no cross-database magic going on. You'll need to roll this out to each database individually. Fortunately, as you can see from @Neil's answer, it's pretty straightforward. Commented Aug 10, 2017 at 23:41
  • Thanks Nick. I see how extensions can be propagated at db create time by having them in template1. (For future db's this seems like a good approach.) I still wonder if perhaps I'm not asking the right question. Commented Aug 14, 2017 at 16:41

1 Answer 1

2

PostgreSQL databases are quite segregated. You'll need to install your extension in each one. Here's a shell script to ease your pain:

for DB in $(psql -t -c "SELECT datname FROM pg_database WHERE datname NOT IN ('postgres', 'template0', 'template1')"); do
  psql -d $DB -c "CREATE EXTENSION IF NOT EXISTS foo"
done

Or is this one database, with multiple schemas that you're talking about?

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Neil, there are several databases, each with multiple schemas, so the shell script would work in theory, though fitting it into our security model might take a minute.;)
Good approach. You could replace the nested -c "CREATE EXTENSION... with -f user_func.ddl to create a function defined in said file to all databases.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.