Thanks all. I tried the appended code in a trigger function, but postgresql won't take it. It complains that assets.quantity is not a scalar. However, the WHERE clause in that select statement guarantees that at most only one record will be returned. An open position on a given kind of asset is represented by null in the end_valid_time field, and the combination of asset_type_id, portfolio_id and end_valid_time is certain to be unique, if there is a record for that asset type in that porfolio at all. I thought I'd try checking for an open position first because the manual indicated that exception handling is quite expensive. But I must have missed something, because it doesn't like how I tried to define my trigger function. I have four sequences, one each for four tables. Two of the tables are just look up tables, for asset types and portfolios; trivial for test case with only an autoincrementing integer primary key and a "name". The other two are the ones of interest. Assets is treated as read only as far as the user is concerned. The user's data in the assets table is mediated through transactions inserted (and NEVER deleted or updated), into the transactions table. Assets has the minimal suite of columns (autoincrementing integer primary key, asset_typeID, portfolio_id, all integers, quantity with is a floating point number and two dates: start_valid_time and end_valid_time). Transactions has only a transaction_id, portfolio_id, asset_type_id, quantity and transaction_date. There are of course foreign keys connectin the assets and transactions tables to the lookup tables, and a composite index on assets to make looking up records based on portfolio_id, asset_id and end_valid_time as quick as possible. It couldn't be simpler, conceptually! yet I must have missed something, cause postgresql won't accept the function body I show below. If I can't get this working quickly, I may just resort to creating a stored procedure that takes the transaction details as arguments and processes both tables appropriately without relying on a trigger. :-( Thanks for everyone's help. Ted =========================================== DECLARE id BIGINT; q DOUBLE PRECISION; BEGIN SELECT assets.id INTO id, assets.quantity INTO q FROM assets WHERE assets.asset_type_id = NEW.asset_type_id AND assets.portfolio_id = NEW.portfolio_id AND assets.end_valid_time IS NULL; IF (id IS NULL) THEN INSERT INTO assets (asset_type_id, portfolio_id,quantity,start_valid_stime,end_valid_time) VALUES (NEW.asset_type_id,NEW.portfolio_id, NEW.quantity, NEW.transaction_date,NULL); ELSE UPDATE assets SET end_valid_time = NEW.transaction_date WHERE id = id; INSERT INTO assets (asset_type_id, portfolio_id,quantity,start_valid_stime,end_valid_time) VALUES (NEW.asset_type_id,NEW.portfolio_id, q + NEW.quantity, NEW.transaction_date,NULL); END END ---------------------------(end of broadcast)--------------------------- TIP 1: if posting/reading through Usenet, please send an appropriate subscribe-nomail command to majordomo@xxxxxxxxxxxxxx so that your message can get through to the mailing list cleanly