identity column behavior in WHEN condition for BEFORE EACH ROW trigger

From: Suraj Kharage <suraj(dot)kharage(at)enterprisedb(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: identity column behavior in WHEN condition for BEFORE EACH ROW trigger
Date: 2019-10-03 14:08:21
Message-ID: CAF1DzPUp2c0F7YxH22VJzEsOoEMdJrq-Yt-3TcDYQVSZ0NT02g@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

It is been observed that when we define the generated columns in WHEN
condition for BEFORE EACH ROW trigger then server throw an error from
CreateTrigger().

e.g:
create table bar(a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2)
STORED);

CREATE OR REPLACE FUNCTION test() RETURNS trigger AS $$
BEGIN
NEW.b = 10;
raise notice 'Before row trigger';
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

postgres(at)78049=#CREATE TRIGGER bar_trigger
BEFORE INSERT ON bar
FOR EACH ROW
*WHEN (NEW.b < 8)*
EXECUTE FUNCTION test();
2019-10-03 19:25:29.945 IST [78049] ERROR: *BEFORE trigger's WHEN
condition cannot reference NEW generated columns* at character 68
2019-10-03 19:25:29.945 IST [78049] DETAIL: Column "b" is a generated
column.
2019-10-03 19:25:29.945 IST [78049] STATEMENT: CREATE TRIGGER bar_trigger
BEFORE INSERT ON bar
FOR EACH ROW
WHEN (NEW.b < 8)
EXECUTE FUNCTION test();
ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated
columns
LINE 4: WHEN (NEW.b < 8)
^
DETAIL: Column "b" is a generated column.

whereas, for identity columns, server allows us to create trigger for same
and trigger gets invoked as defined. Is this behavior expected? or we need
to restrict the identity columns in such scenario because anyone one
override the identity column value in trigger.

e.g:

create table foo(no int, id int generated always as identity);

CREATE OR REPLACE FUNCTION test() RETURNS trigger AS $$
BEGIN
NEW.id = 10;
raise notice 'Before row trigger';
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER foo_trigger
BEFORE INSERT ON foo
FOR EACH ROW
WHEN (NEW.id < 8)
EXECUTE FUNCTION test();

postgres(at)78049=#insert into foo values(1);
*NOTICE: Before row trigger*
INSERT 0 1
postgres(at)78049=#select * from foo;
no | id
----+----
1 | *10*
(1 row)

Thoughts?

--
--

Thanks & Regards,
Suraj kharage,
EnterpriseDB Corporation,
The Postgres Database Company.

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2019-10-03 14:18:04 Re: WIP: Generic functions for Node types using generated metadata
Previous Message Euler Taveira 2019-10-03 14:01:00 Re: Regarding extension