Im building parameterised sql using pgp and wrapping the generated sql inside DO $$ END $$. Problem is when I try saving password (varchar) some of the password hashes contain $$ which causes issues since the psql is inside DO $$ END $$. My question, Is it possible to somehow escape $$ or save password hash with $$ inside it but without plpgsql erroring out.
sample generated plpgsql
DO $$ DECLARE parent_user int;
BEGIN CREATE TEMP TABLE IF NOT EXISTS tmp_f6a8e872_b346_4184_889d_52ffeded463f (id int);
INSERT INTO form_user(firstname,lastname,displayname,job_title,username,authentication_type,password,password2,password_reset,role,comm_portal,issue_ticket,email,rec_sms,created_by,created_on,auto_name)
VALUES ('delete','delete','delete','admin','delete','password','$p5k2$$9kenbgnr$XuoSekYV4qQlDE0NkNEs2UGJEEIWtjG/','$p5k2$$7cxgxz4n$JSkgV8oGg72S1O6i2xYZSLEU2Yd6bdCO','0','admin','No','No','[email protected]','No',22,'11/5/2023 19:59:45','delete delete (admin)') RETURNING id INTO parent_user;
INSERT INTO tmp_f6a8e872_b346_4184_889d_52ffeded463f (id) VALUES (parent_user);
END; $$;
Error
error: syntax error at or near "9"
2
Answers
The
$$
is a special type of string called dollar quoting. The$$
indicates the start and end of a string just like'
does.You can put more characters between the
$$
to make a unique delimiter like$body$
. This is called a "tag".While dealing with a single known string constant, just add a token to your dollar-quotes that is not repeated in the string:
Also, you don’t need the intermediate step with a variable. I would just use the SQL without the wrapping
DO
command, which doesn’t add anything useful in the example.When dealing with unknown string input, and you need a quoted string literal (like for dynamic SQL, unlike the given example!) use the function
quote_literal()
or the equivalentformat('%s', $input)
to build a string with a nested string literal. Each produces a valid string literal automatically, escaping all special characters as needed. (There must be an input variable or parameter in such a case for initial input.See: