Re: proposal: psql: show current user in prompt

2024-01-29 Thread Pavel Stehule
po 29. 1. 2024 v 10:26 odesílatel Pavel Stehule 
napsal:

>
>
> ne 28. 1. 2024 v 22:52 odesílatel Jelte Fennema-Nio 
> napsal:
>
>> On Sun, 28 Jan 2024 at 20:01, Pavel Stehule 
>> wrote:
>> > There is another reason - compatibility with other drivers.  We
>> maintain just libpq, but there are JDBC, Npgsql, and some native Python
>> drivers. I didn't checked, but maybe they expect GUC with GUC_REPORT flag.
>>
>> This doesn't matter, because these drivers themselves would only stop
>> receiving certain GUC report messages if they changed this the
>> _pq_.report_paramers GUC. And at that point the other driver is
>> disabling the reporting on purpose. But like I said, I'm fine with
>> forcing the currently default GUC_REPORT GUCs to be GUC_REPORT always
>> (maybe excluding application_name).
>>
>
> ok
>
>
>>
>> > But now, I don't see any design without problems. Your look a little
>> bit fragile to me,
>>
>> Can you explain what still looks fragile to you about my design? Like
>> I explained at least from a proxy perspective this is the least
>> fragile imho, since it can reuse already existing and battle tested
>> code.
>>
>
> because there is not 100% isolation of different layers, there is one
> resource that can be modified by network layer (proxy) and by application
> layer (psql). Unfortunately, I don't see any better solution, how these
> layes separated.
>
>
>
>>
>> > From my perspective the situation can be better if I know so defaultly
>> reported GUC are fixed, and cannot be broken. Then for almost all clients
>> (without pgbouncer users), the CUSTOM_REPORT_GUC GUC will contain just
>> "role", and then the risk is minimal.
>>
>> Which risk are you talking about here?
>>
>
> The risk of not wanted reporting. I'll return to my psql prompt case. Who
> will disable reporting of "rule", when psql crashes? pgbouncer will call
> DISCARD ALL before reuse connection, but it ignores
> _pq_.report_parameters/';.>"
>
>
>
>>
>> > But still there are problems with handling of RESET ALL - so that means
>> I need to do a recheck of the local state every time, when I will show a
>> prompt with %N - that is not nice, but probably with a short list it will
>> not be a problem.
>>
>> I'm not entirely sure what you mean here. Is this still a problem if
>> RESET ALL is ignored for _pq_.report_parameters? If so, what problem
>> are you talking about then?
>>
>> > But I can imagine a client crash, and then pgbouncer executes RESET
>> ALL, and at this moment I would like to reset GUC_REPORT on "role" GUC.
>> Maybe the introduction of a new flag for DISCARD can solve it. But again
>> there can be a problem for which GUC the flag GUC_REPORT should be removed,
>> because there are not two independent lists.
>>
>> I don't think this is a problem. PgBouncer wouldn't rely on RESET ALL
>> to reset the state of _pq_.report_parameters. Before handing off the
>> old connection to a new client, PgBouncer would simply change the
>> _pq_.report_parameters GUC back to its default value by sending a
>> ParameterSet message. i.e. PgBouncer would use the same logic as it
>> currently uses to correctly reset tracked GUCs (application_name,
>> client_encoding, etc).
>>
>
> ok, this can work, and this is the reply to my previous query.
>

I marked my patch as withdrawn. I'll resend it when your patch
_pq_.report_parameters
will be committed.

Regards

Pavel

>
> Regards
>
> Pavel
>


Re: proposal: psql: show current user in prompt

2024-01-29 Thread Pavel Stehule
ne 28. 1. 2024 v 22:52 odesílatel Jelte Fennema-Nio 
napsal:

> On Sun, 28 Jan 2024 at 20:01, Pavel Stehule 
> wrote:
> > There is another reason - compatibility with other drivers.  We maintain
> just libpq, but there are JDBC, Npgsql, and some native Python drivers. I
> didn't checked, but maybe they expect GUC with GUC_REPORT flag.
>
> This doesn't matter, because these drivers themselves would only stop
> receiving certain GUC report messages if they changed this the
> _pq_.report_paramers GUC. And at that point the other driver is
> disabling the reporting on purpose. But like I said, I'm fine with
> forcing the currently default GUC_REPORT GUCs to be GUC_REPORT always
> (maybe excluding application_name).
>

ok


>
> > But now, I don't see any design without problems. Your look a little bit
> fragile to me,
>
> Can you explain what still looks fragile to you about my design? Like
> I explained at least from a proxy perspective this is the least
> fragile imho, since it can reuse already existing and battle tested
> code.
>

because there is not 100% isolation of different layers, there is one
resource that can be modified by network layer (proxy) and by application
layer (psql). Unfortunately, I don't see any better solution, how these
layes separated.



>
> > From my perspective the situation can be better if I know so defaultly
> reported GUC are fixed, and cannot be broken. Then for almost all clients
> (without pgbouncer users), the CUSTOM_REPORT_GUC GUC will contain just
> "role", and then the risk is minimal.
>
> Which risk are you talking about here?
>

The risk of not wanted reporting. I'll return to my psql prompt case. Who
will disable reporting of "rule", when psql crashes? pgbouncer will call
DISCARD ALL before reuse connection, but it ignores
_pq_.report_parameters/';.>"



>
> > But still there are problems with handling of RESET ALL - so that means
> I need to do a recheck of the local state every time, when I will show a
> prompt with %N - that is not nice, but probably with a short list it will
> not be a problem.
>
> I'm not entirely sure what you mean here. Is this still a problem if
> RESET ALL is ignored for _pq_.report_parameters? If so, what problem
> are you talking about then?
>
> > But I can imagine a client crash, and then pgbouncer executes RESET ALL,
> and at this moment I would like to reset GUC_REPORT on "role" GUC. Maybe
> the introduction of a new flag for DISCARD can solve it. But again there
> can be a problem for which GUC the flag GUC_REPORT should be removed,
> because there are not two independent lists.
>
> I don't think this is a problem. PgBouncer wouldn't rely on RESET ALL
> to reset the state of _pq_.report_parameters. Before handing off the
> old connection to a new client, PgBouncer would simply change the
> _pq_.report_parameters GUC back to its default value by sending a
> ParameterSet message. i.e. PgBouncer would use the same logic as it
> currently uses to correctly reset tracked GUCs (application_name,
> client_encoding, etc).
>

ok, this can work, and this is the reply to my previous query.

Regards

Pavel


Re: proposal: psql: show current user in prompt

2024-01-28 Thread Jelte Fennema-Nio
On Sun, 28 Jan 2024 at 20:01, Pavel Stehule  wrote:
> There is another reason - compatibility with other drivers.  We maintain just 
> libpq, but there are JDBC, Npgsql, and some native Python drivers. I didn't 
> checked, but maybe they expect GUC with GUC_REPORT flag.

This doesn't matter, because these drivers themselves would only stop
receiving certain GUC report messages if they changed this the
_pq_.report_paramers GUC. And at that point the other driver is
disabling the reporting on purpose. But like I said, I'm fine with
forcing the currently default GUC_REPORT GUCs to be GUC_REPORT always
(maybe excluding application_name).

> But now, I don't see any design without problems. Your look a little bit 
> fragile to me,

Can you explain what still looks fragile to you about my design? Like
I explained at least from a proxy perspective this is the least
fragile imho, since it can reuse already existing and battle tested
code.

> From my perspective the situation can be better if I know so defaultly 
> reported GUC are fixed, and cannot be broken. Then for almost all clients 
> (without pgbouncer users), the CUSTOM_REPORT_GUC GUC will contain just 
> "role", and then the risk is minimal.

Which risk are you talking about here?

> But still there are problems with handling of RESET ALL - so that means I 
> need to do a recheck of the local state every time, when I will show a prompt 
> with %N - that is not nice, but probably with a short list it will not be a 
> problem.

I'm not entirely sure what you mean here. Is this still a problem if
RESET ALL is ignored for _pq_.report_parameters? If so, what problem
are you talking about then?

> But I can imagine a client crash, and then pgbouncer executes RESET ALL, and 
> at this moment I would like to reset GUC_REPORT on "role" GUC. Maybe the 
> introduction of a new flag for DISCARD can solve it. But again there can be a 
> problem for which GUC the flag GUC_REPORT should be removed, because there 
> are not two independent lists.

I don't think this is a problem. PgBouncer wouldn't rely on RESET ALL
to reset the state of _pq_.report_parameters. Before handing off the
old connection to a new client, PgBouncer would simply change the
_pq_.report_parameters GUC back to its default value by sending a
ParameterSet message. i.e. PgBouncer would use the same logic as it
currently uses to correctly reset tracked GUCs (application_name,
client_encoding, etc).




Re: proposal: psql: show current user in prompt

2024-01-28 Thread Pavel Stehule
ne 28. 1. 2024 v 10:42 odesílatel Jelte Fennema-Nio 
napsal:

> On Sat, 27 Jan 2024 at 20:44, Pavel Stehule 
> wrote:
> > client_encoding, standard_conforming_strings, server_version,
> default_transaction_read_only, in_hot_standby and scram_iterations
> > are used by libpq directly, so it can be wrong to introduce the
> possibility to break it.
>
> libpq could add these ones automatically to the list, just like a
> proxy. But I think you are probably right and always reporting our
> current default set is probably easier.
>

There is another reason - compatibility with other drivers.  We maintain
just libpq, but there are JDBC, Npgsql, and some native Python drivers. I
didn't checked, but maybe they expect GUC with GUC_REPORT flag.


> >> Maybe I'm misunderstanding what you're saying, but it's not clear to
> >> me why you are seeing two different use cases here. To me if we have
> >> the ParameterSet message then they are both the same. When you enable
> >> %N you would send a ParamaterSet message for _pq_.report_parameters
> >> and set it to a list of gucs including "role". And when you disable %N
> >> you would set _pq_.report_parameters to a list of GUCs without "role".
> >> Then if any proxy still needed "role" even if the list it receives in
> >> _pq_.report_parameters doesn't contain it, then this proxy would
> >> simply prepend "role" to the list of GUCs before forwarding the
> >> ParameterSet message.
> >
> >
> > Your scenario can work but looks too fragile. I checked - GUC now cannot
> contain some special chars, so writing parser should not be hard work. But
> your proposal means the proxy should be smart about it, and have to check
> any change of _pq_.report_parameters, and this point can be fragile and a
> source of hardly searched bugs.
>
> Yes, proxies should be smart about it. But if there's new message
> types introduced specifically for this, then proxies need to be smart
> about it too. Because they would need to remember which reporting was
> requested by the client, to be able to correctly ask for reporting
> GUCs it after server connection . Using GUCs actually makes this
> easier to implement (and thus less error prone), because proxies
> already have logic to re-sync GUCs after connection assignment.
>
> I think this is probably one of the core reasons why I would very much
> prefer GUCs over new message types to configure protocol extensions
> like this: It means proxies would not to keep track of and re-sync a
> new kind of connection state every time a protocol extension is added.
> They can make their GUC tracking and re-syncing robust, and that's all
> they would need.
>

I am not against GUC based solutions. I think so for proxies it is probably
the best solution. But I just see only a GUC based solution not practical
for application.

Things are more complex when we try to think about possibility so
maintaining a list of reported GUC is more than one application. But now, I
don't see any design without problems. Your look a little bit fragile to
me, my proposal probably needs two independent lists of reported GUC, which
is not nice too. From my perspective the situation can be better if I know
so defaultly reported GUC are fixed, and cannot be broken. Then for almost
all clients (without pgbouncer users), the CUSTOM_REPORT_GUC GUC will
contain just "role", and then the risk is minimal. But still there are
problems with handling of RESET ALL - so that means I need to do a recheck
of the local state every time, when I will show a prompt with %N - that is
not nice, but probably with a short list it will not be a problem.



> > This is true, but how common is this situation? Probably every client
> that uses one proxy will use the same defaultly reported GUC.
>
> If you have different clients connecting to the same proxy, it seems
> quite likely that this will happen. This does not seem uncommon to me,
> e.g. actual application would need different things always reported
> than some dev client. Or clients for different languages might ask to
> report slightly different settings.
>
> > Reporting has no extra overhead. The notification is reduced. When there
> is a different set of reported GUC, then the proxy can try to find another
> connection with the same set or can reconnect.
>
> Honestly, this logic seems much more fragile to implement. And
> requiring reconnection seems problematic from a performance point of
> view.
>
> > I think so there is still opened question what should be correct
> behaviour when client execute RESET ALL or DISCARD ALL.  Without special
> protection the communication with proxy can be broken - and we use GUC for
> reported variables, then my case, prompt in psql will be broken too. Inside
> psql I have not callback on change of reported GUC. So this is reason why
> reporting based on mutable GUC is fragile :-/
>
> Specifically for this reason, the current patchset in the other thread
> already ignores RESET ALL and DISCARD ALL for protocol 

Re: proposal: psql: show current user in prompt

2024-01-28 Thread Jelte Fennema-Nio
On Sat, 27 Jan 2024 at 20:44, Pavel Stehule  wrote:
> client_encoding, standard_conforming_strings, server_version, 
> default_transaction_read_only, in_hot_standby and scram_iterations
> are used by libpq directly, so it can be wrong to introduce the possibility 
> to break it.

libpq could add these ones automatically to the list, just like a
proxy. But I think you are probably right and always reporting our
current default set is probably easier.

>> Maybe I'm misunderstanding what you're saying, but it's not clear to
>> me why you are seeing two different use cases here. To me if we have
>> the ParameterSet message then they are both the same. When you enable
>> %N you would send a ParamaterSet message for _pq_.report_parameters
>> and set it to a list of gucs including "role". And when you disable %N
>> you would set _pq_.report_parameters to a list of GUCs without "role".
>> Then if any proxy still needed "role" even if the list it receives in
>> _pq_.report_parameters doesn't contain it, then this proxy would
>> simply prepend "role" to the list of GUCs before forwarding the
>> ParameterSet message.
>
>
> Your scenario can work but looks too fragile. I checked - GUC now cannot 
> contain some special chars, so writing parser should not be hard work. But 
> your proposal means the proxy should be smart about it, and have to check any 
> change of _pq_.report_parameters, and this point can be fragile and a source 
> of hardly searched bugs.

Yes, proxies should be smart about it. But if there's new message
types introduced specifically for this, then proxies need to be smart
about it too. Because they would need to remember which reporting was
requested by the client, to be able to correctly ask for reporting
GUCs it after server connection . Using GUCs actually makes this
easier to implement (and thus less error prone), because proxies
already have logic to re-sync GUCs after connection assignment.

I think this is probably one of the core reasons why I would very much
prefer GUCs over new message types to configure protocol extensions
like this: It means proxies would not to keep track of and re-sync a
new kind of connection state every time a protocol extension is added.
They can make their GUC tracking and re-syncing robust, and that's all
they would need.

> This is true, but how common is this situation? Probably every client  that 
> uses one proxy will use the same defaultly reported GUC.

If you have different clients connecting to the same proxy, it seems
quite likely that this will happen. This does not seem uncommon to me,
e.g. actual application would need different things always reported
than some dev client. Or clients for different languages might ask to
report slightly different settings.

> Reporting has no extra overhead. The notification is reduced. When there is a 
> different set of reported GUC, then the proxy can try to find another 
> connection with the same set or can reconnect.

Honestly, this logic seems much more fragile to implement. And
requiring reconnection seems problematic from a performance point of
view.

> I think so there is still opened question what should be correct behaviour 
> when client execute RESET ALL or DISCARD ALL.  Without special protection the 
> communication with proxy can be broken - and we use GUC for reported 
> variables, then my case, prompt in psql will be broken too. Inside psql I 
> have not callback on change of reported GUC. So this is reason why reporting 
> based on mutable GUC is fragile :-/

Specifically for this reason, the current patchset in the other thread
already ignores RESET ALL and DISCARD ALL for protocol extension
parameters (including _pq_.report_parameters). So this would be a
non-issue.




Re: proposal: psql: show current user in prompt

2024-01-27 Thread Pavel Stehule
so 27. 1. 2024 v 10:24 odesílatel Jelte Fennema-Nio 
napsal:

> On Sat, 27 Jan 2024 at 08:35, Pavel Stehule 
> wrote:
> > Until now, it is not possible to disable reporting. So clients can
> expect so reporting is workable.
>
> Sure, so if we leave the default as is that's fine. It's not as if
> this GUC would be changed without the client knowing, the client would
> be the one changing the GUC and thus disabling the sending of
> reporting for the default GUCs. If it doesn't want to disable the
> reporting, than it simply should not send such a request.
>
> > Do you have a use case, when disabling some of the defaultly reported
> GUC makes sense?
>
> Mostly if the client doesn't actually use them, e.g. I expect many
> clients don't care what the current application_name is. But I do
> agree this is not a very strong usecase, so I'd be okay with always
> sending the ones that we sent as default for now. But that does make
> the implementation more difficult, since we'd have to special case
> these GUCs instead of having the same consistent behaviour for all
> GUCs.
>

client_encoding, standard_conforming_strings, server_version,
default_transaction_read_only, in_hot_standby
and scram_iterations
are used by libpq directly, so it can be wrong to introduce the possibility
to break it.



> > yes, inside gradual connect you can enhance the list of custom reported
> GUC easily.
> >
> > but for use cases like prompt in psql, I need to enable, disable
> reporting - but this use case should be independent of "protected"
> connection related GUC reporting.
> >
> > For example - when I disable %N, I can disable reporting "role" and
> disable showing role in prompt. But when "role" should be necessary for
> pgbouncer, then surely the disabling reporting should be ignored. The user
> by setting a prompt should not break communication.  And it can be ignored
> without any issue, there is not performance issue, because "role" is still
> necessary for pgbouncer that is used for connection. Without described
> behaviour we should not implement controlling reporting to psql, because
> there can be a lot of unhappy side effects in dependency if the user set or
> unset custom prompt or some other future feature.
>
> Maybe I'm misunderstanding what you're saying, but it's not clear to
> me why you are seeing two different use cases here. To me if we have
> the ParameterSet message then they are both the same. When you enable
> %N you would send a ParamaterSet message for _pq_.report_parameters
> and set it to a list of gucs including "role". And when you disable %N
> you would set _pq_.report_parameters to a list of GUCs without "role".
> Then if any proxy still needed "role" even if the list it receives in
> _pq_.report_parameters doesn't contain it, then this proxy would
> simply prepend "role" to the list of GUCs before forwarding the
> ParameterSet message.
>

Your scenario can work but looks too fragile. I checked - GUC now cannot
contain some special chars, so writing parser should not be hard work. But
your proposal means the proxy should be smart about it, and have to check
any change of _pq_.report_parameters, and this point can be fragile and a
source of hardly searched bugs.


>
> Also to be clear, having a "protected" connection-start only GUC is
> problematic for proxies. Because they need to update this setting
> while the connection is active when they hand of one server connection
> to another client.
>

This is true, but how common is this situation? Probably every client  that
uses one proxy will use the same defaultly reported GUC.  Reporting has no
extra overhead. The notification is reduced. When there is a different set
of reported GUC, then the proxy can try to find another connection with the
same set or can reconnect.  I think so there is still opened question what
should be correct behaviour when client execute RESET ALL or DISCARD ALL.
Without special protection the communication with proxy can be broken - and
we use GUC for reported variables, then my case, prompt in psql will be
broken too. Inside psql I have not callback on change of reported GUC. So
this is reason why reporting based on mutable GUC is fragile :-/

Pavel


Re: proposal: psql: show current user in prompt

2024-01-27 Thread Jelte Fennema-Nio
On Sat, 27 Jan 2024 at 08:35, Pavel Stehule  wrote:
> Until now, it is not possible to disable reporting. So clients can expect so 
> reporting is workable.

Sure, so if we leave the default as is that's fine. It's not as if
this GUC would be changed without the client knowing, the client would
be the one changing the GUC and thus disabling the sending of
reporting for the default GUCs. If it doesn't want to disable the
reporting, than it simply should not send such a request.

> Do you have a use case, when disabling some of the defaultly reported GUC 
> makes sense?

Mostly if the client doesn't actually use them, e.g. I expect many
clients don't care what the current application_name is. But I do
agree this is not a very strong usecase, so I'd be okay with always
sending the ones that we sent as default for now. But that does make
the implementation more difficult, since we'd have to special case
these GUCs instead of having the same consistent behaviour for all
GUCs.

> yes, inside gradual connect you can enhance the list of custom reported GUC 
> easily.
>
> but for use cases like prompt in psql, I need to enable, disable reporting - 
> but this use case should be independent of "protected" connection related GUC 
> reporting.
>
> For example - when I disable %N, I can disable reporting "role" and disable 
> showing role in prompt. But when "role" should be necessary for pgbouncer, 
> then surely the disabling reporting should be ignored. The user by setting a 
> prompt should not break communication.  And it can be ignored without any 
> issue, there is not performance issue, because "role" is still necessary for 
> pgbouncer that is used for connection. Without described behaviour we should 
> not implement controlling reporting to psql, because there can be a lot of 
> unhappy side effects in dependency if the user set or unset custom prompt or 
> some other future feature.

Maybe I'm misunderstanding what you're saying, but it's not clear to
me why you are seeing two different use cases here. To me if we have
the ParameterSet message then they are both the same. When you enable
%N you would send a ParamaterSet message for _pq_.report_parameters
and set it to a list of gucs including "role". And when you disable %N
you would set _pq_.report_parameters to a list of GUCs without "role".
Then if any proxy still needed "role" even if the list it receives in
_pq_.report_parameters doesn't contain it, then this proxy would
simply prepend "role" to the list of GUCs before forwarding the
ParameterSet message.

Also to be clear, having a "protected" connection-start only GUC is
problematic for proxies. Because they need to update this setting
while the connection is active when they hand of one server connection
to another client.




Re: proposal: psql: show current user in prompt

2024-01-26 Thread Pavel Stehule
so 27. 1. 2024 v 0:04 odesílatel Jelte Fennema-Nio 
napsal:

> On Fri, 26 Jan 2024 at 21:35, Pavel Stehule 
> wrote:
> > I see a possibility of disabling reporting as possibly dangerous.
> Without reporting encoding you can break psql. So it should be limited just
> to few values where is known behave.
>
> I agree that client_encoding is a GUC that likely all clients would
> want to request reporting for, so I can see the argument for always
> sending it. But I wouldn't call it dangerous for a client to be able
> to disable reporting for it. Ultimately the client is the one that
> decides. A client might just as well completely ignore the reported
> value.
>

Until now, it is not possible to disable reporting. So clients can expect
so reporting is workable.

Do you have a use case, when disabling some of the defaultly reported GUC
makes sense?

My patch doesn't protect these GUC, and now I think it is a mistake.


>
> >> While I agree it's a little bit less friendly, I think you're
> >> overestimating the difficulty of using my proposed approach. Most
> >> importantly there's no need to parse the current GUC value. A client
> >> always knows what variables it wants to have reported. So anytime that
> >> changes the client can simply regenerate the full list of gucs that it
> >> wants to report and send that. So something similar to the following
> >> pseudo code (using += for string concatenation):
> >
> >
> > I disagree with this - I can imagine some proxies add some own reported
> GUC and the client can know nothing about it.
>
> I've definitely thought about this case, since it's the main case I
> care about as maintainer of PgBouncer. And a client wouldn't need to
> know about the extra GUCs that the proxy requires for the proxy to
> work correctly. A proxy can quite simply handle this itself in the
> following manner: Whenever a client sends a ParameterSet for
> _pq_.report_parameters, the proxy could forward to the server after
> prepending its own extra GUCs at the front. The proxy wouldn't even
> need to parse the list from the client to be able to do that. An even
> better behaving proxy, should parse the list of GUCs though and would
> only forward the ParameterStatus messages that it receives from the
> server if the client requested ParameterStatus updates for them.
>

yes, inside gradual connect you can enhance the list of custom reported GUC
easily.

but for use cases like prompt in psql, I need to enable, disable reporting
- but this use case should be independent of "protected" connection related
GUC reporting.

For example - when I disable %N, I can disable reporting "role" and disable
showing role in prompt. But when "role" should be necessary for pgbouncer,
then surely the disabling reporting should be ignored. The user by setting
a prompt should not break communication.  And it can be ignored without any
issue, there is not performance issue, because "role" is still necessary
for pgbouncer that is used for connection. Without described behaviour we
should not implement controlling reporting to psql, because there can be a
lot of unhappy side effects in dependency if the user set or unset custom
prompt or some other future feature.


Re: proposal: psql: show current user in prompt

2024-01-26 Thread Jelte Fennema-Nio
On Fri, 26 Jan 2024 at 21:35, Pavel Stehule  wrote:
> I see a possibility of disabling reporting as possibly dangerous.  Without 
> reporting encoding you can break psql. So it should be limited just to few 
> values where is known behave.

I agree that client_encoding is a GUC that likely all clients would
want to request reporting for, so I can see the argument for always
sending it. But I wouldn't call it dangerous for a client to be able
to disable reporting for it. Ultimately the client is the one that
decides. A client might just as well completely ignore the reported
value.

>> While I agree it's a little bit less friendly, I think you're
>> overestimating the difficulty of using my proposed approach. Most
>> importantly there's no need to parse the current GUC value. A client
>> always knows what variables it wants to have reported. So anytime that
>> changes the client can simply regenerate the full list of gucs that it
>> wants to report and send that. So something similar to the following
>> pseudo code (using += for string concatenation):
>
>
> I disagree with this - I can imagine some proxies add some own reported GUC 
> and the client can know nothing about it.

I've definitely thought about this case, since it's the main case I
care about as maintainer of PgBouncer. And a client wouldn't need to
know about the extra GUCs that the proxy requires for the proxy to
work correctly. A proxy can quite simply handle this itself in the
following manner: Whenever a client sends a ParameterSet for
_pq_.report_parameters, the proxy could forward to the server after
prepending its own extra GUCs at the front. The proxy wouldn't even
need to parse the list from the client to be able to do that. An even
better behaving proxy, should parse the list of GUCs though and would
only forward the ParameterStatus messages that it receives from the
server if the client requested ParameterStatus updates for them.




Re: proposal: psql: show current user in prompt

2024-01-26 Thread Pavel Stehule
pá 26. 1. 2024 v 11:40 odesílatel Jelte Fennema-Nio 
napsal:

> On Thu, 25 Jan 2024 at 21:43, Pavel Stehule 
> wrote:
> > 2. using GUC for all reported GUC looks not too readable. Maybe it
> should be used just for customized reporting, not for default
>
> I thought about this too, because indeed the default list is quite
> long. But I decided against it because it seemed strange that you
> cannot disable reporting for the options that are currently reporting
> by default. Especially since the current default essentially boils
> down to: "whatever the psql client needed"
>

I see a possibility of disabling reporting as possibly dangerous.  Without
reporting encoding you can break psql. So it should be limited just to few
values where is known behave.


> > 3. Another issue of your proposal is less friendly enabling disabling
> reporting of specific GUC. Maintaining a list needs more work than just
> enabling and disabling one specific GUC.
> > I think this is the main disadvantage of your proposal. In my proposal I
> don't need to know the state of any GUC. Just I send PQlinkParameterStatus
> or PQunlinkParameterStatus. With your proposal, I need to read
> _pq_.report_parameters, parse it, and modify, and send it back. This
> doesn't look too practical.
>
> While I agree it's a little bit less friendly, I think you're
> overestimating the difficulty of using my proposed approach. Most
> importantly there's no need to parse the current GUC value. A client
> always knows what variables it wants to have reported. So anytime that
> changes the client can simply regenerate the full list of gucs that it
> wants to report and send that. So something similar to the following
> pseudo code (using += for string concatenation):
>

I disagree with this - I can imagine some proxies add some own reported GUC
and the client can know nothing about it.


>
> char *report_parameters = "server_version,client_encoding"
> if (show_user_in_prompt)
>report_parameters += ",user"
> if (show_search_path_in_prompt)
>report_parameters += ",search_path"
> PQsetParameter("_pq_.report_parameters", report_parameters)
>

It is simple only when default value of report_parameters is constant, but
when not it can be fragile


>
> > Personally I prefer usage of a more generic API than my
> PQlinkParameterStatus and PQunlinkParameterStatus. You talked about it with
> Robert If I remember.
> >
> > Can be nice if I can write just
> >
> > /* similar princip is used inside ncurses */
> > set_report_guc_message_no = PQgetMessageNo("set_report_guc");
> > /* the result can be processed by server and by all proxies on the line
> */
> >
> > if (set_report_guc_message_no == -1)
> >   fprintf(stderr, "feature is not supported");
> > result = PQsendMessage(set_report_guc_message, "user");
> > if (result == -1)
> >   fprintf(stderr, "some error ...");
> >
> > With some API like this it can be easier to do some small protocol
> enhancement. Maybe this is overengineering. Enhancing protocol is not too
> common, and with usage PQsendTypedCommand enhancing protocol is less work
> too.
>
> Honestly, I don't see a benefit to this over protocol extension
> parameters using the ParameterSet message. Afaict this is also
> essentially a key + value message type. And protocol extension
> parameters have the benefit that they are already an established thing
> in the protocol, and that they can easily be integrated with the
> current GUC system.
>

It was an idea.

Personally I like an idea that I described in mail to Peter. Using
dedicated connection related GUC for immutably reported GUC, and using
possibility to set dedicated function in protocol for enabling, disabling
other GUC. It looks (to me) like the most robust solution.

Regards

Pavel


Re: proposal: psql: show current user in prompt

2024-01-26 Thread Jelte Fennema-Nio
On Thu, 25 Jan 2024 at 21:43, Pavel Stehule  wrote:
> 2. using GUC for all reported GUC looks not too readable. Maybe it should be 
> used just for customized reporting, not for default

I thought about this too, because indeed the default list is quite
long. But I decided against it because it seemed strange that you
cannot disable reporting for the options that are currently reporting
by default. Especially since the current default essentially boils
down to: "whatever the psql client needed"

> 3. Another issue of your proposal is less friendly enabling disabling 
> reporting of specific GUC. Maintaining a list needs more work than just 
> enabling and disabling one specific GUC.
> I think this is the main disadvantage of your proposal. In my proposal I 
> don't need to know the state of any GUC. Just I send PQlinkParameterStatus or 
> PQunlinkParameterStatus. With your proposal, I need to read 
> _pq_.report_parameters, parse it, and modify, and send it back. This doesn't 
> look too practical.

While I agree it's a little bit less friendly, I think you're
overestimating the difficulty of using my proposed approach. Most
importantly there's no need to parse the current GUC value. A client
always knows what variables it wants to have reported. So anytime that
changes the client can simply regenerate the full list of gucs that it
wants to report and send that. So something similar to the following
pseudo code (using += for string concatenation):

char *report_parameters = "server_version,client_encoding"
if (show_user_in_prompt)
   report_parameters += ",user"
if (show_search_path_in_prompt)
   report_parameters += ",search_path"
PQsetParameter("_pq_.report_parameters", report_parameters)

> Personally I prefer usage of a more generic API than my PQlinkParameterStatus 
> and PQunlinkParameterStatus. You talked about it with Robert If I remember.
>
> Can be nice if I can write just
>
> /* similar princip is used inside ncurses */
> set_report_guc_message_no = PQgetMessageNo("set_report_guc");
> /* the result can be processed by server and by all proxies on the line */
>
> if (set_report_guc_message_no == -1)
>   fprintf(stderr, "feature is not supported");
> result = PQsendMessage(set_report_guc_message, "user");
> if (result == -1)
>   fprintf(stderr, "some error ...");
>
> With some API like this it can be easier to do some small protocol 
> enhancement. Maybe this is overengineering. Enhancing protocol is not too 
> common, and with usage PQsendTypedCommand enhancing protocol is less work too.

Honestly, I don't see a benefit to this over protocol extension
parameters using the ParameterSet message. Afaict this is also
essentially a key + value message type. And protocol extension
parameters have the benefit that they are already an established thing
in the protocol, and that they can easily be integrated with the
current GUC system.




Re: proposal: psql: show current user in prompt

2024-01-26 Thread Pavel Stehule
po 8. 1. 2024 v 6:08 odesílatel vignesh C  napsal:

> On Tue, 12 Sept 2023 at 14:39, Peter Eisentraut 
> wrote:
> >
> > On 11.09.23 13:59, Jelte Fennema wrote:
> > > @Tom and @Robert, since you originally suggested extending the
> > > protocol for this, I think some input from you on the protocol design
> > > would be quite helpful. BTW, this protocol extension is the main
> > > reason I personally care for this patch, because it would allow
> > > PgBouncer to ask for updates on certain GUCs so that it can preserve
> > > session level SET commands even in transaction pooling mode.
> > > Right now PgBouncer can only do this for a handful of GUCs, but
> > > there's quite a few others that are useful for PgBouncer to preserve
> > > by default:
> > > - search_path
> > > - statement_timeout
> > > - lock_timeout
> >
> > ISTM that for a purpose like pgbouncer, it would be simpler to add a new
> > GUC "report these variables" and send that in the startup message?  That
> > might not help with the psql use case, but it would be much simpler.
>
> I have changed the status to "Waiting on Author" as Peter's comments
> have not been followed up yet.
>

Please, see my reply to Peter. I think his comment is very valuable (and I
am for it), but I don't think it is a practical API for this feature.

Regards

Pavel



>
> Regards,
> Vignesh
>


Re: proposal: psql: show current user in prompt

2024-01-26 Thread Pavel Stehule
út 12. 9. 2023 v 9:46 odesílatel Peter Eisentraut 
napsal:

> On 11.09.23 13:59, Jelte Fennema wrote:
> > @Tom and @Robert, since you originally suggested extending the
> > protocol for this, I think some input from you on the protocol design
> > would be quite helpful. BTW, this protocol extension is the main
> > reason I personally care for this patch, because it would allow
> > PgBouncer to ask for updates on certain GUCs so that it can preserve
> > session level SET commands even in transaction pooling mode.
> > Right now PgBouncer can only do this for a handful of GUCs, but
> > there's quite a few others that are useful for PgBouncer to preserve
> > by default:
> > - search_path
> > - statement_timeout
> > - lock_timeout
>
> ISTM that for a purpose like pgbouncer, it would be simpler to add a new
> GUC "report these variables" and send that in the startup message?  That
> might not help with the psql use case, but it would be much simpler.
>

Introducing this GUC, mainly when the usage will be limited to connection
string, makes sense to me.  Unfortunately for usage in psql it is not
practical.

* For secure usage this GUC should be session immutable - probably you
don't want to disable reporting for search_path, ... inside session
* Enhancing list requires more work - reading current state, parsing
(theoretically the GUC "report these variables" can be marked as
GUC_REPORT, so I can see this value on client side, but still there is
parsing. I can imagine enhancing the SET command to style SET GUC += value
or SET GUC -= value
* SET statement is transactional - that means it cannot be used when a
transaction is broken, but it can be solved by some protocol based command
for setting GUC without dependency on state of transaction (if it is
possible, my functions changes just flag of some existing GUC, so there is
not necessary memory allocation, changing the value can be different story).

I can imagine both access - special GUC allowed only in connection string -
that can work as protection against unwanted remove of GUC_REPORT too, and
dedicated functions for enabling, disabling GUC_REPORT. It can very nicely
work together. Then we don't need any other changes. There is no necessity
for protocol SET, there is no necessity for more user friendly work with
lists in SET statements. And with connect settings for reporting, proxies
can easily detect and get the values of GUC.

Regards

Pavel


Re: proposal: psql: show current user in prompt

2024-01-25 Thread Pavel Stehule
Hi

čt 11. 1. 2024 v 12:12 odesílatel Jelte Fennema-Nio 
napsal:

> On Tue, 12 Sept 2023 at 09:46, Peter Eisentraut 
> wrote:
> > ISTM that for a purpose like pgbouncer, it would be simpler to add a new
> > GUC "report these variables" and send that in the startup message?  That
> > might not help with the psql use case, but it would be much simpler.
>
> FYI I implemented it that way yesterday on this other thread (patch
> 0010 of that patchset):
>
> https://www.postgresql.org/message-id/flat/CAGECzQScQ3N-Ykv2j4NDyDtrPPc3FpRoa%3DLZ-2Uj2ocA4zr%3D4Q%40mail.gmail.com#cd9e8407820d492e8f677ee6a67c21ce


I read your patch, and I see some advantages and some disadvantages.

1. this doesn't need new protocol API just for this feature, what is nice

2. using GUC for all reported GUC looks not too readable. Maybe it should
be used just for customized reporting, not for default

3. Another issue of your proposal is less friendly enabling disabling
reporting of specific GUC. Maintaining a list needs more work than just
enabling and disabling one specific GUC.
I think this is the main disadvantage of your proposal. In my proposal I
don't need to know the state of any GUC. Just I send PQlinkParameterStatus
or PQunlinkParameterStatus. With your proposal, I need to read
_pq_.report_parameters, parse it, and modify, and send it back. This
doesn't look too practical.

Personally I prefer usage of a more generic API than my
PQlinkParameterStatus and PQunlinkParameterStatus. You talked about it with
Robert If I remember.

Can be nice if I can write just

/* similar princip is used inside ncurses */
set_report_guc_message_no = PQgetMessageNo("set_report_guc");
/* the result can be processed by server and by all proxies on the line */

if (set_report_guc_message_no == -1)
  fprintf(stderr, "feature is not supported");
result = PQsendMessage(set_report_guc_message, "user");
if (result == -1)
  fprintf(stderr, "some error ...");

With some API like this it can be easier to do some small protocol
enhancement. Maybe this is overengineering. Enhancing protocol is not too
common, and with usage PQsendTypedCommand enhancing protocol is less work
too.

Regards

Pavel


Re: proposal: psql: show current user in prompt

2024-01-21 Thread Pavel Stehule
Hi

I starting work on this patch - start with rebase

Regards

Pavel
From c7bbdd67898b397143fa314152f32d5ca935c082 Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Sun, 21 Jan 2024 14:23:06 +0100
Subject: [PATCH 1/4] Protocol ReportGUC message

This patch implements dynamic reporting changes of GUC to client side.

The flags per GUC can be changed by functions SetGUCOptionFlag and UsetGUCOptionFlag.
---
 doc/src/sgml/protocol.sgml  | 44 +
 src/backend/tcop/postgres.c | 33 ++
 src/backend/utils/misc/guc.c| 31 
 src/include/libpq/protocol.h|  1 +
 src/include/utils/guc.h |  2 ++
 src/interfaces/libpq/exports.txt|  2 ++
 src/interfaces/libpq/fe-exec.c  | 36 ++-
 src/interfaces/libpq/fe-protocol3.c |  1 -
 src/interfaces/libpq/fe-trace.c | 12 
 src/interfaces/libpq/libpq-fe.h |  3 ++
 src/interfaces/libpq/libpq-int.h|  4 ++-
 11 files changed, 166 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index 6c3e8a631d..990eefc8b5 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -1030,6 +1030,13 @@ SELCT 1/0;
  CloseComplete, or NoData messages.
 

+
+   
+The ReportGUC message allows to set/unset REPORT flag to any configuration
+variable. The response is a CommandComplete message (status string is SET
+or UNSET). An error causes ErrorResponse. When the REPORT flag is succesfully
+assigned, then ParameterStatus message is sent before CommandComplete message.
+   
   
 
   
@@ -5506,6 +5513,43 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
 

 
+   
+ReportGUC (F)
+
+ 
+  
+   Byte1('r')
+   
+
+ Identifies the message type.  ReportGUC is sent by
+ frontend when the changes of specified GUC option
+ should be (or should not be) reported to state parameter.
+
+   
+  
+
+  
+   Byte1
+   
+
+ 't' when reporting should be enables, 'f' if reporting should be
+ disabled.
+
+   
+  
+
+  
+   String
+   
+
+ The name of GUC option.
+
+   
+  
+ 
+
+   
+

 RowDescription (B)
 
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 1a34bd3715..57ea37410b 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -427,6 +427,7 @@ SocketBackend(StringInfo inBuf)
 		case PqMsg_Describe:
 		case PqMsg_Execute:
 		case PqMsg_Flush:
+		case PqMsg_ReportGUC:
 			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
 			doing_extended_query_message = true;
 			break;
@@ -4851,6 +4852,38 @@ PostgresMain(const char *dbname, const char *username)
 send_ready_for_query = true;
 break;
 
+			case PqMsg_ReportGUC:
+{
+	const char	   *name;
+	const char	   *status;
+	intis_set;
+
+	is_set = pq_getmsgbyte(_message);
+	name = pq_getmsgstring(_message);
+	pq_getmsgend(_message);
+
+	if (is_set == 't')
+	{
+		SetGUCOptionFlag(name, GUC_REPORT);
+		status = "SET";
+	}
+	else if (is_set == 'f')
+	{
+		UnsetGUCOptionFlag(name, GUC_REPORT);
+		status = "UNSET";
+	}
+	else
+		ereport(ERROR,
+(errcode(ERRCODE_PROTOCOL_VIOLATION),
+ errmsg("invalid argument of REPORTGUC message %c",
+		is_set)));
+
+	pq_puttextmessage(PqMsg_CommandComplete, status);
+
+	valgrind_report_error_query("ReportGUC message");
+}
+break;
+
 /*
  * 'X' means that the frontend is closing down the socket. EOF
  * means unexpected loss of frontend connection. Either way,
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8f65ef3d89..f6888269b6 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2562,6 +2562,37 @@ BeginReportingGUCOptions(void)
 	}
 }
 
+/*
+ * Allow to set / unset dynamicaly flags to GUC variables
+ */
+void
+SetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, false, ERROR);
+	conf->flags |= flag;
+
+	if (flag == GUC_REPORT)
+		/* force transmit value of related option to client Parameter Status */
+		ReportGUCOption(conf);
+}
+
+void
+UnsetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, false, ERROR);
+	conf->flags &= ~flag;
+}
+
 /*
  * ReportChangedGUCOptions: report recently-changed GUC_REPORT variables
  *
diff --git a/src/include/libpq/protocol.h b/src/include/libpq/protocol.h
index 4b8d440365..abcfbf2bb5 100644
--- a/src/include/libpq/protocol.h
+++ 

Re: proposal: psql: show current user in prompt

2024-01-11 Thread Jelte Fennema-Nio
On Tue, 12 Sept 2023 at 09:46, Peter Eisentraut  wrote:
> ISTM that for a purpose like pgbouncer, it would be simpler to add a new
> GUC "report these variables" and send that in the startup message?  That
> might not help with the psql use case, but it would be much simpler.

FYI I implemented it that way yesterday on this other thread (patch
0010 of that patchset):
https://www.postgresql.org/message-id/flat/CAGECzQScQ3N-Ykv2j4NDyDtrPPc3FpRoa%3DLZ-2Uj2ocA4zr%3D4Q%40mail.gmail.com#cd9e8407820d492e8f677ee6a67c21ce




Re: proposal: psql: show current user in prompt

2024-01-07 Thread vignesh C
On Tue, 12 Sept 2023 at 14:39, Peter Eisentraut  wrote:
>
> On 11.09.23 13:59, Jelte Fennema wrote:
> > @Tom and @Robert, since you originally suggested extending the
> > protocol for this, I think some input from you on the protocol design
> > would be quite helpful. BTW, this protocol extension is the main
> > reason I personally care for this patch, because it would allow
> > PgBouncer to ask for updates on certain GUCs so that it can preserve
> > session level SET commands even in transaction pooling mode.
> > Right now PgBouncer can only do this for a handful of GUCs, but
> > there's quite a few others that are useful for PgBouncer to preserve
> > by default:
> > - search_path
> > - statement_timeout
> > - lock_timeout
>
> ISTM that for a purpose like pgbouncer, it would be simpler to add a new
> GUC "report these variables" and send that in the startup message?  That
> might not help with the psql use case, but it would be much simpler.

I have changed the status to "Waiting on Author" as Peter's comments
have not been followed up yet.

Regards,
Vignesh




Re: proposal: psql: show current user in prompt

2023-09-12 Thread Peter Eisentraut

On 11.09.23 13:59, Jelte Fennema wrote:

@Tom and @Robert, since you originally suggested extending the
protocol for this, I think some input from you on the protocol design
would be quite helpful. BTW, this protocol extension is the main
reason I personally care for this patch, because it would allow
PgBouncer to ask for updates on certain GUCs so that it can preserve
session level SET commands even in transaction pooling mode.
Right now PgBouncer can only do this for a handful of GUCs, but
there's quite a few others that are useful for PgBouncer to preserve
by default:
- search_path
- statement_timeout
- lock_timeout


ISTM that for a purpose like pgbouncer, it would be simpler to add a new 
GUC "report these variables" and send that in the startup message?  That 
might not help with the psql use case, but it would be much simpler.





Re: proposal: psql: show current user in prompt

2023-09-11 Thread Pavel Stehule
po 11. 9. 2023 v 13:24 odesílatel Jelte Fennema  napsal:

> On Fri, 8 Sept 2023 at 21:08, Pavel Stehule 
> wrote:
> > ok changed - there is minor problem - almost all PQ functions are of int
> type, but ProtocolVersion is uint
>
> Your current implementation requires using the PG_PROTOCOL macros to
> compare versions. But clients cannot currently use those macros since
> they are not exported from libpq-fe.h, only from pqcomm.h which is
> then imported by libpq-int.h. (psql/command.c imports pcomm.h
> directly, but I don't think we should expect clients to do that). We
> could ofcourse export these macros from libpq-fe.h too. But then we'd
> need to document those macros too.
>
> > Using different mapping to int can be problematic - can be messy if we
> cannot use PG_PROTOCOL macro.
>
> I see no big problems returning an unsigned or long from the new
> function (even if existing functions all returned int). But I don't
> even think that is necessary. Returning the following as an int from
> PQprotocolVersionFull would work fine afaict:
>
> return PG_PROTOCOL_MAJOR(version) * 1000 + PG_PROTOCOL_MINOR(version)
>
> This would give us one thousand minor versions for each major version.
> This seems fine for all practical purposes. Since postgres only
> releases a version once every year, we'd need a protocol bump every
> year for one thousand years for that to ever cause any problems. So
> I'd prefer this approach over making the PG_PROTOCOL macros a public
> interface.
>

I did proposed change

Regards

Pavel
From 2f432cbb6d38569759e12a2cbe80ec9dce4b2f25 Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Mon, 24 Jul 2023 20:18:16 +0200
Subject: [PATCH 4/4] Implementation of %N prompt placeholder

It is based on forcing reporting feature"role" GUC to client.
---
 doc/src/sgml/ref/psql-ref.sgml | 19 ++-
 src/bin/psql/command.c | 13 +
 src/bin/psql/prompt.c  | 27 +++
 src/bin/psql/settings.h|  1 +
 src/bin/psql/startup.c | 32 
 5 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index d94e3cacfc..8b267a6da6 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4568,7 +4568,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index bcd8eb3538..bad0fdf415 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3883,6 +3883,7 @@ SyncVariables(void)
 {
 	char		vbuf[32];
 	const char *server_version;
+	PGresult   *result;
 
 	/* get stuff from connection */
 	pset.encoding = PQclientEncoding(pset.db);
@@ -3912,6 +3913,18 @@ SyncVariables(void)
 	/* send stuff to it, too */
 	PQsetErrorVerbosity(pset.db, pset.verbosity);
 	PQsetErrorContextVisibility(pset.db, pset.show_context);
+
+	/* link role GUC when it is needed for prompt */
+	if (pset.prompt_shows_role)
+		result = PQlinkParameterStatus(pset.db, "role");
+	else
+		result = PQunlinkParameterStatus(pset.db, "role");
+
+	if (PQresultStatus(result) != PGRES_COMMAND_OK)
+		pg_log_info("cannot set REPORT flag on configuration variable \"role\": %s",
+	PQerrorMessage(pset.db));
+
+	PQclear(result);
 }
 
 /*
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..566b47d814 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,33 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+		const char *rolename = NULL;
+
+		/*
+		 * This feature requires GUC "role" to be marked
+		 * by GUC_REPORT flag. This is done by PQlinkParameterStatus
+		 * function. This function requires protocol 3.1 (ReportGUC
+		 * message). Fallback is empty string.
+		 */
+		if (PQprotocolVersionFull(pset.db) >= PQmakeProtocolVersionFull(3,1))
+		{
+			rolename  = PQparameterStatus(pset.db, "role");
+
+			/* fallback when role is not set yet */
+			if (rolename && strcmp(rolename, "none") == 0)
+rolename = session_username();
+		}
+
+		if (rolename)
+			strlcpy(buf, rolename, sizeof(buf));
+		else
+			buf[0] = '\0';
+	}
+	break;
 	/* backend pid 

Re: proposal: psql: show current user in prompt

2023-09-11 Thread Jelte Fennema
On Mon, 11 Sept 2023 at 13:59, Jelte Fennema  wrote:
> I think that would make the client code even simpler than it is now.

To be clear, I'm not saying we should do this. There's benefits to
using a dedicated new message type too (e.g. clearer errors if a proxy
like pgbouncer does not understand it).




Re: proposal: psql: show current user in prompt

2023-09-11 Thread Jelte Fennema
@Tom and @Robert, since you originally suggested extending the
protocol for this, I think some input from you on the protocol design
would be quite helpful. BTW, this protocol extension is the main
reason I personally care for this patch, because it would allow
PgBouncer to ask for updates on certain GUCs so that it can preserve
session level SET commands even in transaction pooling mode.
Right now PgBouncer can only do this for a handful of GUCs, but
there's quite a few others that are useful for PgBouncer to preserve
by default:
- search_path
- statement_timeout
- lock_timeout

And users might have others that they want to preserve others too.

On Fri, 8 Sept 2023 at 21:08, Pavel Stehule  wrote:
>> I think we'll need some bikeshedding on what the protocol message
>> should look like exactly. I'm not entirely sure what is the most
>> sensible here, so please treat everything I write next as
>> suggestions/discussion:
>> I see that you're piggy-backing on PQsendTypedCommand, which seems
>> nice to avoid code duplication. It has one downside though: not every
>> type, is valid for each command anymore.
>> One way to avoid that would be to not introduce a new command, but
>> only add a new type that is understood by Describe and Close, e.g. a
>> 'G' (for GUC). Then PqMsg_Describe, G would become the equivalent of
>> what'the current patch its PqMsg_ReportGUC, 't' and PqMsg_Close, G
>> would be the same as PqMsg_ReportGUC, 'f'.
>
>
> I am sorry, I don't understand this idea?

To clarify what I meant: I meant instead of introducing a new top
level message type (i.e. your newly introduced ReportGUC message), I
suggested adding a new subtype that is understood by the Describe and
Close messages. In addition to being able to use Describe and Close
for statements and portals with the S and P subtypes respectively,
like you currently can, we could add a new subtype G which would start
and stop GUC reporting (with the Describe and Close message
respectively). I think that would make the client code even simpler than
it is now.




Re: proposal: psql: show current user in prompt

2023-09-11 Thread Jelte Fennema
On Fri, 8 Sept 2023 at 21:08, Pavel Stehule  wrote:
> ok changed - there is minor problem - almost all PQ functions are of int 
> type, but ProtocolVersion is uint

Your current implementation requires using the PG_PROTOCOL macros to
compare versions. But clients cannot currently use those macros since
they are not exported from libpq-fe.h, only from pqcomm.h which is
then imported by libpq-int.h. (psql/command.c imports pcomm.h
directly, but I don't think we should expect clients to do that). We
could ofcourse export these macros from libpq-fe.h too. But then we'd
need to document those macros too.

> Using different mapping to int can be problematic - can be messy if we cannot 
> use PG_PROTOCOL macro.

I see no big problems returning an unsigned or long from the new
function (even if existing functions all returned int). But I don't
even think that is necessary. Returning the following as an int from
PQprotocolVersionFull would work fine afaict:

return PG_PROTOCOL_MAJOR(version) * 1000 + PG_PROTOCOL_MINOR(version)

This would give us one thousand minor versions for each major version.
This seems fine for all practical purposes. Since postgres only
releases a version once every year, we'd need a protocol bump every
year for one thousand years for that to ever cause any problems. So
I'd prefer this approach over making the PG_PROTOCOL macros a public
interface.




Re: proposal: psql: show current user in prompt

2023-09-10 Thread Pavel Stehule
pá 8. 9. 2023 v 21:07 odesílatel Pavel Stehule 
napsal:

> Hi
>
> Another thing that should be described there is that this falls
>> outside of the transaction flow, i.e. it's changes are not reverted on
>> ROLLBACK. But that leaves an important consideration: What happens
>> when an error occurs on the server during handling of this message
>> (e.g. the GUC does not exist or an OOM is triggered). Is any open
>> transaction aborted in that case? If not, we should have a test for
>> that.
>>
>
> I tested this scenario. I had to modify message handling to fix warning
> "message type 0x5a arrived from server while idle"
>

I fixed this issue. The problem was in the missing setting
`doing_extended_query_message`.


> But if this is inside a transaction, the transaction is aborted.
>
>>
>> +   if (PQresultStatus(res) != PGRES_COMMAND_OK)
>> +   pg_fatal("failed to link custom variable: %s",
>> PQerrorMessage(conn));
>> +   PQclear(res);
>>
>
> done
>
>
>>
>> The tests should also change the config after running
>> PQlinkParameterStatus/PQunlinkParameterStatus to show that the guc is
>> reported then or not reported then.
>>
>
> done
>
>
>>
>> +   if (!PQsendTypedCommand(conn, PqMsg_ReportGUC, 't', paramName))
>> +   return NULL;
>>
>>
>> I think we'll need some bikeshedding on what the protocol message
>> should look like exactly. I'm not entirely sure what is the most
>> sensible here, so please treat everything I write next as
>> suggestions/discussion:
>> I see that you're piggy-backing on PQsendTypedCommand, which seems
>> nice to avoid code duplication. It has one downside though: not every
>> type, is valid for each command anymore.
>> One way to avoid that would be to not introduce a new command, but
>> only add a new type that is understood by Describe and Close, e.g. a
>> 'G' (for GUC). Then PqMsg_Describe, G would become the equivalent of
>> what'the current patch its PqMsg_ReportGUC, 't' and PqMsg_Close, G
>> would be the same as PqMsg_ReportGUC, 'f'.
>>
>
> I am sorry, I don't understand this idea?
>
>
>>
>> The rest of this email assumes that we're keeping your current
>> proposal for the protocol message, so it might not make sense to
>> address all of this feedback, in case we're still going to change the
>> protocol:
>>
>> +   if (is_set == 't')
>> +   {
>> +   SetGUCOptionFlag(name, GUC_REPORT);
>> +   status = "SET REPORT_GUC";
>> +   }
>> +   else
>> +   {
>> +   UnsetGUCOptionFlag(name, GUC_REPORT);
>> +   status = "UNSET REPORT_GUC";
>> +   }
>>
>> I think we should be strict about what we accept here. Any other value
>> than 'f'/'t' for is_set should result in an error imho.
>>
>
> done
>

Regards

Pavel


>
>
From 4a7c8b30f297189f6801076556a984baa51daa4f Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Sun, 3 Sep 2023 19:14:24 +0200
Subject: [PATCH 3/4] - allow to connect to server with major protocol version
 3, minor version is ignored

- allow to read minor protocol version
---
 doc/src/sgml/libpq.sgml | 17 +
 src/include/libpq/pqcomm.h  |  2 +-
 src/interfaces/libpq/exports.txt|  1 +
 src/interfaces/libpq/fe-connect.c   | 12 +++-
 src/interfaces/libpq/fe-protocol3.c | 21 +
 src/interfaces/libpq/libpq-fe.h |  1 +
 6 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index a52baa27d5..d9e5502d09 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -2576,6 +2576,23 @@ int PQprotocolVersion(const PGconn *conn);
  
 
 
+
+ PQprotocolVersionFullPQprotocolVersionFull
+
+ 
+  
+   Returns complete frontend/backend protocol number.
+
+int PQprotocolVersionFull(const PGconn *conn);
+
+   The frontend/backend version protocol number is an value, that composites.
+   major protocol number and minor protocol number. These numbers can be
+   separated by using macros PG_PROTOCOL_MAJOR and
+   PG_PROTOCOL_MINOR.
+  
+ 
+
+
 
  PQserverVersionPQserverVersion
 
diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 46a0946b8b..4ea4538157 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -94,7 +94,7 @@ is_unixsock_path(const char *path)
  */
 
 #define PG_PROTOCOL_EARLIEST	PG_PROTOCOL(3,0)
-#define PG_PROTOCOL_LATEST		PG_PROTOCOL(3,0)
+#define PG_PROTOCOL_LATEST		PG_PROTOCOL(3,1)
 
 typedef uint32 ProtocolVersion; /* FE/BE protocol version number */
 
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index 7e101368d5..595a4808f2 100644
--- a/src/interfaces/libpq/exports.txt
+++ b/src/interfaces/libpq/exports.txt
@@ -193,3 +193,4 @@ PQsendClosePrepared   190
 PQsendClosePortal 191
 PQlinkParameterStatus 192
 

Re: proposal: psql: show current user in prompt

2023-09-08 Thread Pavel Stehule
Hi

Another thing that should be described there is that this falls
> outside of the transaction flow, i.e. it's changes are not reverted on
> ROLLBACK. But that leaves an important consideration: What happens
> when an error occurs on the server during handling of this message
> (e.g. the GUC does not exist or an OOM is triggered). Is any open
> transaction aborted in that case? If not, we should have a test for
> that.
>

I tested this scenario. I had to modify message handling to fix warning
"message type 0x5a arrived from server while idle"

