Thread

Commits

  1. Ignore not-yet-defined Portals in pg_cursors view.

  1. Server crash when selecting from pg_cursors

    PetSerAl <petseral@gmail.com> — 2024-10-06T16:15:10Z

    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:  server process (PID 22552) was terminated by exception 0xC0000005
    [21932] DETAIL:  Failed process was running: DO $$
            DECLARE
                    a integer;
            BEGIN
                    FOR a IN SELECT t.a FROM t WHERE t.b = f() LOOP
                    END LOOP;
            END
            $$;
    [21932] HINT:  See C include file "ntstatus.h" for a description of
    the hexadecimal value.
    [21932] LOG:  terminating any other active server processes
    [21932] LOG:  all server processes terminated; reinitializing
    
    
    
    
  2. Re: Server crash when selecting from pg_cursors

    Tom Lane <tgl@sss.pgh.pa.us> — 2024-10-06T18:08:25Z

    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