add batch remove batch split batch comment selection show hidden batches hide batch highlight batch
db<>fiddle
donate feedback about
By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
Help with an interesting Postgres question: Why isn't an Index Only Scan used on a partition accessed via the parent table?.
CREATE TABLE prices (
prices_id serial PRIMARY KEY
, id int
, price int
, eff_from date
, eff_to date
);
CREATE TABLE
CREATE OR REPLACE FUNCTION prices_set_all_eff_to()
RETURNS trigger
LANGUAGE plpgsql AS
$func$
BEGIN
UPDATE prices p
SET eff_to = COALESCE(p1.next_eff_to, 'infinity')
FROM news n
LEFT JOIN LATERAL (
SELECT p1.eff_from - 1 AS next_eff_to
FROM prices p1
WHERE p1.id = n.id
AND p1.eff_from > n.eff_from
ORDER BY p1.eff_from
LIMIT 1
) p1 ON true
WHERE n.eff_to IS NULL
AND p.prices_id = n.prices_id;

RETURN NULL; -- for statement-level trigger
END
$func$;

CREATE TRIGGER after_insert_prices
AFTER INSERT ON prices
REFERENCING NEW TABLE AS news -- transition table
FOR EACH STATEMENT
EXECUTE FUNCTION prices_set_all_eff_to();
CREATE FUNCTION
CREATE TRIGGER
-- multi-row (!) inserts work as desired: all rows are visible to all
INSERT INTO prices(id, price, eff_from) VALUES
(1, 100, '2017-01-12')
, (1, 150, '2017-02-09')
, (1, 125, '2017-01-27')
RETURNING *; -- NOTE how RETURNING does not show effects of AFTER trigger, yet!
prices_id id price eff_from eff_to
1 1 100 2017-01-12 null
2 1 150 2017-02-09 null
3 1 125 2017-01-27 null
INSERT 0 3
-- ... even when mixing with pre-existing rows
INSERT INTO prices(id, price, eff_from) VALUES
(1, 200, '2017-01-13')
, (1, 250, '2017-02-08')
, (1, 225, '2017-01-28')
;
INSERT 0 3
-- But pre-existing rows are not changed!
INSERT INTO prices(id, price, eff_from) VALUES
(1, 350, '2017-02-10') -- voids old "infinity"
;
INSERT 0 1
-- But single-row INSERTs have no way of anticipating later rows:
INSERT INTO prices(id, price, eff_from) VALUES
(2, 100, '2017-01-12');

INSERT INTO prices(id, price, eff_from) VALUES
(2, 150, '2017-02-09');

INSERT INTO prices(id, price, eff_from) VALUES
(2, 125, '2017-01-27');
INSERT 0 1
INSERT 0 1
INSERT 0 1
TABLE prices
ORDER BY id, eff_from;
prices_id id price eff_from eff_to
1 1 100 2017-01-12 2017-01-26
4 1 200 2017-01-13 2017-01-26
3 1 125 2017-01-27 2017-02-08
6 1 225 2017-01-28 2017-02-07
5 1 250 2017-02-08 2017-02-08
2 1 150 2017-02-09 infinity
7 1 350 2017-02-10 infinity
8 2 100 2017-01-12 infinity
10 2 125 2017-01-27 2017-02-08
9 2 150 2017-02-09 infinity
SELECT 10