0

I have been trying to create a script that detects that a role already excists and if it does it should revoke all privileges. This works fine doing it like this:

DO $$DECLARE count int;
BEGIN
SELECT count(*) INTO count FROM pg_roles WHERE rolname = 'superman';
IF count > 0 THEN
    REVOKE ALL PRIVILEGES ON TABLE FROM superman;
END IF;
END$$;

But now I want this to be dynamic per environment since I will be using different role names per environment. So I tried to use the \set mechanism but that doesn't seem to work when using pl/sql so if I would do something like the following Postgresql is complaining with syntax errors:

/set environment _int

DO $$DECLARE count int;
BEGIN
SELECT count(*) INTO count FROM pg_roles WHERE rolname = 'superman';
IF count > 0 THEN
    REVOKE ALL PRIVILEGES ON TABLE FROM superman:environment;
END IF;
END$$;

Although if I would not do it in pl/sql the revoke statment works just fine. So my question is how can I make my script dynamic by passing parameters to it so they will be replaced?

0

1 Answer 1

4

You have to use EXECUTE for dynamic SQL. Also, a DO statement cannot take parameters. Create a plpgsql function:

CREATE OR REPLACE FUNCTION f_revoke_all_from_role(_role text)
  RETURNS void AS
$BODY$
BEGIN

IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = _role) THEN
    EXECUTE 'REVOKE ALL PRIVILEGES ON TABLE x FROM ' || quote_ident(_role);
END IF;

END;
$BODY$ LANGUAGE plpgsql;

Call:

SELECT f_revoke_all_from_role('superman');
  • IF block is simpler with EXISTS.

  • I use quote_ident() to avoid SQLi.

  • The table name could be the second parameter of the function ...

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

3 Comments

Ah ok.. Thnx!! I will try this out. I was already afraid to have to do it like this. I find it weird though since in Oracle it is possible to pass variables from the outside to a plsql script without having to write a function. I just want this logic in there so I can do a deployment of my database. Why do I have to create a function for this? Isn't there any other way of doing it like in Oracle?
@user1515731: I wouldn't know of any. The plpgsql function doesn't seem to complicated, though, or does it?
No it's not indeed but I don't like the fact that I have to create a function just to detect if a role exists and basically drop it afterwords since I won't be using it in my application. But I will try it out thnx for your help :-)

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.