But if this is inside a transaction, the transaction is aborted.

>
> +   if (PQresultStatus(res) != PGRES_COMMAND_OK)
> +   pg_fatal("failed to link custom variable: %s",
> PQerrorMessage(conn));
> +   PQclear(res);
>

done


>
> The tests should also change the config after running
> PQlinkParameterStatus/PQunlinkParameterStatus to show that the guc is
> reported then or not reported then.
>

done


>
> +   if (!PQsendTypedCommand(conn, PqMsg_ReportGUC, 't', paramName))
> +   return NULL;
>
>
> I think we'll need some bikeshedding on what the protocol message
> should look like exactly. I'm not entirely sure what is the most
> sensible here, so please treat everything I write next as
> suggestions/discussion:
> I see that you're piggy-backing on PQsendTypedCommand, which seems
> nice to avoid code duplication. It has one downside though: not every
> type, is valid for each command anymore.
> One way to avoid that would be to not introduce a new command, but
> only add a new type that is understood by Describe and Close, e.g. a
> 'G' (for GUC). Then PqMsg_Describe, G would become the equivalent of
> what'the current patch its PqMsg_ReportGUC, 't' and PqMsg_Close, G
> would be the same as PqMsg_ReportGUC, 'f'.
>

I am sorry, I don't understand this idea?


>
> The rest of this email assumes that we're keeping your current
> proposal for the protocol message, so it might not make sense to
> address all of this feedback, in case we're still going to change the
> protocol:
>
> +   if (is_set == 't')
> +   {
> +   SetGUCOptionFlag(name, GUC_REPORT);
> +   status = "SET REPORT_GUC";
> +   }
> +   else
> +   {
> +   UnsetGUCOptionFlag(name, GUC_REPORT);
> +   status = "UNSET REPORT_GUC";
> +   }
>
> I think we should be strict about what we accept here. Any other value
> than 'f'/'t' for is_set should result in an error imho.
>

done


Re: proposal: psql: show current user in prompt

2023-09-08 Thread Pavel Stehule
út 5. 9. 2023 v 13:29 odesílatel Jelte Fennema  napsal:

> On Tue, 5 Sept 2023 at 05:50, Pavel Stehule 
> wrote:
>
> > I prefer to introduce a new function - it is ten lines of code. The form
> is not important - it can be a full number or minor number. It doesn't
> matter I think. But my opinion in this area is not strong, and I like to
> see feedback from others too. It is true that this feature and interface is
> not fully complete.
>
> I think when using the API it is nicest to have a single function that
> returns the full version number. i.e. if we're introducing a new
> function I think it should be PQprotocolFullVersion instead of
> PQprotocolSubversion. Then instead of doing a version check like this:
>
> if (PQprotocolVersion(pset.db) == 3 && PQprotocolSubversion(pset.db) >= 1)
>
> You can do the simpler:
>
> if (PQprotocolFullVersion(pset.db) >= 301)
>
> This is also in line with how you do version checks for postgres versions.
>
> So I think this patch should at least add that one instead of
> PQprotocolSubversion. If we then decide to replace PQprotocolVersion
> with this new implementation, that would be a trivial change.
>

ok changed - there is minor problem - almost all PQ functions are of int
type, but ProtocolVersion is uint

Using different mapping to int can be problematic - can be messy if we
cannot to use PG_PROTOCOL macro.


> >> +   /* The protocol 3.0 is required */
> >> +   if (PG_PROTOCOL_MAJOR(their_version) == 3)
> >> +   conn->pversion = their_version;
> >>
> >> Let's compare against the actual PG_PROTOCOL_EARLIEST and
> >> PG_PROTOCOL_LATEST to determine if the version is supported or not.
> >
> >
> > changed
>
> I think we should also check the minor version part. So like this instead
> +   if (their_version < PG_PROTOCOL_EARLIEST || their_version >
> PG_PROTOCOL_LATEST)
>
>
done

Regards

Pavel


>
> PS. If you use the -v flag of git format-patch a version number is
> prepended to your patches. That makes it easier to reference them.
>
From a43a620d0ab8dfa01d82baf5c1752a2ba3bb8666 Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Mon, 24 Jul 2023 20:18:16 +0200
Subject: [PATCH 4/4] Implementation of %N prompt placeholder

It is based on forcing reporting feature"role" GUC to client.
---
 doc/src/sgml/ref/psql-ref.sgml | 19 ++-
 src/bin/psql/command.c | 13 +
 src/bin/psql/prompt.c  | 27 +++
 src/bin/psql/settings.h|  1 +
 src/bin/psql/startup.c | 32 
 5 files changed, 91 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index d94e3cacfc..8b267a6da6 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4568,7 +4568,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index bcd8eb3538..bad0fdf415 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3883,6 +3883,7 @@ SyncVariables(void)
 {
 	char		vbuf[32];
 	const char *server_version;
+	PGresult   *result;
 
 	/* get stuff from connection */
 	pset.encoding = PQclientEncoding(pset.db);
@@ -3912,6 +3913,18 @@ SyncVariables(void)
 	/* send stuff to it, too */
 	PQsetErrorVerbosity(pset.db, pset.verbosity);
 	PQsetErrorContextVisibility(pset.db, pset.show_context);
+
+	/* link role GUC when it is needed for prompt */
+	if (pset.prompt_shows_role)
+		result = PQlinkParameterStatus(pset.db, "role");
+	else
+		result = PQunlinkParameterStatus(pset.db, "role");
+
+	if (PQresultStatus(result) != PGRES_COMMAND_OK)
+		pg_log_info("cannot set REPORT flag on configuration variable \"role\": %s",
+	PQerrorMessage(pset.db));
+
+	PQclear(result);
 }
 
 /*
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..c1bc81c8dd 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,33 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+		const char *rolename = NULL;
+
+		/*
+		 * This feature requires GUC "role" to be marked
+		 * by GUC_REPORT flag. This is done by PQlinkParameterStatus
+		 * function. This function requires protocol 3.1 (ReportGUC
+		

Re: proposal: psql: show current user in prompt

2023-09-05 Thread Jelte Fennema
On Tue, 5 Sept 2023 at 05:50, Pavel Stehule  wrote:

> I prefer to introduce a new function - it is ten lines of code. The form is 
> not important - it can be a full number or minor number. It doesn't matter I 
> think. But my opinion in this area is not strong, and I like to see feedback 
> from others too. It is true that this feature and interface is not fully 
> complete.

I think when using the API it is nicest to have a single function that
returns the full version number. i.e. if we're introducing a new
function I think it should be PQprotocolFullVersion instead of
PQprotocolSubversion. Then instead of doing a version check like this:

if (PQprotocolVersion(pset.db) == 3 && PQprotocolSubversion(pset.db) >= 1)

You can do the simpler:

if (PQprotocolFullVersion(pset.db) >= 301)

This is also in line with how you do version checks for postgres versions.

So I think this patch should at least add that one instead of
PQprotocolSubversion. If we then decide to replace PQprotocolVersion
with this new implementation, that would be a trivial change.

>> +   /* The protocol 3.0 is required */
>> +   if (PG_PROTOCOL_MAJOR(their_version) == 3)
>> +   conn->pversion = their_version;
>>
>> Let's compare against the actual PG_PROTOCOL_EARLIEST and
>> PG_PROTOCOL_LATEST to determine if the version is supported or not.
>
>
> changed

I think we should also check the minor version part. So like this instead
+   if (their_version < PG_PROTOCOL_EARLIEST || their_version >
PG_PROTOCOL_LATEST)


PS. If you use the -v flag of git format-patch a version number is
prepended to your patches. That makes it easier to reference them.




Re: proposal: psql: show current user in prompt

2023-09-04 Thread Pavel Stehule
po 4. 9. 2023 v 14:24 odesílatel Jelte Fennema  napsal:

> On Sun, 3 Sept 2023 at 20:58, Pavel Stehule 
> wrote:
> > here is an try
>
> Overall it does what I had in mind. Below a few suggestions:
>
> +int
> +PQprotocolSubversion(const PGconn *conn)
>
> Ugh, it's quite annoying that the original PQprotocolVersion only
> returns the major version and thus we need this new function. It
> seems like it would be much nicer if it returned a number similar to
> PQserverVersion. I think it might be nicer to change PQprotocolVersion
> to do that than to add another function. We could do:
>
> return PG_PROTOCOL_MAJOR(conn->pversion) * 100 +
> PG_PROTOCOL_MINOR(conn->pversion);
>
> or even:
>
> if (PG_PROTOCOL_MAJOR(conn->pversion) == 3 &&
> PG_PROTOCOL_MINOR(conn->pversion))
> return 3;
> else
> return PG_PROTOCOL_MAJOR(conn->pversion) * 100 +
> PG_PROTOCOL_MINOR(conn->pversion);
>
> The second option would be safest backwards compatibility wise, but in
> practice you would only get another value than 3 (or 0) when
> connecting to pre 7.4 servers. That seems old enough that I don't
> think anyone is actually calling this function. **I'd like some
> feedback from others on this though.**
>

This point is open. I'll wait for a reply from others.


>
> +   /* The protocol 3.0 is required */
> +   if (PG_PROTOCOL_MAJOR(their_version) == 3)
> +   conn->pversion = their_version;
>
> Let's compare against the actual PG_PROTOCOL_EARLIEST and
> PG_PROTOCOL_LATEST to determine if the version is supported or not.
>

changed
From f1975b784627fda06b23303c4f1fb6972d80a0a0 Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Mon, 24 Jul 2023 20:18:16 +0200
Subject: [PATCH 4/4] Implementation of %N prompt placeholder

It is based on forcing reporting feature"role" GUC to client.
---
 doc/src/sgml/ref/psql-ref.sgml | 19 ++-
 src/bin/psql/command.c | 13 +
 src/bin/psql/prompt.c  | 28 
 src/bin/psql/settings.h|  1 +
 src/bin/psql/startup.c | 32 
 5 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index d94e3cacfc..8b267a6da6 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4568,7 +4568,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index bcd8eb3538..bad0fdf415 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3883,6 +3883,7 @@ SyncVariables(void)
 {
 	char		vbuf[32];
 	const char *server_version;
+	PGresult   *result;
 
 	/* get stuff from connection */
 	pset.encoding = PQclientEncoding(pset.db);
@@ -3912,6 +3913,18 @@ SyncVariables(void)
 	/* send stuff to it, too */
 	PQsetErrorVerbosity(pset.db, pset.verbosity);
 	PQsetErrorContextVisibility(pset.db, pset.show_context);
+
+	/* link role GUC when it is needed for prompt */
+	if (pset.prompt_shows_role)
+		result = PQlinkParameterStatus(pset.db, "role");
+	else
+		result = PQunlinkParameterStatus(pset.db, "role");
+
+	if (PQresultStatus(result) != PGRES_COMMAND_OK)
+		pg_log_info("cannot set REPORT flag on configuration variable \"role\": %s",
+	PQerrorMessage(pset.db));
+
+	PQclear(result);
 }
 
 /*
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..d306c91d19 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,34 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+		const char *rolename = NULL;
+
+		/*
+		 * This feature requires GUC "role" to be marked
+		 * by GUC_REPORT flag. This is done by PQlinkParameterStatus
+		 * function. This function requires protocol 3.1 (ReportGUC
+		 * message). Fallback is empty string.
+		 */
+		if (PQprotocolVersion(pset.db) == 3 &&
+			PQprotocolSubversion(pset.db) >= 1)
+		{
+			rolename  = PQparameterStatus(pset.db, "role");
+
+			/* fallback when role is not set yet */
+			if (rolename && strcmp(rolename, "none") == 0)
+rolename = session_username();
+		}
+
+		if (rolename)
+			strlcpy(buf, rolename, sizeof(buf));
+		else
+			buf[0] = '\0';
+	

Re: proposal: psql: show current user in prompt

2023-09-04 Thread Pavel Stehule
po 4. 9. 2023 v 14:24 odesílatel Jelte Fennema  napsal:

> On Sun, 3 Sept 2023 at 20:58, Pavel Stehule 
> wrote:
> > here is an try
>
> Overall it does what I had in mind. Below a few suggestions:
>
> +int
> +PQprotocolSubversion(const PGconn *conn)
>
> Ugh, it's quite annoying that the original PQprotocolVersion only
> returns the major version and thus we need this new function. It
> seems like it would be much nicer if it returned a number similar to
> PQserverVersion. I think it might be nicer to change PQprotocolVersion
> to do that than to add another function. We could do:
>
> return PG_PROTOCOL_MAJOR(conn->pversion) * 100 +
> PG_PROTOCOL_MINOR(conn->pversion);
>
> or even:
>
> if (PG_PROTOCOL_MAJOR(conn->pversion) == 3 &&
> PG_PROTOCOL_MINOR(conn->pversion))
> return 3;
> else
> return PG_PROTOCOL_MAJOR(conn->pversion) * 100 +
> PG_PROTOCOL_MINOR(conn->pversion);
>
> The second option would be safest backwards compatibility wise, but in
> practice you would only get another value than 3 (or 0) when
> connecting to pre 7.4 servers. That seems old enough that I don't
> think anyone is actually calling this function. **I'd like some
> feedback from others on this though.**
>

Both versions look a little bit strange to me. I have not strong opinion
about it, but I am not sure if is best to change contract after 20 years ago

commit from Jun 2003 efc3a25bb02ada63158fe7006673518b005261ba

I prefer to introduce a new function - it is ten lines of code. The form is
not important - it can be a full number or minor number. It doesn't matter
I think. But my opinion in this area is not strong, and I like to see
feedback from others too. It is true that this feature and interface is not
fully complete.

Reards

Pavel


> +   /* The protocol 3.0 is required */
> +   if (PG_PROTOCOL_MAJOR(their_version) == 3)
> +   conn->pversion = their_version;
>
> Let's compare against the actual PG_PROTOCOL_EARLIEST and
> PG_PROTOCOL_LATEST to determine if the version is supported or not.
>


Re: proposal: psql: show current user in prompt

2023-09-04 Thread Jelte Fennema
On Sun, 3 Sept 2023 at 20:58, Pavel Stehule  wrote:
> here is an try

Overall it does what I had in mind. Below a few suggestions:

+int
+PQprotocolSubversion(const PGconn *conn)

Ugh, it's quite annoying that the original PQprotocolVersion only
returns the major version and thus we need this new function. It
seems like it would be much nicer if it returned a number similar to
PQserverVersion. I think it might be nicer to change PQprotocolVersion
to do that than to add another function. We could do:

return PG_PROTOCOL_MAJOR(conn->pversion) * 100 +
PG_PROTOCOL_MINOR(conn->pversion);

or even:

if (PG_PROTOCOL_MAJOR(conn->pversion) == 3 && PG_PROTOCOL_MINOR(conn->pversion))
return 3;
else
return PG_PROTOCOL_MAJOR(conn->pversion) * 100 +
PG_PROTOCOL_MINOR(conn->pversion);

The second option would be safest backwards compatibility wise, but in
practice you would only get another value than 3 (or 0) when
connecting to pre 7.4 servers. That seems old enough that I don't
think anyone is actually calling this function. **I'd like some
feedback from others on this though.**

+   /* The protocol 3.0 is required */
+   if (PG_PROTOCOL_MAJOR(their_version) == 3)
+   conn->pversion = their_version;

Let's compare against the actual PG_PROTOCOL_EARLIEST and
PG_PROTOCOL_LATEST to determine if the version is supported or not.




Re: proposal: psql: show current user in prompt

2023-09-03 Thread Pavel Stehule
Hi

ne 3. 9. 2023 v 9:59 odesílatel Jelte Fennema  napsal:

> On Sun, 3 Sept 2023 at 08:24, Pavel Stehule 
> wrote:
> > My personal feeling from this area is that the protocol design is done,
> but it is not implemented on libpq level. My feelings can be wrong. The
> protocol number is hardcoded in libpq, so I cannot change it from the
> client side.
>
>
> No, I agree you're right the client side code to fall back to older
> versions is not implemented. But that seems fairly simple to do. We
> can change pqGetNegotiateProtocolVersion3 its behaviour. That function
> should change conn->pversion to the server provided version if it's
> lower than the client version (as long as the server provided version
> is 3.0 or larger). And then we should return an error when calling
> PQlinkParameterStatus/PQunlinkParameterStatus if the pversion is not
> high enough.
>

ok

here is an try

Regards

Pavel
From 80a076e28c293aef96f455a25e967f2c9baf8eac Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Sun, 3 Sep 2023 19:14:24 +0200
Subject: [PATCH 3/4] - allow to connect to server with major protocol version
 3, minor version is ignored

- allow to read minor protocol version
---
 src/include/libpq/pqcomm.h  |  2 +-
 src/interfaces/libpq/exports.txt|  1 +
 src/interfaces/libpq/fe-connect.c   | 12 +++-
 src/interfaces/libpq/fe-protocol3.c | 13 ++---
 src/interfaces/libpq/libpq-fe.h |  1 +
 5 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h
index 46a0946b8b..4ea4538157 100644
--- a/src/include/libpq/pqcomm.h
+++ b/src/include/libpq/pqcomm.h
@@ -94,7 +94,7 @@ is_unixsock_path(const char *path)
  */
 
 #define PG_PROTOCOL_EARLIEST	PG_PROTOCOL(3,0)
-#define PG_PROTOCOL_LATEST		PG_PROTOCOL(3,0)
+#define PG_PROTOCOL_LATEST		PG_PROTOCOL(3,1)
 
 typedef uint32 ProtocolVersion; /* FE/BE protocol version number */
 
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index 7e101368d5..71e180cd57 100644
--- a/src/interfaces/libpq/exports.txt
+++ b/src/interfaces/libpq/exports.txt
@@ -193,3 +193,4 @@ PQsendClosePrepared   190
 PQsendClosePortal 191
 PQlinkParameterStatus 192
 PQunlinkParameterStatus   193
+PQprotocolSubversion  194
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index bf83a9b569..5e628578b4 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -2777,7 +2777,7 @@ keep_going:		/* We will come back to here until there is
 		 * must persist across individual connection attempts, but we must
 		 * reset them when we start to consider a new server.
 		 */
-		conn->pversion = PG_PROTOCOL(3, 0);
+		conn->pversion = PG_PROTOCOL(3, 1);
 		conn->send_appname = true;
 #ifdef USE_SSL
 		/* initialize these values based on SSL mode */
@@ -7234,6 +7234,16 @@ PQprotocolVersion(const PGconn *conn)
 	return PG_PROTOCOL_MAJOR(conn->pversion);
 }
 
+int
+PQprotocolSubversion(const PGconn *conn)
+{
+	if (!conn)
+		return 0;
+	if (conn->status == CONNECTION_BAD)
+		return 0;
+	return PG_PROTOCOL_MINOR(conn->pversion);
+}
+
 int
 PQserverVersion(const PGconn *conn)
 {
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 90d4e17e6f..05afa70694 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -1441,9 +1441,16 @@ pqGetNegotiateProtocolVersion3(PGconn *conn)
 	}
 
 	if (their_version < conn->pversion)
