Re: libpq: unexpected return code from PQexecParams with a DO INSTEAD rule present

From: Aleksander Alekseev <aleksander(at)timescale(dot)com>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org
Cc: Vasilii Smirnov <vasilii(dot)smirnov(at)mailbox(dot)org>
Subject: Re: libpq: unexpected return code from PQexecParams with a DO INSTEAD rule present
Date: 2024-07-17 13:58:26
Message-ID: CAJ7c6TOs2MEoXrtffyHob5XM7QK8fb24=3EJ0LnR5r0KnuymSw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi Vasilii,

> > Let's say I have a table "_users", and also a view "users" that excludes
> > all soft-deleted records from that table:
> >
> > [...]
>
> Thanks for the report. Here is what I discovered so far.
>
> [...]

Ok, this has to do with different code paths of the different protocols.

PQexec() uses the simple query protocol. Corresponding function
exec_simple_query() just creates a receiver using CreateDestReceiver()
and passes it to PortalRun(). Corresponding callbacks of the receiver
printtup_startup() / printtup() have the access to TupleDesc and most
importantly don't rely on the value of portal->tupDesc. This is why
PQexec always works as you expect.

PQexecParams() uses the extended query protocol that works
differently. PqMsg_NoData message you get is an answer on
PqMsg_Describe ("describe the portal"). Note that you are sending
PqMsg_Describe when the portal is not yet executed. This PqMsg_NoData
response comes from the corresponding message handler,
exec_describe_portal_message(). This handler *does* rely on
portal->tupDesc, because it's all it has access to. And this value is
different depending on whether you access a regular table or a VIEW.

For a regular table ChoosePortalStrategy() returns
PORTAL_ONE_RETURNING and PortalStart() sets portal->tupDesc. For VIEWs
ChoosePortalStrategy() returns PORTAL_MULTI_QUERY and portal->tupDesc
is set to NULL. This is why you get different results for a regular
table and a VIEW when using PQexecParams() and the extended query
protocol.

It seems to me that we have several options now:

1. Claim that this is not a bug. To my knowledge, simple query
protocol never committed to behave identically to the extended query
protocol.

2. Teach the code to process this case differently than it does now.
In theory, during the Bind phase, when PortalStart() and
ChoosePortalStrategy() are called, we already have a query plan where
the rewrite rules are applied. So we should be able to deduce what
will actually happen when querying the VIEW.

3. Claim that we could do (2) but it isn't worth an effort and invest
our resources into working on something else.

Thoughts?

--
Best regards,
Aleksander Alekseev

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message 1165125080 2024-07-17 14:55:58 RE:BUG #18533: pg_basebackup uses out-of-bounds memory and a segment error occurs during backup
Previous Message PG Bug reporting form 2024-07-17 12:53:39 BUG #18543: Mistake in docs example