I am writing a PostgreSQL trigger function that will allow me to do an ETL transformation on a data.
I have a table with fields (id, price, EFF_FROM, EFF_TO), and if I only insert (id, price, EFF_FROM), EFF_TO needs to be calculated automatically as the next EFF_FROM of this id (-1 day) if it exists, and "5999-12-31" if it does not.
To update the table, I am using UPDATE ... FROM inside of a trigger function, but it seems to update all EFF_TO values in the table with the last given EFF_FROM value.
The trigger function that I use looks like this:
CREATE OR REPLACE FUNCTION prices_schema.prices_etl() RETURNS TRIGGER AS $$
BEGIN
    UPDATE prices_schema.prices
    SET EFF_TO = subquery.next_eff_from
    FROM (
        SELECT COALESCE(
            LEAD(EFF_FROM, 1)
            OVER (
                ORDER BY EFF_FROM ASC
            ),
            TO_DATE('6000-00-00', 'YYYY-MM-DD')
        ) - 1 AS next_eff_from FROM prices_schema.prices
    ) AS subquery;
    
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE TRIGGER after_insert_prices
AFTER INSERT ON prices_schema.prices
FOR EACH ROW EXECUTE PROCEDURE prices_schema.prices_etl();
Load some test data:
INSERT INTO prices_schema.prices(id, Price, EFF_FROM)
    VALUES(1, 100, '2017-01-12');
    
INSERT INTO prices_schema.prices(id, Price, EFF_FROM)
    VALUES(1, 150, '2017-02-09');
    
INSERT INTO prices_schema.prices(id, Price, EFF_FROM)
    VALUES(1, 125, '2017-01-27');
Execute:
SELECT * FROM prices_schema.prices
    ORDER BY EFF_FROM ASC;
Result:
| id | price | EFF_FROM | EFF_TO | 
|---|---|---|---|
| 1 | 100 | 2017-01-12 | 2017-01-26 | 
| 1 | 125 | 2017-01-27 | 2017-01-26 | 
| 1 | 150 | 2017-02-09 | 2017-01-26 | 
EFF_TO obviously doesn't look as expected to. What amazes me more is that calling this query:
SELECT eff_from, COALESCE(
            LEAD(EFF_FROM, 1)
            OVER (
                ORDER BY EFF_FROM ASC
            ),
            TO_DATE('6000-00-00', 'YYYY-MM-DD')
        ) - 1 AS next_eff_from FROM prices_schema.prices;
Gives me the correct result:
| EFF_FROM | next_eff_from | 
|---|---|
| 2017-01-12 | 2017-01-26 | 
| 2017-01-27 | 2017-02-08 | 
| 2017-02-09 | 5999-12-31 | 
I bet this has something to do with how triggers & trigger functions work, but I wasn't able to find the right thing. I would like to be pointed out in the right direction.
 
     
    