Search code examples
postgresqltemporal-tables

How to return value from INSERT statement in transaction block?


My goal is to return transaction_start value. Tried RETURNING keyword.

But in transaction it is not working. There is no errors in result. The result just contains no data.

Is there other way to achieve this goal?

BEGIN;
DELETE FROM table_for_tests WHERE item_id = '142';
INSERT INTO table_for_tests (item_id, valid, key, value) 
VALUES 
  ('142', tstzrange('1970-01-01T03:00', '1970-01-01T03:00:00.000100', '[)'), 'key1', 'modified value1'), 
  ('142', tstzrange('1970-01-01T03:00', '1970-01-01T03:00:00.000100', '[)'), 'key2', 'modified value2') 
RETURNING lower(transaction) as transaction_start;
COMMIT;

UPD:

table_for_tests schema:

id         | item_id  | valid               | transaction        | key           | value 
BIGSERIAL  | BIGINT   | TSTZRANGE NOT NULL  | TSTZRANGE NOT NULL | VARCHAR(255)  | VARCHAR(255) 

transaction column is filled automatically by trigger (posgresql temporal_tables extension) while executing INSERT, UPDATE or DELETE operation.

The trigger was created by this code:

CREATE TRIGGER versioning_trigger BEFORE INSERT OR UPDATE OR DELETE ON 
table_for_tests FOR EACH ROW 
EXECUTE PROCEDURE versioning('transaction', 'table_for_tests_history', true);

UPD 2:

Source code of the trigger function (versioning), from pgAdmin III:

-- Function: public.versioning()

-- DROP FUNCTION public.versioning();

CREATE OR REPLACE FUNCTION public.versioning()
  RETURNS trigger AS
'$libdir/temporal_tables', 'versioning'
  LANGUAGE c VOLATILE STRICT
  COST 1;
ALTER FUNCTION public.versioning()
  OWNER TO postgres;
GRANT EXECUTE ON FUNCTION public.versioning() TO postgres;
REVOKE ALL ON FUNCTION public.versioning() FROM public;
COMMENT ON FUNCTION public.versioning() IS 'System-period temporal table trigger';

Solution

  • Solved this problem with JOOQ.

    It has DSLContext with transactionResult() method.

    Example:

    KeyValuesRecord record = context.transactionResult(tx -> {
    
    tx.dsl().deleteFrom(KEY_VALUES)
                .where(KEY_VALUES.ITEM_ID.eq('142'))
                .execute();
    
    KeyValuesRecord insertResult = tx.dsl().insertInto(KEY_VALUES, KEY_VALUES.ITEM_ID, KEY_VALUES.VALID, KEY_VALUES.VALUE)
            .values(itemId, range, value)
            .returning(KEY_VALUES.TRANSACTION)
            .fetchOne(); 
    
    return insertResult;
    });