-		libpq_append_conn_error(conn, "protocol version not supported by server: client uses %u.%u, server supports up to %u.%u",
-PG_PROTOCOL_MAJOR(conn->pversion), PG_PROTOCOL_MINOR(conn->pversion),
-PG_PROTOCOL_MAJOR(their_version), PG_PROTOCOL_MINOR(their_version));
+	{
+		/* The protocol 3.0 is required */
+		if (PG_PROTOCOL_MAJOR(their_version) == 3)
+			conn->pversion = their_version;
+		else
+			libpq_append_conn_error(conn, "protocol version not supported by server: client uses %u.%u, server supports up to %u.%u",
+	PG_PROTOCOL_MAJOR(conn->pversion), PG_PROTOCOL_MINOR(conn->pversion),
+	PG_PROTOCOL_MAJOR(their_version), PG_PROTOCOL_MINOR(their_version));
+	}
+
 	if (num > 0)
 	{
 		appendPQExpBuffer(>errorMessage,
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index ba3ad7e0aa..904e611670 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -347,6 +347,7 @@ extern PGTransactionStatusType PQtransactionStatus(const PGconn *conn);
 extern const char *PQparameterStatus(const PGconn *conn,
 	 const char *paramName);
 extern int	PQprotocolVersion(const PGconn *conn);
+extern int	PQprotocolSubversion(const PGconn *conn);
 extern int	PQserverVersion(const PGconn *conn);
 extern char *PQerrorMessage(const PGconn *conn);
 extern int	PQsocket(const PGconn *conn);
-- 
2.41.0

From bd59c5318c09d09b764da81533d2712aa6d658d4 Mon Sep 17 00:00:00 

Re: proposal: psql: show current user in prompt

2023-09-03 Thread Jelte Fennema
On Sun, 3 Sept 2023 at 08:24, Pavel Stehule  wrote:
> My personal feeling from this area is that the protocol design is done, but 
> it is not implemented on libpq level. My feelings can be wrong. The protocol 
> number is hardcoded in libpq, so I cannot change it from the client side.


No, I agree you're right the client side code to fall back to older
versions is not implemented. But that seems fairly simple to do. We
can change pqGetNegotiateProtocolVersion3 its behaviour. That function
should change conn->pversion to the server provided version if it's
lower than the client version (as long as the server provided version
is 3.0 or larger). And then we should return an error when calling
PQlinkParameterStatus/PQunlinkParameterStatus if the pversion is not
high enough.




Re: proposal: psql: show current user in prompt

2023-09-03 Thread Pavel Stehule
út 29. 8. 2023 v 14:11 odesílatel Jelte Fennema  napsal:

> On Mon, 28 Aug 2023 at 15:00, Pavel Stehule 
> wrote:
> +   minServerMajor = 1600;
> +   serverMajor = PQserverVersion(pset.db) / 100;
>
> Instead of using the server version, we should instead use the
> protocol version negotiation that's provided by the
> NegotiateProtocolVersion message type. We should bump the requested
> protocol version from 3.0 to 3.1 and check that the server supports
> 3.1. Otherwise proxies or connection poolers might get this new
> message type, without knowing what to do with them.
>

I checked this part and this part of the code, and it looks like current
libpq doesn't allow optional requirements of higher protocol version number.

With the current state of NegotiateProtocolVersion handling I am not able
to connect to any older servers, because there is no fallback
implementation.

My personal feeling from this area is that the protocol design is done, but
it is not implemented on libpq level. My feelings can be wrong. The
protocol number is hardcoded in libpq, so I cannot change it from the
client side.

But maybe I don't see some possibility?

Regards

Pavel


>


Re: proposal: psql: show current user in prompt

2023-08-29 Thread Jelte Fennema
On Mon, 28 Aug 2023 at 15:00, Pavel Stehule  wrote:
+   minServerMajor = 1600;
+   serverMajor = PQserverVersion(pset.db) / 100;

Instead of using the server version, we should instead use the
protocol version negotiation that's provided by the
NegotiateProtocolVersion message type. We should bump the requested
protocol version from 3.0 to 3.1 and check that the server supports
3.1. Otherwise proxies or connection poolers might get this new
message type, without knowing what to do with them.

+   
+ReportGUC (F)

We'll need some docs on the "Message Flow" page too:
https://www.postgresql.org/docs/current/protocol-flow.html
Specifically what response is expected, if any.

Another thing that should be described there is that this falls
outside of the transaction flow, i.e. it's changes are not reverted on
ROLLBACK. But that leaves an important consideration: What happens
when an error occurs on the server during handling of this message
(e.g. the GUC does not exist or an OOM is triggered). Is any open
transaction aborted in that case? If not, we should have a test for
that.

+   if (PQresultStatus(res) != PGRES_COMMAND_OK)
+   pg_fatal("failed to link custom variable: %s", PQerrorMessage(conn));
+   PQclear(res);

The tests should also change the config after running
PQlinkParameterStatus/PQunlinkParameterStatus to show that the guc is
reported then or not reported then.

+   if (!PQsendTypedCommand(conn, PqMsg_ReportGUC, 't', paramName))
+   return NULL;


I think we'll need some bikeshedding on what the protocol message
should look like exactly. I'm not entirely sure what is the most
sensible here, so please treat everything I write next as
suggestions/discussion:
I see that you're piggy-backing on PQsendTypedCommand, which seems
nice to avoid code duplication. It has one downside though: not every
type, is valid for each command anymore.
One way to avoid that would be to not introduce a new command, but
only add a new type that is understood by Describe and Close, e.g. a
'G' (for GUC). Then PqMsg_Describe, G would become the equivalent of
what'the current patch its PqMsg_ReportGUC, 't' and PqMsg_Close, G
would be the same as PqMsg_ReportGUC, 'f'.

The rest of this email assumes that we're keeping your current
proposal for the protocol message, so it might not make sense to
address all of this feedback, in case we're still going to change the
protocol:

+   if (is_set == 't')
+   {
+   SetGUCOptionFlag(name, GUC_REPORT);
+   status = "SET REPORT_GUC";
+   }
+   else
+   {
+   UnsetGUCOptionFlag(name, GUC_REPORT);
+   status = "UNSET REPORT_GUC";
+   }

I think we should be strict about what we accept here. Any other value
than 'f'/'t' for is_set should result in an error imho.




Re: proposal: psql: show current user in prompt

2023-08-28 Thread Pavel Stehule
po 28. 8. 2023 v 13:58 odesílatel Pavel Stehule 
napsal:

> Hi
>
>
>>>
>>>
>>> But afaict there's no problem with using pqParseInput3() and
>>> PQexecFinish() even if the message isn't handled as part of the
>>> transaction. Some other messages that pqParseInput3 handles which are
>>> not part of the transaction are 'N' (Notice) and 'K' (secret key).
>>>
>>
>> I have to recheck it
>>
>
> here is new version based on usage of PQexecFinish
>

with protocol test

Regards

Pavel


>
> Regards
>
> Pavel
>
>
>>
>> Regards
>>
>> Pavel
>>
>>
>
From 4567473ebd7fec9dc836793e8e80244b22e5c96b Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Mon, 24 Jul 2023 20:18:16 +0200
Subject: [PATCH 2/3] Implementation of %N prompt placeholder

It is based on forcing reporting feature"role" GUC to client.
---
 doc/src/sgml/ref/psql-ref.sgml | 19 +-
 src/bin/psql/command.c | 13 +
 src/bin/psql/prompt.c  | 35 ++
 src/bin/psql/settings.h|  1 +
 src/bin/psql/startup.c | 32 +++
 5 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 182e58353f..b5da83013e 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4567,7 +4567,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 1300869d79..bf67febc11 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3861,6 +3861,7 @@ SyncVariables(void)
 {
 	char		vbuf[32];
 	const char *server_version;
+	PGresult   *result;
 
 	/* get stuff from connection */
 	pset.encoding = PQclientEncoding(pset.db);
@@ -3890,6 +3891,18 @@ SyncVariables(void)
 	/* send stuff to it, too */
 	PQsetErrorVerbosity(pset.db, pset.verbosity);
 	PQsetErrorContextVisibility(pset.db, pset.show_context);
+
+	/* link role GUC when it is needed for prompt */
+	if (pset.prompt_shows_role)
+		result = PQlinkParameterStatus(pset.db, "role");
+	else
+		result = PQunlinkParameterStatus(pset.db, "role");
+
+	if (PQresultStatus(result) != PGRES_COMMAND_OK)
+		pg_log_info("cannot set REPORT flag on configuration variable \"role\": %s",
+	PQerrorMessage(pset.db));
+
+	PQclear(result);
 }
 
 /*
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..b0f5158c59 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,41 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+		int			minServerMajor;
+		int			serverMajor;
+		const char *rolename = NULL;
+
+		/*
+		 * This feature requires GUC "role" to be marked
+		 * as GUC_REPORT. Without it is hard to specify fallback
+		 * result. Returning empty value can be messy, returning
+		 * PQuser like session_username can be messy too.
+		 * Exec query is not too practical too, because it doesn't
+		 * work when session is not in transactional state, and
+		 * CURRENT_ROLE returns different result when role is not
+		 * explicitly specified by SET ROLE.
+		 */
+		minServerMajor = 1600;
+		serverMajor = PQserverVersion(pset.db) / 100;
+		if (serverMajor >= minServerMajor)
+		{
+			rolename  = PQparameterStatus(pset.db, "role");
+
+			/* fallback when role is not set yet */
+			if (rolename && strcmp(rolename, "none") == 0)
+rolename = session_username();
+		}
+
+		if (rolename)
+			strlcpy(buf, rolename, sizeof(buf));
+		else
+			buf[0] = '\0';
+	}
+	break;
 	/* backend pid */
 case 'p':
 	if (pset.db)
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index 1106954236..cb7c12bd1d 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -154,6 +154,7 @@ typedef struct _psqlSettings
 	PGVerbosity verbosity;		/* current error verbosity level */
 	bool		show_all_results;
 	PGContextVisibility show_context;	/* current context display level */
+	bool		prompt_shows_role;
 } PsqlSettings;
 
 extern PsqlSettings pset;
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 5a28b6f713..0dac396525 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ 

Re: proposal: psql: show current user in prompt

2023-08-28 Thread Pavel Stehule
Hi


>>
>>
>> But afaict there's no problem with using pqParseInput3() and
>> PQexecFinish() even if the message isn't handled as part of the
>> transaction. Some other messages that pqParseInput3 handles which are
>> not part of the transaction are 'N' (Notice) and 'K' (secret key).
>>
>
> I have to recheck it
>

here is new version based on usage of PQexecFinish

Regards

Pavel


>
> Regards
>
> Pavel
>
>
From 4567473ebd7fec9dc836793e8e80244b22e5c96b Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Mon, 24 Jul 2023 20:18:16 +0200
Subject: [PATCH 2/2] Implementation of %N prompt placeholder

It is based on forcing reporting feature"role" GUC to client.
---
 doc/src/sgml/ref/psql-ref.sgml | 19 +-
 src/bin/psql/command.c | 13 +
 src/bin/psql/prompt.c  | 35 ++
 src/bin/psql/settings.h|  1 +
 src/bin/psql/startup.c | 32 +++
 5 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 182e58353f..b5da83013e 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4567,7 +4567,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 1300869d79..bf67febc11 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3861,6 +3861,7 @@ SyncVariables(void)
 {
 	char		vbuf[32];
 	const char *server_version;
+	PGresult   *result;
 
 	/* get stuff from connection */
 	pset.encoding = PQclientEncoding(pset.db);
@@ -3890,6 +3891,18 @@ SyncVariables(void)
 	/* send stuff to it, too */
 	PQsetErrorVerbosity(pset.db, pset.verbosity);
 	PQsetErrorContextVisibility(pset.db, pset.show_context);
+
+	/* link role GUC when it is needed for prompt */
+	if (pset.prompt_shows_role)
+		result = PQlinkParameterStatus(pset.db, "role");
+	else
+		result = PQunlinkParameterStatus(pset.db, "role");
+
+	if (PQresultStatus(result) != PGRES_COMMAND_OK)
+		pg_log_info("cannot set REPORT flag on configuration variable \"role\": %s",
+	PQerrorMessage(pset.db));
+
+	PQclear(result);
 }
 
 /*
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..b0f5158c59 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,41 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+		int			minServerMajor;
+		int			serverMajor;
+		const char *rolename = NULL;
+
+		/*
+		 * This feature requires GUC "role" to be marked
+		 * as GUC_REPORT. Without it is hard to specify fallback
+		 * result. Returning empty value can be messy, returning
+		 * PQuser like session_username can be messy too.
+		 * Exec query is not too practical too, because it doesn't
+		 * work when session is not in transactional state, and
+		 * CURRENT_ROLE returns different result when role is not
+		 * explicitly specified by SET ROLE.
+		 */
+		minServerMajor = 1600;
+		serverMajor = PQserverVersion(pset.db) / 100;
+		if (serverMajor >= minServerMajor)
+		{
+			rolename  = PQparameterStatus(pset.db, "role");
+
+			/* fallback when role is not set yet */
+			if (rolename && strcmp(rolename, "none") == 0)
+rolename = session_username();
+		}
+
+		if (rolename)
+			strlcpy(buf, rolename, sizeof(buf));
+		else
+			buf[0] = '\0';
+	}
+	break;
 	/* backend pid */
 case 'p':
 	if (pset.db)
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index 1106954236..cb7c12bd1d 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -154,6 +154,7 @@ typedef struct _psqlSettings
 	PGVerbosity verbosity;		/* current error verbosity level */
 	bool		show_all_results;
 	PGContextVisibility show_context;	/* current context display level */
+	bool		prompt_shows_role;
 } PsqlSettings;
 
 extern PsqlSettings pset;
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 5a28b6f713..0dac396525 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -1094,10 +1094,40 @@ histcontrol_hook(const char *newval)
 	return true;
 }
 
