Re: BUG #16862: Unexpected result of checking for null "IS NOT NULL" in function

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Дмитрий Иванов <firstdismay(at)gmail(dot)com>
Cc: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #16862: Unexpected result of checking for null "IS NOT NULL" in function
Date: 2021-02-12 18:57:48
Message-ID: 1561481.1613156268@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

=?UTF-8?B?0JTQvNC40YLRgNC40Lkg0JjQstCw0L3QvtCy?= <firstdismay(at)gmail(dot)com> writes:
> CREATE TABLE "public"."test" (
> "id" Bigint NOT NULL,
> "name" Character Varying NOT NULL,
> PRIMARY KEY ( "id" ) );
> -- -------------------------------------------------------------
> INSERT INTO "public"."test" ( "id", "name")
> VALUES ( 1, 'sdsdsdsdsd' );
> CREATE OR REPLACE VIEW "public"."vtest" AS SELECT test.id,
> test.name
> FROM test;;

> -- CREATE FUNCTION "class_is_actual3( int8, timestamp, timestamp )"
> CREATE OR REPLACE FUNCTION test_is_null_id(iid bigint, OUT tr BOOLEAN, OUT
> vr BOOLEAN)
> RETURNS RECORD
> LANGUAGE plpgsql
> AS $function$
> DECLARE
> t "test"%ROWTYPE;
> v "vtest"%ROWTYPE;

> BEGIN
> SELECT * INTO t FROM ONLY test WHERE id = iid;
> SELECT * INTO v FROM ONLY vtest WHERE id = iid;

> IF t IS NOT NULL THEN
> tr = true;
> ELSE
> tr = false;
> END IF;

> IF v IS NOT NULL THEN
> vr = true;
> ELSE
> vr = false;
> END IF;
> END;
> $function$;
> -- -------------------------------------------------------------
> SELECT * FROM test_is_null_id(1);

> ALTER TABLE "public"."test" ADD COLUMN "New_olumn" Bigint[] NULL;

> SELECT * FROM test_is_null_id(1);

OK, I appreciate the test case, but as far as I can see the database
is doing exactly what it's supposed to. After the ALTER ADD COLUMN
we have

# table test;
id | name | New_olumn
----+------------+-----------
1 | sdsdsdsdsd |
(1 row)

# table vtest;
id | name
----+------------
1 | sdsdsdsdsd
(1 row)

# SELECT * FROM test_is_null_id(1);
tr | vr
----+----
f | t
(1 row)

That looks fine to me: "test" now contains a column that is null,
so it doesn't pass the IS NOT NULL test. On the other hand,
"vtest" doesn't contain that column; all its columns are still non
null, so it does pass the IS NOT NULL test.

Note that "foo IS NOT NULL" is not the same as "NOT (foo IS NULL)"
when foo is of composite type. I agree that's confusing, but it's
required by the SQL spec. See
https://www.postgresql.org/docs/12/functions-comparison.html

regards, tom lane

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message PG Bug reporting form 2021-02-12 19:00:01 BUG #16863: Assert failed in set_plain_rel_size() on processing ~* with a long prefix
Previous Message David G. Johnston 2021-02-12 18:34:43 Re: BUG #16862: Unexpected result of checking for null "IS NOT NULL" in function