BUG #18190: PL/pgSQL does not document comparison operations on RECORD (or ROW) types - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #18190: PL/pgSQL does not document comparison operations on RECORD (or ROW) types
Date
Msg-id 18190-ba5eff0af347078d@postgresql.org
Whole thread Raw
Responses Re: BUG #18190: PL/pgSQL does not document comparison operations on RECORD (or ROW) types
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      18190
Logged by:          Karl Pinc
Email address:      kop@karlpinc.com
PostgreSQL version: 15.4
Operating system:   Linux
Description:

Nothing is said about how to compare entire RECORD type variables, or ROW
type variables.

This leads to surprising behavior in the code below.  The row in table "foo"
that has foo.col2 = NULL does not raise an error, but the row that has
foo.col2 = 1 does.

CREATE OR REPLACE FUNCTION checktime (tbl TEXT, col TEXT)
  RETURNS void
  LANGUAGE plpgsql
  AS $$
  DECLARE
    qry TEXT;
    problem RECORD := NULL;
  BEGIN
    qry := '
    SELECT *
      FROM ' || quote_ident(tbl) || '
      WHERE ' || quote_ident(col) || '::TIME <> $tim$00:00:00$tim$';
    EXECUTE qry INTO problem;
    IF problem IS NOT NULL THEN
      RAISE EXCEPTION data_exception USING
            MESSAGE = tbl
                      || ' has a time part in column '
                      || col
                      || ' that is not 00:00:00'
          , DETAIL = 'The row is: ' || problem;
    END IF;
  END;
$$;

CREATE TABLE foo (stamp TIMESTAMP WITHOUT TIME ZONE, col2 INT NULL);

INSERT INTO foo (stamp, col2) VALUES ('1979-01-01 00:01:00', NULL);

SELECT checktime('foo', 'stamp');

TRUNCATE foo;

INSERT INTO foo (stamp, col2) VALUES ('1979-01-01 00:01:00', 1);

SELECT checktime('foo', 'stamp');

Probably the right way to write the code is with GET DIAGNOSTICS..., but
that's neither here nor there.

Or maybe an error should be raised when trying to use IS NULL with RECORD
type variables.  Or the code needs changing so IS NULL/IS NOT NULL works
with RECORD type variables.  Or something else needs doing.

Note that I've not tried anything with ROW type variables but it seems worth
mentioning them since it's not obvious how to tell if they've ever been
assigned a value, which is vaguely related to the intention of the code
above.  Likewise, equality comparisons on ROWs and RECORDs (not mixed) seem
like they should work, but what of other comparisions?

If the issue is documentation, the PL/pgSQL docs should link to the
composite type docs, or the expression docs, or type conversion, or where
ever the current documentation is that I can't find or that needs to be
written.


pgsql-bugs by date:

Previous
From: Tom Lane
Date:
Subject: Re: BUG #18189: Value partitioned tables: Upd ERROR: more than one row returned by a subquery used as an expression
Next
From: Alexander Korotkov
Date:
Subject: Re: BUG #18187: Unexpected error: "variable not found in subplan target lists" triggered by JOIN