+static void
+prompt_needs_role_parameter_status(void)
+{

Re: proposal: psql: show current user in prompt

2023-08-11 Thread Pavel Stehule
čt 10. 8. 2023 v 16:31 odesílatel Jelte Fennema  napsal:

> On Thu, 10 Aug 2023 at 14:44, Pavel Stehule 
> wrote:
> > čt 10. 8. 2023 v 14:05 odesílatel Jelte Fennema 
> napsal:
> >> That it is not rolled-back
> >> in a case like this?
> >>
> >> BEGIN;
> >> \set PROMPT '%N'
> >> ROLLBACK;
> >
> >
> > surely not.
> >
> > \set is client side setting, and it is not transactional. Attention -
> "\set" and "set" commands are absolutely different creatures.
>
> To clarify: I agree it's the desired behavior that \set is not rolled back.
>
> > It Would be strange (can be very messy) if I had a message like "cannot
> set a prompt, because you should do ROLLBACK first"
>
> This was a very helpful sentence for my understanding. To double check
> that I'm understanding you correctly. This is the kind of case that
> you're talking about.
>
> postgres=# BEGIN;
> postgres=# SELECT some syntax error;
> ERROR:  42601: syntax error at or near "some"
> postgres=# \set PROMPT '%N'
> ERROR:  25P02: current transaction is aborted, commands ignored until
> end of transaction block
>

yes

>
> I agree that it should not throw an error like that. So indeed a
> dedicated message type is needed for psql too. Because any query will
> cause that error.
>


>
> But afaict there's no problem with using pqParseInput3() and
> PQexecFinish() even if the message isn't handled as part of the
> transaction. Some other messages that pqParseInput3 handles which are
> not part of the transaction are 'N' (Notice) and 'K' (secret key).
>

I have to recheck it

Regards

Pavel


Re: proposal: psql: show current user in prompt

2023-08-10 Thread Jelte Fennema
On Thu, 10 Aug 2023 at 14:44, Pavel Stehule  wrote:
> čt 10. 8. 2023 v 14:05 odesílatel Jelte Fennema  napsal:
>> That it is not rolled-back
>> in a case like this?
>>
>> BEGIN;
>> \set PROMPT '%N'
>> ROLLBACK;
>
>
> surely not.
>
> \set is client side setting, and it is not transactional. Attention - "\set" 
> and "set" commands are absolutely different creatures.

To clarify: I agree it's the desired behavior that \set is not rolled back.

> It Would be strange (can be very messy) if I had a message like "cannot set a 
> prompt, because you should do ROLLBACK first"

This was a very helpful sentence for my understanding. To double check
that I'm understanding you correctly. This is the kind of case that
you're talking about.

postgres=# BEGIN;
postgres=# SELECT some syntax error;
ERROR:  42601: syntax error at or near "some"
postgres=# \set PROMPT '%N'
ERROR:  25P02: current transaction is aborted, commands ignored until
end of transaction block

I agree that it should not throw an error like that. So indeed a
dedicated message type is needed for psql too. Because any query will
cause that error.

But afaict there's no problem with using pqParseInput3() and
PQexecFinish() even if the message isn't handled as part of the
transaction. Some other messages that pqParseInput3 handles which are
not part of the transaction are 'N' (Notice) and 'K' (secret key).




Re: proposal: psql: show current user in prompt

2023-08-10 Thread Pavel Stehule
čt 10. 8. 2023 v 14:05 odesílatel Jelte Fennema  napsal:

> On Tue, 8 Aug 2023 at 07:20, Pavel Stehule 
> wrote:
> > The reason why I implemented separate flow is usage from psql and
> independence of transaction state.  It is used for the \set command, that
> is non-transactional, not SQL. If I inject this message to some other flow,
> I lose this independence.
>
> I still don't understand the issue that you're trying to solve by
> introducing a new flow for handling the response. What do you mean
> with independence of the transaction state? That it is not rolled-back
> in a case like this?
>
> BEGIN;
> \set PROMPT '%N'
> ROLLBACK;
>

surely not.

\set is client side setting, and it is not transactional. Attention -
"\set" and "set" commands are absolutely different creatures.


> That seems more like a Postgres server concern, i.e. don't revert the
> change back on ROLLBACK. (I think your current server-side
> implementation already does that)
>

Postgres does it, but not on the client side. What I know, almost all
environments don't support transactions on the client side. Postgres is not
special in this direction.


>
> I guess one reason that I don't understand what you mean is that libpq
> doesn't really care about "transaction state" at all. It's really a
> wrapper around a socket with easy functions to send messages in the
> postgres protocol over it. So it cares about the "connection state",
> but not really about a "transaction state". (it does track the current
> connection state, but it doesn't actually use the value except when
> reporting the value when PQtransactionStatus is called by the user of
> libpq)
>
> > Without independence on transaction state and SQL, I can just implement
> some SQL function that sets reporting for any GUC, and it is more simple
> than extending protocol.
>
> I don't understand why this is not possible. As far as I can tell this
> should work fine for the usecase of psql. I still prefer the protocol
> message approach though, because that makes it possible for connection
> poolers to intercept the message and handle it accordingly. And I see
> some use cases for this reporting feature for PgBouncer as well.
>

Maybe we are talking about different features. Now, I have no idea how the
proposed feature can be useful for pgbouncer?

Sure If I implement a new flow, then pgbouncer cannot forward. But it is
not too hard to implement redirection of new flow to pgbouncer.


> However, I think this is probably the key thing that I don't
> understand about the problem you're describing: So, could you explain
> in some more detail why implementing a SQL function would not work for
> psql?
>

I try to get some consistency. psql setting and some features like
formatting doesn't depend on transactional state. It depends just on
connection.  This is the reason why I don't want to inject dependency on
transaction state. Without this dependency, I don't need to check
transaction state, and I can execute prompt settings immediately. If I
implement this feature as transactional, then I need to wait to idle or to
make a new transaction (and this I have not under my control). I try to be
consistent with current psql behaviour. It Would be strange (can be very
messy) if I had a message like "cannot set a prompt, because you should do
ROLLBACK first"

When this feature should be implemented as an injected message, then I have
another problem. Which SQL command I have to send to the server, when the
user wants to set a prompt? And then I don't need to implement a new
message, and I can just implement the SQL function
pg_catalog.report_config(...).


Re: proposal: psql: show current user in prompt

2023-08-10 Thread Jelte Fennema
On Tue, 8 Aug 2023 at 07:20, Pavel Stehule  wrote:
> The reason why I implemented separate flow is usage from psql and 
> independence of transaction state.  It is used for the \set command, that is 
> non-transactional, not SQL. If I inject this message to some other flow, I 
> lose this independence.

I still don't understand the issue that you're trying to solve by
introducing a new flow for handling the response. What do you mean
with independence of the transaction state? That it is not rolled-back
in a case like this?

BEGIN;
\set PROMPT '%N'
ROLLBACK;

That seems more like a Postgres server concern, i.e. don't revert the
change back on ROLLBACK. (I think your current server-side
implementation already does that)

I guess one reason that I don't understand what you mean is that libpq
doesn't really care about "transaction state" at all. It's really a
wrapper around a socket with easy functions to send messages in the
postgres protocol over it. So it cares about the "connection state",
but not really about a "transaction state". (it does track the current
connection state, but it doesn't actually use the value except when
reporting the value when PQtransactionStatus is called by the user of
libpq)

> Without independence on transaction state and SQL, I can just implement some 
> SQL function that sets reporting for any GUC, and it is more simple than 
> extending protocol.

I don't understand why this is not possible. As far as I can tell this
should work fine for the usecase of psql. I still prefer the protocol
message approach though, because that makes it possible for connection
poolers to intercept the message and handle it accordingly. And I see
some use cases for this reporting feature for PgBouncer as well.
However, I think this is probably the key thing that I don't
understand about the problem you're describing: So, could you explain
in some more detail why implementing a SQL function would not work for
psql?




Re: proposal: psql: show current user in prompt

2023-08-07 Thread Pavel Stehule
po 31. 7. 2023 v 17:46 odesílatel Jelte Fennema  napsal:

> On Mon, 24 Jul 2023 at 21:16, Pavel Stehule 
> wrote:
> > I don't understand how it can be possible to do it without.  I need to
> process possible errors, and then I need to read and synchronize protocol.
> I didn't inject
> > this feature to some oher flow, so I need to implement a complete
> process.
>
> I think I might be missing the reason for this then. Could you explain
> a bit more why you didn't inject the feature into another flow?
> Because it seems like it would be better to inserting the logic for
> handling the new response packet in pqParseInput3(), and then wait on
> the result with PQexecFinish(). This would allow sending these
> messages in a pipelined mode.
>
> > For example, PQsetClientEncoding does a PQexec call, which is much more
> expensive.
>
> Yeah, but you'd usually only call that once for the life of the
> connection. But honestly it would still be good if there was a
> pipelined version of that function.
>
> > Unfortunately, for this feature, I cannot change some local state
> variables, but I need to change the state of the server. Own message is
> necessary, because we don't want to be limited by the current transaction
> state, and then we cannot reuse PQexec.
>
> I guess this is your reasoning for why it needs its own state machine,
> but I don't think I understand the problem. Could you expand a bit
> more on what you mean? Note that different message types use
> PQexecFinish to wait for their result, e.g. PQdescribePrepared and
> PQclosePrepared use PQexecFinish too and those wait for a
> RowDescription and a Close message respectively. I added the logic for
> PQclosePerpared recently, that patch might be some helpful example
> code:
> https://github.com/postgres/postgres/commit/28b5726561841556dc3e00ffe26b01a8107ee654


The reason why I implemented separate flow is usage from psql and
independence of transaction state.  It is used for the \set command, that
is non-transactional, not SQL. If I inject this message to some other flow,
I lose this independence. Proposed message can be injected to other flows
too, I think, but for the proposed psql feature it is not practical.
Without independence on transaction state and SQL, I can just implement
some SQL function that sets reporting for any GUC, and it is more simple
than extending protocol.

Regards

Pavel



>
> > The API can be changed from PQlinkParameterStatus(PGconn *conn, const
> char *paramName)
> >
> > to
> >
> > PQlinkParameterStatus(PGconn *conn, int nParamNames, const char
> *paramNames)
>
> That would definitely address the issue with the many round trips
> being needed. But it would still leave the issue of introducing a
> second state machine in the libpq code. So if it's possible to combine
> this new code into the existing state machine, then that seems a lot
> better.
>


Re: proposal: psql: show current user in prompt

2023-07-31 Thread Jelte Fennema
On Mon, 24 Jul 2023 at 21:16, Pavel Stehule  wrote:
> I don't understand how it can be possible to do it without.  I need to 
> process possible errors, and then I need to read and synchronize protocol. I 
> didn't inject
> this feature to some oher flow, so I need to implement a complete process.

I think I might be missing the reason for this then. Could you explain
a bit more why you didn't inject the feature into another flow?
Because it seems like it would be better to inserting the logic for
handling the new response packet in pqParseInput3(), and then wait on
the result with PQexecFinish(). This would allow sending these
messages in a pipelined mode.

> For example, PQsetClientEncoding does a PQexec call, which is much more 
> expensive.

Yeah, but you'd usually only call that once for the life of the
connection. But honestly it would still be good if there was a
pipelined version of that function.

> Unfortunately, for this feature, I cannot change some local state variables, 
> but I need to change the state of the server. Own message is necessary, 
> because we don't want to be limited by the current transaction state, and 
> then we cannot reuse PQexec.

I guess this is your reasoning for why it needs its own state machine,
but I don't think I understand the problem. Could you expand a bit
more on what you mean? Note that different message types use
PQexecFinish to wait for their result, e.g. PQdescribePrepared and
PQclosePrepared use PQexecFinish too and those wait for a
RowDescription and a Close message respectively. I added the logic for
PQclosePerpared recently, that patch might be some helpful example
code: 
https://github.com/postgres/postgres/commit/28b5726561841556dc3e00ffe26b01a8107ee654

> The API can be changed from PQlinkParameterStatus(PGconn *conn, const char 
> *paramName)
>
> to
>
> PQlinkParameterStatus(PGconn *conn, int nParamNames, const char *paramNames)

That would definitely address the issue with the many round trips
being needed. But it would still leave the issue of introducing a
second state machine in the libpq code. So if it's possible to combine
this new code into the existing state machine, then that seems a lot
better.




Re: proposal: psql: show current user in prompt

2023-07-24 Thread Pavel Stehule
Hi

po 8. 5. 2023 v 14:22 odesílatel Jelte Fennema  napsal:

> I'm very much in favor of adding a way to support reporting other GUC
> variables than the current hardcoded list. This can be quite useful to
> support some amount of session state in connection poolers.
>
> Some general feedback on the patch:
> 1. I don't think the synchronization mechanism that you added should
> be part of PQlinkParameterStatus. It seems likely for people to want
> to turn on reporting for multiple GUCs in one go. Having to
> synchronize for each would introduce unnecessary round trips. Maybe
> you also don't care about syncing at all at this point in time.
>

I don't understand how it can be possible to do it without.  I need to
process possible errors, and then I need to read and synchronize protocol.
I didn't inject
this feature to some oher flow, so I need to implement a complete process.
For example, PQsetClientEncoding does a PQexec call, which is much more
expensive. Unfortunately, for this feature, I cannot change some local
state variables, but I need to change the state of the server. Own message
is necessary, because we don't want to be limited by the current
transaction state, and then we cannot reuse PQexec.

The API can be changed from PQlinkParameterStatus(PGconn *conn, const char
*paramName)

to

PQlinkParameterStatus(PGconn *conn, int nParamNames, const char *paramNames)

What do you think?

Regards

Pavel


>
> 2. Support for this message should probably require a protocol
> extension. There is another recent thread that discusses about adding
> message types and protocol extensions:
>
> https://www.postgresql.org/message-id/flat/CA%2BTgmoaxfJ3whOqnxTjT-%2BHDgZYbEho7dVHHsuEU2sgRw17OEQ%40mail.gmail.com#acd99fde0c037cc6cb35d565329b6e00
>
> 3. Some tests for this new libpq API should be added in
> src/test/modules/libpq_pipeline
>
> 4. s/massages/messages
>
>
> Finally, I think this patch should be split into two commits:
> 1. adding custom GUC_REPORT protocol support+libpq API
> 2. using this libpq API in psql for the user prompt
>
> If you have multiple commits (which are rebased on master), you can
> very easily create multiple patch files using this command:
> git format-patch master --base=master --reroll-count={version_number_here}
>
>
> On Fri, 28 Apr 2023 at 07:00, Pavel Stehule 
> wrote:
> >
> >
> >
> > čt 27. 4. 2023 v 7:39 odesílatel Pavel Stehule 
> napsal:
> >>
> >> Hi
> >>
> >> rebased version + fix warning possibly uninitialized variable
> >
> >
> > fix not unique function id
> >
> > Regards
> >
> > Pavel
> >
> >>
> >> Regards
> >>
> >> Pavel
> >>
>


Re: proposal: psql: show current user in prompt

2023-07-15 Thread Pavel Stehule
Hi

pá 28. 4. 2023 v 7:00 odesílatel Pavel Stehule 
napsal:

>
>
> čt 27. 4. 2023 v 7:39 odesílatel Pavel Stehule 
> napsal:
>
>> Hi
>>
>> rebased version + fix warning possibly uninitialized variable
>>
>
> fix not unique function id
>
> Regards
>
> Pavel
>

only rebase



>
>
>> Regards
>>
>> Pavel
>>
>>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index b11d9a6ba3..f774ffa310 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -5401,6 +5401,43 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
 

 
+   
+ReportGUC (F)
+
+ 
+  
+   Byte1('r')
+   
+
+ Identifies the message type.  ReportGUC is sent by
+ frontend when the changes of specified GUC option
+ should be (or should not be) reported to state parameter.
+
+   
+  
+
+  
+   String
+   
+
+ The name of GUC option.
+
+   
+  
+
+  
+   Int16
+   
+
+ 1 if reporting should be enables, 0 if reporting should be
+ disabled.
+
+   
+  
+ 
+
+   
+

 RowDescription (B)
 
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 35aec6d3ce..036d34f412 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4545,7 +4545,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 36cc99ec9c..0df46514bf 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -451,6 +451,11 @@ SocketBackend(StringInfo inBuf)
 			doing_extended_query_message = false;
 			break;
 
+		case 'r':/* report GUC */
+			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
+			doing_extended_query_message = false;
+			break;
+
 		default:
 
 			/*
@@ -4828,6 +4833,24 @@ PostgresMain(const char *dbname, const char *username)
 	pq_flush();
 break;
 
+			case 'r':			/* report GUC */
+{
+	const char	   *name;
+	intcreate_flag;
+
+	name = pq_getmsgstring(_message);
+	create_flag = pq_getmsgint(_message, 2);
+	pq_getmsgend(_message);
+
+	if (create_flag)
+		SetGUCOptionFlag(name, GUC_REPORT);
+	else
+	UnsetGUCOptionFlag(name, GUC_REPORT);
+
+	send_ready_for_query = true;
+}
+break;
+
 			case 'S':			/* sync */
 pq_getmsgend(_message);
 finish_xact_command();
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5308896c87..e09cbbb414 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2532,6 +2532,37 @@ BeginReportingGUCOptions(void)
 	}
 }
 
+/*
+ * Allow to set / unset dynamicaly flags to GUC variables
+ */
+void
+SetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, true, ERROR);
+	conf->flags |= flag;
+
+	if (flag == GUC_REPORT)
+		/* force transmit value of related option to client Parameter Status */
+		ReportGUCOption(conf);
+}
+
+void
+UnsetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, true, ERROR);
+	conf->flags &= ~flag;
+}
+
 /*
  * ReportChangedGUCOptions: report recently-changed GUC_REPORT variables
  *
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 511debbe81..a1cf434187 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3859,6 +3859,7 @@ SyncVariables(void)
 {
 	char		vbuf[32];
 	const char *server_version;
+	int			res;
 
 	/* get stuff from connection */
 	pset.encoding = PQclientEncoding(pset.db);
@@ -3888,6 +3889,15 @@ SyncVariables(void)
 	/* send stuff to it, too */
 	PQsetErrorVerbosity(pset.db, pset.verbosity);
 	PQsetErrorContextVisibility(pset.db, pset.show_context);
+
+	/* link role GUC when it is needed for prompt */
+	if (pset.prompt_shows_role)
+		res = PQlinkParameterStatus(pset.db, "role");
+	else
+		res = PQunlinkParameterStatus(pset.db, "role");
+
+	if (res < 0)
+		pg_log_info("%s", PQerrorMessage(pset.db));
 }
 
 /*
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..b0f5158c59 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 

Re: proposal: psql: show current user in prompt

2023-07-15 Thread Pavel Stehule
Hi

po 8. 5. 2023 v 14:22 odesílatel Jelte Fennema  napsal:

> I'm very much in favor of adding a way to support reporting other GUC
> variables than the current hardcoded list. This can be quite useful to
> support some amount of session state in connection poolers.
>
> Some general feedback on the patch:
> 1. I don't think the synchronization mechanism that you added should
> be part of PQlinkParameterStatus. It seems likely for people to want
> to turn on reporting for multiple GUCs in one go. Having to
> synchronize for each would introduce unnecessary round trips. Maybe
> you also don't care about syncing at all at this point in time.
>
> 2. Support for this message should probably require a protocol
> extension. There is another recent thread that discusses about adding
> message types and protocol extensions:
>
> https://www.postgresql.org/message-id/flat/CA%2BTgmoaxfJ3whOqnxTjT-%2BHDgZYbEho7dVHHsuEU2sgRw17OEQ%40mail.gmail.com#acd99fde0c037cc6cb35d565329b6e00
>
> 3. Some tests for this new libpq API should be added in
> src/test/modules/libpq_pipeline
>
> 4. s/massages/messages
>
>
> Finally, I think this patch should be split into two commits:
> 1. adding custom GUC_REPORT protocol support+libpq API
> 2. using this libpq API in psql for the user prompt
>
> If you have multiple commits (which are rebased on master), you can
> very easily create multiple patch files using this command:
> git format-patch master --base=master --reroll-count={version_number_here}
>
>
Thank you for your comments, I'll finish refactoring plpgsql_check, and
I'll start refactoring this patch with your comments.

Regards

Pavel


>
> On Fri, 28 Apr 2023 at 07:00, Pavel Stehule 
> wrote:
> >
> >
> >
> > čt 27. 4. 2023 v 7:39 odesílatel Pavel Stehule 
> napsal:
> >>
> >> Hi
> >>
> >> rebased version + fix warning possibly uninitialized variable
> >
> >
> > fix not unique function id
> >
> > Regards
> >
> > Pavel
> >
> >>
> >> Regards
> >>
> >> Pavel
> >>
>


Re: proposal: psql: show current user in prompt

2023-05-08 Thread Jelte Fennema
I'm very much in favor of adding a way to support reporting other GUC
variables than the current hardcoded list. This can be quite useful to
support some amount of session state in connection poolers.

Some general feedback on the patch:
1. I don't think the synchronization mechanism that you added should
be part of PQlinkParameterStatus. It seems likely for people to want
to turn on reporting for multiple GUCs in one go. Having to
synchronize for each would introduce unnecessary round trips. Maybe
you also don't care about syncing at all at this point in time.

2. Support for this message should probably require a protocol
extension. There is another recent thread that discusses about adding
message types and protocol extensions:
https://www.postgresql.org/message-id/flat/CA%2BTgmoaxfJ3whOqnxTjT-%2BHDgZYbEho7dVHHsuEU2sgRw17OEQ%40mail.gmail.com#acd99fde0c037cc6cb35d565329b6e00

3. Some tests for this new libpq API should be added in
src/test/modules/libpq_pipeline

4. s/massages/messages


Finally, I think this patch should be split into two commits:
1. adding custom GUC_REPORT protocol support+libpq API
2. using this libpq API in psql for the user prompt

If you have multiple commits (which are rebased on master), you can
very easily create multiple patch files using this command:
git format-patch master --base=master --reroll-count={version_number_here}


On Fri, 28 Apr 2023 at 07:00, Pavel Stehule  wrote:
>
>
>
> čt 27. 4. 2023 v 7:39 odesílatel Pavel Stehule  
> napsal:
>>
>> Hi
>>
>> rebased version + fix warning possibly uninitialized variable
>
>
> fix not unique function id
>
> Regards
>
> Pavel
>
>>
>> Regards
>>
>> Pavel
>>




Re: proposal: psql: show current user in prompt

2023-04-27 Thread Pavel Stehule
čt 27. 4. 2023 v 7:39 odesílatel Pavel Stehule 
napsal:

> Hi
>
> rebased version + fix warning possibly uninitialized variable
>

fix not unique function id

Regards

Pavel


> Regards
>
> Pavel
>
>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index b11d9a6ba3..f774ffa310 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -5401,6 +5401,43 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
 

 
+   
+ReportGUC (F)
+
+ 
+  
+   Byte1('r')
+   
+
+ Identifies the message type.  ReportGUC is sent by
+ frontend when the changes of specified GUC option
+ should be (or should not be) reported to state parameter.
+
+   
+  
+
+  
+   String
+   
+
+ The name of GUC option.
+
+   
+  
+
+  
+   Int16
+   
+
+ 1 if reporting should be enables, 0 if reporting should be
+ disabled.
+
+   
+  
+ 
+
+   
+

 RowDescription (B)
 
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index dc422373d6..569f50fe7d 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4551,7 +4551,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 01b6cc1f7d..54a3f5c1e9 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -451,6 +451,11 @@ SocketBackend(StringInfo inBuf)
 			doing_extended_query_message = false;
 			break;
 
+		case 'r':/* report GUC */
+			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
+			doing_extended_query_message = false;
+			break;
+
 		default:
 
 			/*
@@ -4823,6 +4828,24 @@ PostgresMain(const char *dbname, const char *username)
 	pq_flush();
 break;
 
+			case 'r':			/* report GUC */
+{
+	const char	   *name;
+	intcreate_flag;
+
+	name = pq_getmsgstring(_message);
+	create_flag = pq_getmsgint(_message, 2);
+	pq_getmsgend(_message);
+
+	if (create_flag)
+		SetGUCOptionFlag(name, GUC_REPORT);
+	else
+	UnsetGUCOptionFlag(name, GUC_REPORT);
+
+	send_ready_for_query = true;
+}
+break;
+
 			case 'S':			/* sync */
 pq_getmsgend(_message);
 finish_xact_command();
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 53d1d9a06a..b023b1a020 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2531,6 +2531,37 @@ BeginReportingGUCOptions(void)
 	}
 }
 
+/*
+ * Allow to set / unset dynamicaly flags to GUC variables
+ */
+void
+SetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, true, ERROR);
+	conf->flags |= flag;
+
+	if (flag == GUC_REPORT)
+		/* force transmit value of related option to client Parameter Status */
+		ReportGUCOption(conf);
+}
+
+void
+UnsetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, true, ERROR);
+	conf->flags &= ~flag;
+}
+
 /*
  * ReportChangedGUCOptions: report recently-changed GUC_REPORT variables
  *
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 97f7d97220..5276da54fc 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3859,6 +3859,7 @@ SyncVariables(void)
 {
 	char		vbuf[32];
 	const char *server_version;
+	int			res;
 
 	/* get stuff from connection */
 	pset.encoding = PQclientEncoding(pset.db);
