I’m using a client library that only accepts SQL strings that are compile-time constant, in order to prevent SQL injection attacks. And I wanted to execute some GRANT statements for a set of tables and a user.
I tried
GRANT SELECT ON $1 TO $2
and passing the table and user names as bound parameters. But that fails with
syntax error at or near "$1"
Not being able to pass in a tablename as a bound parameter is understandable (you can’t use SELECT columns FROM $1
for instance), and with a bit of work, I can make the tablenames compile-time constants. But changing the command to
GRANT SELECT ON MyTable to $1
and passing just the username as a bound parameter also fails. Which is more of an issue: whereas the tablenames can be hard-coded with a bit of work, the username is only known at runtime.
Is there a way to pass the username as a bound parameter, or do I need to bypass my client library in order to GRANT permissions to a run-time-defined username?
2
Answers
The only statements that can use parameters are
INSERT
,UPDATE
,DELETE
andSELECT
.GRANT
cannot use parameters; you will have to build a statement dynamically.You can also make the table as function input argument. quote_ident is used for identifiers quoting. In
GRANT SELECT ON MyTable to $1
you hope to make sure $1 is a identifiers rather than some string. Because if $1 string then the whole command can be:GRANT SELECT ON MyTable to public;
GRANT SELECT ON MyTable to role_a WITH GRANT OPTION;
So the above function can solve these problem.