Thread: StartupMessage parameters - free-form or not?

StartupMessage parameters - free-form or not?

From
Jaka Jančar
Date:
Hi,

I wrote a Postgres client and in it I allow the user to specify arbitrary StartupMessage parameters (Map<string,string>). This is convenient because the user can for example set search_path without issuing a separate SET query or encoding things into the "options" parameter. The protocol documentation also says that the latter is deprecated and what I'm doing (if I understand it right) is preferred.

A fellow author of a driver for a different language reminds me that libpq explicitly enumerates the supported parameters in the docs, and I checked the code, and indeed there is a whitelist and others are rejected. So technically, he's correct: it's nowhere documented that sending e.g. search_path in StartupMessage parameters will work, and for that matter whether everything that you can set using SET you can also send there.

What is the proper behavior for a driver here:
 1. Whitelist parameters like libpq does, or
 2. Allow the user to send anything, with the understanding it'll work the same as SET

Thanks!
Jaka

Re: StartupMessage parameters - free-form or not?

From
Tom Lane
Date:
=?UTF-8?B?SmFrYSBKYW7EjWFy?= <jaka@kubje.org> writes:
> I wrote a Postgres client and in it I allow the user to specify arbitrary
> StartupMessage parameters (Map<string,string>). This is convenient because
> the user can for example set search_path without issuing a separate SET
> query or encoding things into the "options" parameter. The protocol
> documentation also says that the latter is deprecated and what I'm doing
> (if I understand it right) is preferred.

Sure.

> A fellow author of a driver for a different language reminds me that libpq
> explicitly enumerates the supported parameters in the docs, and I checked
> the code, and indeed there is a whitelist and others are rejected.

Not sure what you're looking at, but the issue for libpq is that the set
of "options" that it accepts in connection strings is independent of the
set of backend GUC names (and relatively few of them actually correspond
directly to backend GUCs, either).  I suppose we could make it pass
through unrecognized options, but that would be an unmaintainable mess,
because both sets of names are constantly evolving.

It's a bit of a hack that the backend accepts GUC names directly in
startup messages, but the set of "fixed" parameter names in that context
is very short and has barely changed in decades, so we haven't had
conflict problems.

> technically, he's correct: it's nowhere documented that sending e.g.
> search_path in StartupMessage parameters will work, and for that matter
> whether everything that you can set using SET you can also send there.

protocol.sgml saith (under Message Formats)

    In addition to the above, other parameters may be listed. Parameter
    names beginning with _pq_. are reserved for use as protocol
    extensions, while others are treated as run-time parameters to be set
    at backend start time. Such settings will be applied during backend
    start (after parsing the command-line arguments if any) and will act
    as session defaults.

Admittedly, that doesn't directly define what it means by "run-time
parameter", but what it means is any settable GUC.

            regards, tom lane



Re: StartupMessage parameters - free-form or not?

From
Jaka Jančar
Date:
Excellent, thanks!

On Sat, Jul 11, 2020 at 8:43 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Jaka Jančar <jaka@kubje.org> writes:
> I wrote a Postgres client and in it I allow the user to specify arbitrary
> StartupMessage parameters (Map<string,string>). This is convenient because
> the user can for example set search_path without issuing a separate SET
> query or encoding things into the "options" parameter. The protocol
> documentation also says that the latter is deprecated and what I'm doing
> (if I understand it right) is preferred.

Sure.

> A fellow author of a driver for a different language reminds me that libpq
> explicitly enumerates the supported parameters in the docs, and I checked
> the code, and indeed there is a whitelist and others are rejected.

Not sure what you're looking at, but the issue for libpq is that the set
of "options" that it accepts in connection strings is independent of the
set of backend GUC names (and relatively few of them actually correspond
directly to backend GUCs, either).  I suppose we could make it pass
through unrecognized options, but that would be an unmaintainable mess,
because both sets of names are constantly evolving.

It's a bit of a hack that the backend accepts GUC names directly in
startup messages, but the set of "fixed" parameter names in that context
is very short and has barely changed in decades, so we haven't had
conflict problems.

> technically, he's correct: it's nowhere documented that sending e.g.
> search_path in StartupMessage parameters will work, and for that matter
> whether everything that you can set using SET you can also send there.

protocol.sgml saith (under Message Formats)

    In addition to the above, other parameters may be listed. Parameter
    names beginning with _pq_. are reserved for use as protocol
    extensions, while others are treated as run-time parameters to be set
    at backend start time. Such settings will be applied during backend
    start (after parsing the command-line arguments if any) and will act
    as session defaults.

Admittedly, that doesn't directly define what it means by "run-time
parameter", but what it means is any settable GUC.

                        regards, tom lane