@@ -3888,6 +3889,15 @@ SyncVariables(void)
 	/* send stuff to it, too */
 	PQsetErrorVerbosity(pset.db, pset.verbosity);
 	PQsetErrorContextVisibility(pset.db, pset.show_context);
+
+	/* link role GUC when it is needed for prompt */
+	if (pset.prompt_shows_role)
+		res = PQlinkParameterStatus(pset.db, "role");
+	else
+		res = PQunlinkParameterStatus(pset.db, "role");
+
+	if (res < 0)
+		pg_log_info("%s", PQerrorMessage(pset.db));
 }
 
 /*
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..b0f5158c59 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,41 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, 

Re: proposal: psql: show current user in prompt

2023-04-26 Thread Pavel Stehule
Hi

rebased version + fix warning possibly uninitialized variable

Regards

Pavel
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index b11d9a6ba3..f774ffa310 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -5401,6 +5401,43 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
 

 
+   
+ReportGUC (F)
+
+ 
+  
+   Byte1('r')
+   
+
+ Identifies the message type.  ReportGUC is sent by
+ frontend when the changes of specified GUC option
+ should be (or should not be) reported to state parameter.
+
+   
+  
+
+  
+   String
+   
+
+ The name of GUC option.
+
+   
+  
+
+  
+   Int16
+   
+
+ 1 if reporting should be enables, 0 if reporting should be
+ disabled.
+
+   
+  
+ 
+
+   
+

 RowDescription (B)
 
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index dc422373d6..569f50fe7d 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4551,7 +4551,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 01b6cc1f7d..54a3f5c1e9 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -451,6 +451,11 @@ SocketBackend(StringInfo inBuf)
 			doing_extended_query_message = false;
 			break;
 
+		case 'r':/* report GUC */
+			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
+			doing_extended_query_message = false;
+			break;
+
 		default:
 
 			/*
@@ -4823,6 +4828,24 @@ PostgresMain(const char *dbname, const char *username)
 	pq_flush();
 break;
 
+			case 'r':			/* report GUC */
+{
+	const char	   *name;
+	intcreate_flag;
+
+	name = pq_getmsgstring(_message);
+	create_flag = pq_getmsgint(_message, 2);
+	pq_getmsgend(_message);
+
+	if (create_flag)
+		SetGUCOptionFlag(name, GUC_REPORT);
+	else
+	UnsetGUCOptionFlag(name, GUC_REPORT);
+
+	send_ready_for_query = true;
+}
+break;
+
 			case 'S':			/* sync */
 pq_getmsgend(_message);
 finish_xact_command();
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9dd624b3ae..e0dccd1fa3 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2531,6 +2531,37 @@ BeginReportingGUCOptions(void)
 	}
 }
 
+/*
+ * Allow to set / unset dynamicaly flags to GUC variables
+ */
+void
+SetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, true, ERROR);
+	conf->flags |= flag;
+
+	if (flag == GUC_REPORT)
+		/* force transmit value of related option to client Parameter Status */
+		ReportGUCOption(conf);
+}
+
+void
+UnsetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, true, ERROR);
+	conf->flags &= ~flag;
+}
+
 /*
  * ReportChangedGUCOptions: report recently-changed GUC_REPORT variables
  *
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 97f7d97220..5276da54fc 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3859,6 +3859,7 @@ SyncVariables(void)
 {
 	char		vbuf[32];
 	const char *server_version;
+	int			res;
 
 	/* get stuff from connection */
 	pset.encoding = PQclientEncoding(pset.db);
@@ -3888,6 +3889,15 @@ SyncVariables(void)
 	/* send stuff to it, too */
 	PQsetErrorVerbosity(pset.db, pset.verbosity);
 	PQsetErrorContextVisibility(pset.db, pset.show_context);
+
+	/* link role GUC when it is needed for prompt */
+	if (pset.prompt_shows_role)
+		res = PQlinkParameterStatus(pset.db, "role");
+	else
+		res = PQunlinkParameterStatus(pset.db, "role");
+
+	if (res < 0)
+		pg_log_info("%s", PQerrorMessage(pset.db));
 }
 
 /*
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..b0f5158c59 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,41 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+	

Re: proposal: psql: show current user in prompt

2023-04-11 Thread Pavel Stehule
st 5. 4. 2023 v 18:40 odesílatel Pavel Stehule 
napsal:

>
>
> st 5. 4. 2023 v 17:47 odesílatel Robert Haas 
> napsal:
>
>> On Wed, Apr 5, 2023 at 11:34 AM Pavel Stehule 
>> wrote:
>> > If the GUC_REPORT should not  be used, then only one possibility is
>> enhancing the protocol, about the possibility to read some predefined
>> server's features from the client.
>> > It can be much cheaper than SQL query, and it can be used when the
>> current transaction is aborted. I can imagine a possibility to read server
>> time or a server session role from a prompt processing routine.
>> >
>> > But for this specific case, you need to cache the role name somewhere.
>> You can simply get oid everytime, but for role name you need to access to
>> system catalogue, and it is not possible in aborted transactions. So at the
>> end, you probably should read "role" GUC.
>> >
>> > Can this design be  acceptable?
>>
>> I don't think we want to add a dedicated protocol message that says
>> "send me the role GUC right now". I mean, we could, but being able to
>> tell the GUC mechanism "please send me the role GUC after every
>> command" sounds a lot easier to use.
>>
>
> I'll try it
>

here is patch with setting GUC_REPORT on role only when it is required by
prompt

Regards

Pavel


>
> Regards
>
> Pavel
>
>
>>
>> --
>> Robert Haas
>> EDB: http://www.enterprisedb.com
>>
>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index b11d9a6ba3..f774ffa310 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -5401,6 +5401,43 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
 

 
+   
+ReportGUC (F)
+
+ 
+  
+   Byte1('r')
+   
+
+ Identifies the message type.  ReportGUC is sent by
+ frontend when the changes of specified GUC option
+ should be (or should not be) reported to state parameter.
+
+   
+  
+
+  
+   String
+   
+
+ The name of GUC option.
+
+   
+  
+
+  
+   Int16
+   
+
+ 1 if reporting should be enables, 0 if reporting should be
+ disabled.
+
+   
+  
+ 
+
+   
+

 RowDescription (B)
 
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index f4f25d1b07..962bf65f95 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4552,7 +4552,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 01b6cc1f7d..54a3f5c1e9 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -451,6 +451,11 @@ SocketBackend(StringInfo inBuf)
 			doing_extended_query_message = false;
 			break;
 
+		case 'r':/* report GUC */
+			maxmsglen = PQ_SMALL_MESSAGE_LIMIT;
+			doing_extended_query_message = false;
+			break;
+
 		default:
 
 			/*
@@ -4823,6 +4828,24 @@ PostgresMain(const char *dbname, const char *username)
 	pq_flush();
 break;
 
+			case 'r':			/* report GUC */
+{
+	const char	   *name;
+	intcreate_flag;
+
+	name = pq_getmsgstring(_message);
+	create_flag = pq_getmsgint(_message, 2);
+	pq_getmsgend(_message);
+
+	if (create_flag)
+		SetGUCOptionFlag(name, GUC_REPORT);
+	else
+	UnsetGUCOptionFlag(name, GUC_REPORT);
+
+	send_ready_for_query = true;
+}
+break;
+
 			case 'S':			/* sync */
 pq_getmsgend(_message);
 finish_xact_command();
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index ea67cfa5e5..ee8d831e1c 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2532,6 +2532,37 @@ BeginReportingGUCOptions(void)
 	}
 }
 
+/*
+ * Allow to set / unset dynamicaly flags to GUC variables
+ */
+void
+SetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, true, ERROR);
+	conf->flags |= flag;
+
+	if (flag == GUC_REPORT)
+		/* force transmit value of related option to client Parameter Status */
+		ReportGUCOption(conf);
+}
+
+void
+UnsetGUCOptionFlag(const char *name, int flag)
+{
+	struct config_generic *conf;
+
+	/* only GUC_REPORT flag is supported now */
+	Assert(flag == GUC_REPORT);
+
+	conf = find_option(name, false, true, 

Re: proposal: psql: show current user in prompt

2023-04-05 Thread Pavel Stehule
st 5. 4. 2023 v 17:47 odesílatel Robert Haas  napsal:

> On Wed, Apr 5, 2023 at 11:34 AM Pavel Stehule 
> wrote:
> > If the GUC_REPORT should not  be used, then only one possibility is
> enhancing the protocol, about the possibility to read some predefined
> server's features from the client.
> > It can be much cheaper than SQL query, and it can be used when the
> current transaction is aborted. I can imagine a possibility to read server
> time or a server session role from a prompt processing routine.
> >
> > But for this specific case, you need to cache the role name somewhere.
> You can simply get oid everytime, but for role name you need to access to
> system catalogue, and it is not possible in aborted transactions. So at the
> end, you probably should read "role" GUC.
> >
> > Can this design be  acceptable?
>
> I don't think we want to add a dedicated protocol message that says
> "send me the role GUC right now". I mean, we could, but being able to
> tell the GUC mechanism "please send me the role GUC after every
> command" sounds a lot easier to use.
>

I'll try it

Regards

Pavel


>
> --
> Robert Haas
> EDB: http://www.enterprisedb.com
>


Re: proposal: psql: show current user in prompt

2023-04-05 Thread Robert Haas
On Wed, Apr 5, 2023 at 11:34 AM Pavel Stehule  wrote:
> If the GUC_REPORT should not  be used, then only one possibility is enhancing 
> the protocol, about the possibility to read some predefined server's features 
> from the client.
> It can be much cheaper than SQL query, and it can be used when the current 
> transaction is aborted. I can imagine a possibility to read server time or a 
> server session role from a prompt processing routine.
>
> But for this specific case, you need to cache the role name somewhere. You 
> can simply get oid everytime, but for role name you need to access to system 
> catalogue, and it is not possible in aborted transactions. So at the end, you 
> probably should read "role" GUC.
>
> Can this design be  acceptable?

I don't think we want to add a dedicated protocol message that says
"send me the role GUC right now". I mean, we could, but being able to
tell the GUC mechanism "please send me the role GUC after every
command" sounds a lot easier to use.

-- 
Robert Haas
EDB: http://www.enterprisedb.com




Re: proposal: psql: show current user in prompt

2023-04-05 Thread Pavel Stehule
st 5. 4. 2023 v 16:02 odesílatel Robert Haas  napsal:

> On Wed, Apr 5, 2023 at 9:56 AM Tom Lane  wrote:
> > Robert Haas  writes:
> > > On Tue, Apr 4, 2023 at 12:42 PM Tom Lane  wrote:
> > >> Basically, I want to reject this on the grounds that it's not
> > >> useful enough to justify the overhead of marking the "role" GUC
> > >> as GUC_REPORT.
> >
> > > I agree with that. I think we need some method for optionally
> > > reporting values, so that stuff like this can be handled without
> > > adding it to the wire protocol for everyone.
> >
> > It could probably be possible to provide some mechanism for setting
> > GUC_REPORT on specific variables locally within sessions.  I don't
> > think this'd be much of a protocol-break problem, because clients
> > should already be coded to deal gracefully with ParameterStatus messages
> > for variables they don't know.  However, connecting that up to something
> > like a psql prompt feature would still be annoying.  I doubt I'd want
> > to go as far as having psql try to turn on GUC_REPORT automatically
> > if it sees %N in the prompt ...
>
> Oh, I had it in mind that it would do exactly that. And I think that
> should be mediated by a wire protocol message, not a GUC, so that
> users don't mess things up for psql or other clients -- in either
> direction -- via SET commands.
>
>
If the GUC_REPORT should not  be used, then only one possibility is
enhancing the protocol, about the possibility to read some predefined
server's features from the client.
It can be much cheaper than SQL query, and it can be used when the current
transaction is aborted. I can imagine a possibility to read server time or
a server session role from a prompt processing routine.

But for this specific case, you need to cache the role name somewhere. You
can simply get oid everytime, but for role name you need to access to
system catalogue, and it is not possible in aborted transactions. So at the
end, you probably should read "role" GUC.

Can this design be  acceptable?

Regards

Pavel




>
> --
> Robert Haas
> EDB: http://www.enterprisedb.com
>


Re: proposal: psql: show current user in prompt

2023-04-05 Thread Pavel Stehule
st 5. 4. 2023 v 15:56 odesílatel Tom Lane  napsal:

> Robert Haas  writes:
> > On Tue, Apr 4, 2023 at 12:42 PM Tom Lane  wrote:
> >> Basically, I want to reject this on the grounds that it's not
> >> useful enough to justify the overhead of marking the "role" GUC
> >> as GUC_REPORT.
>
> > I agree with that. I think we need some method for optionally
> > reporting values, so that stuff like this can be handled without
> > adding it to the wire protocol for everyone.
>
> It could probably be possible to provide some mechanism for setting
> GUC_REPORT on specific variables locally within sessions.  I don't
> think this'd be much of a protocol-break problem, because clients
> should already be coded to deal gracefully with ParameterStatus messages
> for variables they don't know.  However, connecting that up to something
> like a psql prompt feature would still be annoying.  I doubt I'd want
> to go as far as having psql try to turn on GUC_REPORT automatically
> if it sees %N in the prompt ...
>

I agree with this analyze

Regards

Pavel


>
> regards, tom lane
>


Re: proposal: psql: show current user in prompt

2023-04-05 Thread Robert Haas
On Wed, Apr 5, 2023 at 9:56 AM Tom Lane  wrote:
> Robert Haas  writes:
> > On Tue, Apr 4, 2023 at 12:42 PM Tom Lane  wrote:
> >> Basically, I want to reject this on the grounds that it's not
> >> useful enough to justify the overhead of marking the "role" GUC
> >> as GUC_REPORT.
>
> > I agree with that. I think we need some method for optionally
> > reporting values, so that stuff like this can be handled without
> > adding it to the wire protocol for everyone.
>
> It could probably be possible to provide some mechanism for setting
> GUC_REPORT on specific variables locally within sessions.  I don't
> think this'd be much of a protocol-break problem, because clients
> should already be coded to deal gracefully with ParameterStatus messages
> for variables they don't know.  However, connecting that up to something
> like a psql prompt feature would still be annoying.  I doubt I'd want
> to go as far as having psql try to turn on GUC_REPORT automatically
> if it sees %N in the prompt ...

Oh, I had it in mind that it would do exactly that. And I think that
should be mediated by a wire protocol message, not a GUC, so that
users don't mess things up for psql or other clients -- in either
direction -- via SET commands.

Maybe there's a better way, that just seemed like the obvious design.

-- 
Robert Haas
EDB: http://www.enterprisedb.com




Re: proposal: psql: show current user in prompt

2023-04-05 Thread Tom Lane
Robert Haas  writes:
> On Tue, Apr 4, 2023 at 12:42 PM Tom Lane  wrote:
>> Basically, I want to reject this on the grounds that it's not
>> useful enough to justify the overhead of marking the "role" GUC
>> as GUC_REPORT.

> I agree with that. I think we need some method for optionally
> reporting values, so that stuff like this can be handled without
> adding it to the wire protocol for everyone.

It could probably be possible to provide some mechanism for setting
GUC_REPORT on specific variables locally within sessions.  I don't
think this'd be much of a protocol-break problem, because clients
should already be coded to deal gracefully with ParameterStatus messages
for variables they don't know.  However, connecting that up to something
like a psql prompt feature would still be annoying.  I doubt I'd want
to go as far as having psql try to turn on GUC_REPORT automatically
if it sees %N in the prompt ...

regards, tom lane




Re: proposal: psql: show current user in prompt

2023-04-05 Thread Robert Haas
On Tue, Apr 4, 2023 at 12:42 PM Tom Lane  wrote:
> Basically, I want to reject this on the grounds that it's not
> useful enough to justify the overhead of marking the "role" GUC
> as GUC_REPORT.

I agree with that. I think we need some method for optionally
reporting values, so that stuff like this can be handled without
adding it to the wire protocol for everyone. I don't think we can just
keep adding stuff to the set of things that gets reported for
everyone. It doesn't scale. We need a really good reason to enlarge
the set of values reported for all users, and I don't think this meets
that bar.

-- 
Robert Haas
EDB: http://www.enterprisedb.com




Re: proposal: psql: show current user in prompt

2023-04-04 Thread Pavel Stehule
út 4. 4. 2023 v 21:11 odesílatel Pavel Stehule 
napsal:

>
>
> út 4. 4. 2023 v 20:50 odesílatel Pavel Stehule 
> napsal:
>
>>
>>
>> út 4. 4. 2023 v 19:55 odesílatel Tom Lane  napsal:
>>
>>> Pavel Stehule  writes:
>>> > út 4. 4. 2023 v 18:42 odesílatel Tom Lane  napsal:
>>> >> Basically, I want to reject this on the grounds that it's not
>>> >> useful enough to justify the overhead of marking the "role" GUC
>>> >> as GUC_REPORT.  The problems with it not going to work properly
>>> >> with old servers are an additional reason not to like it.
>>>
>>> > If I understand to next comment correctly, the overhead should not be
>>> too
>>> > big
>>>
>>> Yeah, but how big is the use-case?  The reason I'm skeptical is that
>>> half the time what you're going to get is "none":
>>>
>>> $ psql
>>> psql (16devel)
>>> Type "help" for help.
>>>
>>> regression=# show role;
>>>  role
>>> --
>>>  none
>>> (1 row)
>>>
>>> That's required by SQL spec I believe, but that doesn't make it useful
>>> data to keep in one's prompt.
>>>
>>
>> Who needs it, and who uses different roles, then very quickly uses SET
>> ROLE TO command.
>>
>> But I fully agree so current behavior can be a little bit messy. I like
>> this feature, and I think it can have some benefits. Proposed
>> implementation is minimalistic.
>>
>> One hard problem is translation of the oid of current_user to name. It
>> requires an opened transaction, and then it cannot be postponed to the end
>> of the statement. On the other hand, when the change of role is done inside
>> a nested command, then it should not be visible from the client side.
>>
>> Can you accept the introduction of a new invisible GUC, that can be
>> modified only by SET ROLE TO command when it is executed as top command?
>>
>
> It was stupid idea.
>
> There can be implemented fallbacks. When the role is "none", then the
> :USER can be displayed instead.
>
> It can work, because the custom role "none" is not allowed
>
> (2023-04-04 21:10:25) postgres=# create role none;
> ERROR:  role name "none" is reserved
> LINE 1: create role none;
>
> ?
>
>
attached updated patch

Regards

Pavel



>
>
>
>>
>> Regards
>>
>> Pavel
>>
>>
>>
>>
>>
>>
>>>
>>> regards, tom lane
>>>
>>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 9f72dd29d8..966cce9559 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -2482,6 +2482,7 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
in_hot_standby,
is_superuser,
session_authorization,
+   role,
DateStyle,
IntervalStyle,
TimeZone,
@@ -2496,7 +2497,8 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
9.0;
default_transaction_read_only and
in_hot_standby were not reported by releases before
-   14.)
+   14;
+   role was not reported by releases before 16;)
Note that
server_version,
server_encoding and
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 29bbec2188..98669fc18a 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4540,7 +4540,24 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is set to the database session user name.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 16 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 8062589efd..3eec4768b3 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -4174,7 +4174,7 @@ struct config_string ConfigureNamesString[] =
 		{"role", PGC_USERSET, UNGROUPED,
 			gettext_noop("Sets the current role."),
 			NULL,
-			GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
+			GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
 		},
 		_string,
 		"none",
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..7399bacd5f 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,41 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+		int			minServerMajor;
+		int			serverMajor;
+		const char *rolename;
+
+		/*
+		 * This feature requires GUC 

Re: proposal: psql: show current user in prompt

2023-04-04 Thread Pavel Stehule
út 4. 4. 2023 v 20:50 odesílatel Pavel Stehule 
napsal:

>
>
> út 4. 4. 2023 v 19:55 odesílatel Tom Lane  napsal:
>
>> Pavel Stehule  writes:
>> > út 4. 4. 2023 v 18:42 odesílatel Tom Lane  napsal:
>> >> Basically, I want to reject this on the grounds that it's not
>> >> useful enough to justify the overhead of marking the "role" GUC
>> >> as GUC_REPORT.  The problems with it not going to work properly
>> >> with old servers are an additional reason not to like it.
>>
>> > If I understand to next comment correctly, the overhead should not be
>> too
>> > big
>>
>> Yeah, but how big is the use-case?  The reason I'm skeptical is that
>> half the time what you're going to get is "none":
>>
>> $ psql
>> psql (16devel)
>> Type "help" for help.
>>
>> regression=# show role;
>>  role
>> --
>>  none
>> (1 row)
>>
>> That's required by SQL spec I believe, but that doesn't make it useful
>> data to keep in one's prompt.
>>
>
> Who needs it, and who uses different roles, then very quickly uses SET
> ROLE TO command.
>
> But I fully agree so current behavior can be a little bit messy. I like
> this feature, and I think it can have some benefits. Proposed
> implementation is minimalistic.
>
> One hard problem is translation of the oid of current_user to name. It
> requires an opened transaction, and then it cannot be postponed to the end
> of the statement. On the other hand, when the change of role is done inside
> a nested command, then it should not be visible from the client side.
>
> Can you accept the introduction of a new invisible GUC, that can be
> modified only by SET ROLE TO command when it is executed as top command?
>

It was stupid idea.

There can be implemented fallbacks. When the role is "none", then the :USER
can be displayed instead.

It can work, because the custom role "none" is not allowed

(2023-04-04 21:10:25) postgres=# create role none;
ERROR:  role name "none" is reserved
LINE 1: create role none;

?




>
> Regards
>
> Pavel
>
>
>
>
>
>
>>
>> regards, tom lane
>>
>


Re: proposal: psql: show current user in prompt

2023-04-04 Thread Pavel Stehule
út 4. 4. 2023 v 19:55 odesílatel Tom Lane  napsal:

> Pavel Stehule  writes:
> > út 4. 4. 2023 v 18:42 odesílatel Tom Lane  napsal:
> >> Basically, I want to reject this on the grounds that it's not
> >> useful enough to justify the overhead of marking the "role" GUC
> >> as GUC_REPORT.  The problems with it not going to work properly
> >> with old servers are an additional reason not to like it.
>
> > If I understand to next comment correctly, the overhead should not be too
> > big
>
> Yeah, but how big is the use-case?  The reason I'm skeptical is that
> half the time what you're going to get is "none":
>
> $ psql
> psql (16devel)
> Type "help" for help.
>
> regression=# show role;
>  role
> --
>  none
> (1 row)
>
> That's required by SQL spec I believe, but that doesn't make it useful
> data to keep in one's prompt.
>

Who needs it, and who uses different roles, then very quickly uses SET ROLE
TO command.

But I fully agree so current behavior can be a little bit messy. I like
this feature, and I think it can have some benefits. Proposed
implementation is minimalistic.

One hard problem is translation of the oid of current_user to name. It
requires an opened transaction, and then it cannot be postponed to the end
of the statement. On the other hand, when the change of role is done inside
a nested command, then it should not be visible from the client side.

Can you accept the introduction of a new invisible GUC, that can be
modified only by SET ROLE TO command when it is executed as top command?

Regards

Pavel






>
> regards, tom lane
>


Re: proposal: psql: show current user in prompt

2023-04-04 Thread Tom Lane
Pavel Stehule  writes:
> út 4. 4. 2023 v 18:42 odesílatel Tom Lane  napsal:
>> Basically, I want to reject this on the grounds that it's not
>> useful enough to justify the overhead of marking the "role" GUC
>> as GUC_REPORT.  The problems with it not going to work properly
>> with old servers are an additional reason not to like it.

> If I understand to next comment correctly, the overhead should not be too
> big

Yeah, but how big is the use-case?  The reason I'm skeptical is that
half the time what you're going to get is "none":

$ psql
psql (16devel)
Type "help" for help.

regression=# show role;
 role 
--
 none
(1 row)

That's required by SQL spec I believe, but that doesn't make it useful
data to keep in one's prompt.

regards, tom lane




Re: proposal: psql: show current user in prompt

2023-04-04 Thread Pavel Stehule
út 4. 4. 2023 v 18:42 odesílatel Tom Lane  napsal:

> Kirk Wolak  writes:
> > Changed status to Ready for Committer. (100% Guessing here...)
>
> Basically, I want to reject this on the grounds that it's not
> useful enough to justify the overhead of marking the "role" GUC
> as GUC_REPORT.  The problems with it not going to work properly
> with old servers are an additional reason not to like it.
>

If I understand to next comment correctly, the overhead should not be too
big

/*
 * ReportChangedGUCOptions: report recently-changed GUC_REPORT variables
 *
 * This is called just before we wait for a new client query.
 *
 * By handling things this way, we ensure that a ParameterStatus message
 * is sent at most once per variable per query, even if the variable
 * changed multiple times within the query.  That's quite possible when
 * using features such as function SET clauses.  Function SET clauses
 * also tend to cause values to change intraquery but eventually revert
 * to their prevailing values; ReportGUCOption is responsible for avoiding
 * redundant reports in such cases.
 */



