Server crash when selecting from pg_cursors

Started by PetSerAlover 1 year ago2 messagesbugs
Jump to latest
#1PetSerAl
petseral@gmail.com

postgres=# SELECT version();
version
-------------------------------------------------------------------------
PostgreSQL 17.0 on x86_64-windows, compiled by msvc-19.41.34120, 64-bit
(1 row)

postgres=# CREATE TABLE t (a integer, b integer);
CREATE TABLE
postgres=# CREATE FUNCTION f() RETURNS integer
postgres-# STABLE STRICT LANGUAGE plpgsql
postgres-# AS $$
postgres$# BEGIN
postgres$# PERFORM FROM pg_cursors;
postgres$# RETURN null;
postgres$# END
postgres$# $$;
CREATE FUNCTION
postgres=# DO $$
postgres$# DECLARE
postgres$# a integer;
postgres$# BEGIN
postgres$# FOR a IN SELECT t.a FROM t WHERE t.b = f() LOOP
postgres$# END LOOP;
postgres$# END
postgres$# $$;
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
The connection to the server was lost. Attempting reset: Failed.
!?>

Server log:
[21932]: LOG: all server processes terminated; reinitializing
[21932]: LOG: all server processes terminated; reinitializing
DECLARE
a integer;
BEGIN
FOR a IN SELECT t.a FROM t WHERE t.b = f() LOOP
END LOOP;
END
$$;
[21932]: LOG: all server processes terminated; reinitializing
the hexadecimal value.
[21932]: LOG: all server processes terminated; reinitializing
[21932]: LOG: all server processes terminated; reinitializing

#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: PetSerAl (#1)
Re: Server crash when selecting from pg_cursors

PetSerAl <petseral@gmail.com> writes:

postgres=# CREATE TABLE t (a integer, b integer);
CREATE TABLE
postgres=# CREATE FUNCTION f() RETURNS integer
postgres-# STABLE STRICT LANGUAGE plpgsql
postgres-# AS $$
postgres$# BEGIN
postgres$# PERFORM FROM pg_cursors;
postgres$# RETURN null;
postgres$# END
postgres$# $$;
CREATE FUNCTION
postgres=# DO $$
postgres$# DECLARE
postgres$# a integer;
postgres$# BEGIN
postgres$# FOR a IN SELECT t.a FROM t WHERE t.b = f() LOOP
postgres$# END LOOP;
postgres$# END
postgres$# $$;
server closed the connection unexpectedly

Huh, nice one. It's not new in v17 though --- it seems quite ancient.
The proximate cause is that pg_cursor() is assuming portal->sourceText
can't be NULL:

values[1] = CStringGetTextDatum(portal->sourceText);

which is not unreasonable considering that portal.h quoth

const char *sourceText; /* text of query (as of 8.4, never NULL) */

But there's a problem: we may be examining a portal that has been
added to the portal hashtable, but for which PortalDefineQuery
hasn't been called yet.

There are a few ways we might try to deal with this, but I think
the most reasonable one is to make pg_cursor() ignore portals
that haven't been defined yet, as attached.

regards, tom lane

Attachments:

harden-pg_cursor-against-null-sourceText.patchtext/x-diff; charset=us-ascii; name=harden-pg_cursor-against-null-sourceText.patchDownload+3-0