I posted this here:
https://dba.stackexchange.com/questions/260184/create-table-if-not-exists-fails-with-privilege-exception-when-table-exists
and after a bit of time on chat with Peter Vandivier, decided I should ask here
for confirmation. The question as posed:
======================================================================
I discovered that CREATE TABLE IF NOT EXISTS will fail with
insufficient_privilege if the role executing the statement does, in fact, not
have the necessary privileges, but does so regardless of whether the table
exists or not. I would expect that if the table exists, the statement succeeds
without making any modifications. Is that reasonable, or am I missing something?
The docs (for 9, 10, 11, and 12) all say simply
IF NOT EXISTS
Do not throw an error if a relation with the same name already exists. A
notice is issued in this case. Note that there is no guarantee that the
existing relation is anything like the one that would have been created.
I don't know whether a notice about the privilege check taking precedence over
the existence check is appropriate here, but I feel like either it should be
documented (maybe it is, somewhere else?), or that the behavior should change
(could this be a backwards compatibility issue?).
I've worked around it by
DO $$
BEGIN
CREATE TABLE IF NOT EXISTS tbl();
EXCEPTION WHEN insufficient_privilege THEN
IF NOT EXISTS (
SELECT FROM pg_catalog.pg_tables
WHERE schemaname = current_schema() AND tablename = 'tbl'
) THEN
RAISE;
END IF;
WHEN others THEN RAISE;
END;
$$;
but in the end, that query is not in code I own, so my ability to change it is
limited, and if I can't get that change accepted, I believe I either have to get
Postgres changed (which is admittedly likely a larger lift) or accept that I
have to give the user more privilege than I want it to have.
======================================================================
Peter had some confusion about the "I can't change the code, but I changed the
code" bit in the last paragraph. It's code in a third-party module I'd rather
not fork (though I probably will, in order to fix the problem, if the author
doesn't respond). But it led to his comment
CREATE IF NOT EXISTS... must be a pseudo-transactional command (at first glance)
1. schema lock identifier
2. schema check identifier
3. schema modify
4. schema unlock identifier
if you don't have the permission to do #2, that doesn't mean you get to skip #1
hence the error
which, after a bit of thought, I realized that the insufficient_privilege might
very well be coming from #1, not #3, which is where I thought it was coming
from.
So my question is a) is that the case, and b) if so, would an update to the docs
be warranted? Or is this actually documented somewhere?
Thanks!
Danek