>
> But, if I lose the argument and we do commit this, I think it
> should just print an empty string when dealing with an old server.
> "ERR02000" is an awful idea, not least because it could be a
> real role name.
>

ok


>
> BTW, we should probably get rid of the PQuser() fallback in
> %n (session_username()) as well.  It's unlikely that there are
> still servers in the wild that don't report "session_authorization",
> but if we did find one then the output is potentially misleading.
> I'd rather print nothing than something that might not be your
> actual session authorization setting.
>

It should be a separate patch?

Updated patch attached

Regards

Pavel



>
> regards, tom lane
>
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 9f72dd29d8..966cce9559 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -2482,6 +2482,7 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
in_hot_standby,
is_superuser,
session_authorization,
+   role,
DateStyle,
IntervalStyle,
TimeZone,
@@ -2496,7 +2497,8 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
9.0;
default_transaction_read_only and
in_hot_standby were not reported by releases before
-   14.)
+   14;
+   role was not reported by releases before 16;)
Note that
server_version,
server_encoding and
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 29bbec2188..330c085329 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4540,7 +4540,26 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is none. The value is same like
+  the value of the parameter role (can be
+  displayed by SHOW.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 15 and up. When you use older version, the empty string
+  is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 8062589efd..3eec4768b3 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -4174,7 +4174,7 @@ struct config_string ConfigureNamesString[] =
 		{"role", PGC_USERSET, UNGROUPED,
 			gettext_noop("Sets the current role."),
 			NULL,
-			GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
+			GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
 		},
 		_string,
 		"none",
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..a304fe1868 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,35 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+		int			minServerMajor;
+		int			serverMajor;
+		const char *val;
+
+		/*
+		 * This feature requires GUC "role" to be marked
+		 * as GUC_REPORT. Without it is hard to specify fallback
+		 * result. Returning empty value can be messy, returning
+		 * PQuser like session_username can be messy too.
+		 * Exec query is not too practical too, because it doesn't
+		 * work when session is not in transactional state, and
+		 * 

Re: proposal: psql: show current user in prompt

2023-04-04 Thread Tom Lane
Kirk Wolak  writes:
> Changed status to Ready for Committer. (100% Guessing here...)

Basically, I want to reject this on the grounds that it's not
useful enough to justify the overhead of marking the "role" GUC
as GUC_REPORT.  The problems with it not going to work properly
with old servers are an additional reason not to like it.

But, if I lose the argument and we do commit this, I think it
should just print an empty string when dealing with an old server.
"ERR02000" is an awful idea, not least because it could be a
real role name.

BTW, we should probably get rid of the PQuser() fallback in
%n (session_username()) as well.  It's unlikely that there are
still servers in the wild that don't report "session_authorization",
but if we did find one then the output is potentially misleading.
I'd rather print nothing than something that might not be your
actual session authorization setting.

regards, tom lane




Re: proposal: psql: show current user in prompt

2023-03-02 Thread Kirk Wolak
On Sat, Feb 4, 2023 at 3:33 PM Pavel Stehule 
wrote:

> Hi
>
> pá 3. 2. 2023 v 21:43 odesílatel Pavel Stehule 
> napsal:
>
>>
>>
>> pá 3. 2. 2023 v 21:21 odesílatel Tom Lane  napsal:
>>
>>> Pavel Stehule  writes:
>>> > Both patches are very simple - and they use almost already prepared
>>> > infrastructure.
>>>
>>> It's not simple at all to make the psql feature depend on marking
>>> "role" as GUC_REPORT when it never has been before.  That will
>>> cause the feature to misbehave when using older servers.  I'm
>>> even less impressed by having it fall back on PQuser(), which
>>> would be misleading at exactly the times when it matters.
>>>
>>
>> It is a good note. This can be disabled for older servers, and maybe it
>> can  introduce its own GUC (and again - it can be disallowed for older
>> servers).
>>
>
> Here is another version. For older servers it shows the string ERR0A000.
> That is  ERR code of "feature is not supported"
>
>
>> My goal at this moment is to get some prototype. We can talk if this
>> feature request is valid or not, and we can talk about implementation.
>>
>> There is another possibility to directly execute "select current_user()"
>> instead of looking at status parameters inside prompt processing. It can
>> work too.
>>
>
> I tested using the query SELECT CURRENT_USER, but I don't think it is
> usable now, because it doesn't work in the broken transaction.
>
> Regards
>
> Pavel
>
>
>
>>
>> Regards
>>
>> Pavel
>>
>>
>>
>>
>>
>>> regards, tom lane
>>>
>>
I've tested this w/regards to psql.  Latest commit.
It works as described.  'none' is displayed for the default role. (SET ROLE
DEFAULT), otherwise the specific ROLE is displayed.

I tried this patch on 15.2, but guc_files.c does not exist in that version,
so it did not install.
I also tried applying the %T patch, but since they touch the same file, it
would not install with it, without rebasing, repatching.

The Docs are updated, and it's a relatively contained patch.

Changed status to Ready for Committer. (100% Guessing here...)

Kirk


Re: proposal: psql: show current user in prompt

2023-02-04 Thread Pavel Stehule
Hi

pá 3. 2. 2023 v 21:43 odesílatel Pavel Stehule 
napsal:

>
>
> pá 3. 2. 2023 v 21:21 odesílatel Tom Lane  napsal:
>
>> Pavel Stehule  writes:
>> > Both patches are very simple - and they use almost already prepared
>> > infrastructure.
>>
>> It's not simple at all to make the psql feature depend on marking
>> "role" as GUC_REPORT when it never has been before.  That will
>> cause the feature to misbehave when using older servers.  I'm
>> even less impressed by having it fall back on PQuser(), which
>> would be misleading at exactly the times when it matters.
>>
>
> It is a good note. This can be disabled for older servers, and maybe it
> can  introduce its own GUC (and again - it can be disallowed for older
> servers).
>

Here is another version. For older servers it shows the string ERR0A000.
That is  ERR code of "feature is not supported"


> My goal at this moment is to get some prototype. We can talk if this
> feature request is valid or not, and we can talk about implementation.
>
> There is another possibility to directly execute "select current_user()"
> instead of looking at status parameters inside prompt processing. It can
> work too.
>

I tested using the query SELECT CURRENT_USER, but I don't think it is
usable now, because it doesn't work in the broken transaction.

Regards

Pavel



>
> Regards
>
> Pavel
>
>
>
>
>
>> regards, tom lane
>>
>
From 3b42bd47db4488f320b166d4c580193bd2c02de8 Mon Sep 17 00:00:00 2001
From: "ok...@github.com" 
Date: Sat, 4 Feb 2023 21:16:30 +0100
Subject: [PATCH] implementation of psql prompt substitution %N

this substitution shows used role specified by command SET ROLE.
it can show string ERRA (SQL code - feature not supported)
when the variable "role" is not reported (PostgreSQL 15 and older).
---
 doc/src/sgml/libpq.sgml |  4 +++-
 doc/src/sgml/ref/psql-ref.sgml  | 21 +++-
 src/backend/utils/misc/guc_tables.c |  2 +-
 src/bin/psql/prompt.c   | 37 +
 4 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 0e7ae70c70..6a2f92b368 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -2270,6 +2270,7 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
in_hot_standby,
is_superuser,
session_authorization,
+   role,
DateStyle,
IntervalStyle,
TimeZone,
@@ -2284,7 +2285,8 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName);
9.0;
default_transaction_read_only and
in_hot_standby were not reported by releases before
-   14.)
+   14;
+   role was not reported by releases before 16;)
Note that
server_version,
server_encoding and
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index dc6528dc11..5e313f06ab 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4509,7 +4509,26 @@ testdb= INSERT INTO my_table VALUES (:'content');
 The port number at which the database server is listening.
   
 
-  
+  
+%N
+
+ 
+  The database role name. This value is specified by command
+  SET ROLE. Until execution of this command
+  the value is none. The value is same like
+  the value of the parameter role (can be
+  displayed by SHOW.
+ 
+
+ 
+  This substitution requires PostgreSQL
+  version 15 and up. When you use older version, the error value
+  ERR0A000 is used instead.
+ 
+
+  
+
+  
 %n
 
  
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index b46e3b8c55..3188fd015d 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -4144,7 +4144,7 @@ struct config_string ConfigureNamesString[] =
 		{"role", PGC_USERSET, UNGROUPED,
 			gettext_noop("Sets the current role."),
 			NULL,
-			GUC_IS_NAME | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
+			GUC_IS_NAME | GUC_REPORT | GUC_NO_SHOW_ALL | GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_NOT_WHILE_SEC_REST
 		},
 		_string,
 		"none",
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 969cd9908e..ef720c8496 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -165,6 +165,43 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 	if (pset.db)
 		strlcpy(buf, session_username(), sizeof(buf));
 	break;
+	/* DB server user role */
+case 'N':
+	if (pset.db)
+	{
+		int			minServerMajor;
+		int			serverMajor;
+
+		/*
+		 * This feature requires GUC "role" to be marked
+		 * as GUC_REPORT. Without it is hard to specify fallback
+		 * result. Returning 

Re: proposal: psql: show current user in prompt

2023-02-03 Thread Pavel Stehule
pá 3. 2. 2023 v 21:21 odesílatel Tom Lane  napsal:

> Pavel Stehule  writes:
> > Both patches are very simple - and they use almost already prepared
> > infrastructure.
>
> It's not simple at all to make the psql feature depend on marking
> "role" as GUC_REPORT when it never has been before.  That will
> cause the feature to misbehave when using older servers.  I'm
> even less impressed by having it fall back on PQuser(), which
> would be misleading at exactly the times when it matters.
>

It is a good note. This can be disabled for older servers, and maybe it
can  introduce its own GUC (and again - it can be disallowed for older
servers).

My goal at this moment is to get some prototype. We can talk if this
feature request is valid or not, and we can talk about implementation.

There is another possibility to directly execute "select current_user()"
instead of looking at status parameters inside prompt processing. It can
work too.

Regards

Pavel





> regards, tom lane
>


Re: proposal: psql: show current user in prompt

2023-02-03 Thread Tom Lane
Pavel Stehule  writes:
> Both patches are very simple - and they use almost already prepared
> infrastructure.

It's not simple at all to make the psql feature depend on marking
"role" as GUC_REPORT when it never has been before.  That will
cause the feature to misbehave when using older servers.  I'm
even less impressed by having it fall back on PQuser(), which
would be misleading at exactly the times when it matters.

regards, tom lane




Re: proposal: psql: show current user in prompt

2023-02-03 Thread Pavel Stehule
pá 3. 2. 2023 v 20:42 odesílatel Corey Huinker 
napsal:

>
>
> On Fri, Feb 3, 2023 at 9:56 AM Pavel Stehule 
> wrote:
>
>> Hi
>>
>> one visitor of p2d2 (Prague PostgreSQL Developer Day) asked if it is
>> possible to show the current role in psql's prompt. I think it is not
>> possible, but fortunately (with some limits) almost all necessary work is
>> done, and the patch is short.
>>
>> In the assigned patch I implemented a new prompt placeholder %N, that
>> shows the current role name.
>>
>> (2023-02-03 15:52:28) postgres=# \set PROMPT1 '%n as %N at '%/%=%#
>> pavel as pavel at postgres=#set role to admin;
>> SET
>> pavel as admin at postgres=>set role to default;
>> SET
>> pavel as pavel at postgres=#
>>
>> Comments, notes are welcome.
>>
>> Regards
>>
>> Pavel
>>
>
> This patch is cluttered with the BACKEND_PID patch and some guc_tables.c
> stuff that I don't think is related.
>

I was little bit lazy, I am sorry. I did it in one my experimental branch.
Both patches are PoC, and there are not documentation yet. I will separate
it.


> We'd have to document the %N.
>
> I think there is some value here for people who have to connect as several
> different users (tech support), and need a reminder-at-a-glance whether
> they are operating in the desired role. It may be helpful in audit
> documentation as well.
>

 yes, I agree so it can be useful - it is not my idea - and it is maybe
partially deduced from some other databases.

Both patches are very simple - and they use almost already prepared
infrastructure.

Regards

Pavel


Re: proposal: psql: show current user in prompt

2023-02-03 Thread Corey Huinker
On Fri, Feb 3, 2023 at 9:56 AM Pavel Stehule 
wrote:

> Hi
>
> one visitor of p2d2 (Prague PostgreSQL Developer Day) asked if it is
> possible to show the current role in psql's prompt. I think it is not
> possible, but fortunately (with some limits) almost all necessary work is
> done, and the patch is short.
>
> In the assigned patch I implemented a new prompt placeholder %N, that
> shows the current role name.
>
> (2023-02-03 15:52:28) postgres=# \set PROMPT1 '%n as %N at '%/%=%#
> pavel as pavel at postgres=#set role to admin;
> SET
> pavel as admin at postgres=>set role to default;
> SET
> pavel as pavel at postgres=#
>
> Comments, notes are welcome.
>
> Regards
>
> Pavel
>

This patch is cluttered with the BACKEND_PID patch and some guc_tables.c
stuff that I don't think is related.

We'd have to document the %N.

I think there is some value here for people who have to connect as several
different users (tech support), and need a reminder-at-a-glance whether
they are operating in the desired role. It may be helpful in audit
documentation as well.