Re: Issue with server side statement-level rollback

From: Gilles Darold <gilles(at)darold(dot)net>
To: Andres Freund <andres(at)anarazel(dot)de>
Cc: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Issue with server side statement-level rollback
Date: 2020-11-22 10:05:52
Message-ID: 7fda915c-d3da-380f-39c8-58f3c1ecef34@darold.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Le 20/11/2020 à 16:18, Gilles Darold a écrit :
> I will work later on a POC to demonstrate the use case I want to
> implement.

Hi Andres,

I have created a new version of the pg_statement_rollback extension [1]
to demonstrate the use of the hooks on start_xact_command(),
finish_xact_command() and AbortCurrentTransaction() to implement the
statement-level rollback feature entirely driven at serverside. It
require that the patch [2]  I've provided be applied on PostgreSQL
source first.

Here is what can be achieved with this patch:

LOAD 'pg_statement_rollback.so';
LOAD
SET pg_statement_rollback.enabled TO on;
SET
CREATE SCHEMA testrsl;
CREATE SCHEMA
SET search_path TO testrsl,public;
SET
BEGIN;
BEGIN
CREATE TABLE tbl_rsl(id integer, val varchar(256));
CREATE TABLE
INSERT INTO tbl_rsl VALUES (1, 'one');
INSERT 0 1
WITH write AS (INSERT INTO tbl_rsl VALUES (2, 'two') RETURNING id,
val) SELECT * FROM write;
 id | val
----+-----
  2 | two
(1 row)

UPDATE tbl_rsl SET id = 'two', val = 2 WHERE id = 1; -- >>>>> will fail
psql:simple.sql:14: ERROR:  invalid input syntax for type integer: "two"
LINE 1: UPDATE tbl_rsl SET id = 'two', val = 2 WHERE id = 1;
                                ^
SELECT * FROM tbl_rsl; -- Should show records id 1 + 2
 id | val
----+-----
  1 | one
  2 | two
(2 rows)

COMMIT;
COMMIT

Actually unlike I've though this is the hook on finish_xact_command()
that is useless. In the extension I'm executing the RELEASE/SAVEPOINT in
the start_xact_command() hook before executing the next statement. The
hook on AbortCurrentTransaction() is used to signal that a ROLLOBACK
TO/SAVEPOINT need to be executed into the start_xact_command() hook
instead of a RELEASE/SAVEPOINT.

This works perfectly and do not crash PG anymore when compiled with
assert. Advanced tests (with triggers, client savepoint, CTE, etc.) are
available in the test/sql/ directory. Use of "make installcheck" allow
to run the regression tests.

Based on this result I really think that these hooks should be included
to be able to extend PostgreSQL for such feature although I have not
though about an other use that this one.

Regards, 

I've attached all code for archiving but the current version can be
found here too:

[1] https://github.com/darold/pg_statement_rollbackv2

[2]
https://raw.githubusercontent.com/darold/pg_statement_rollbackv2/main/command-start-finish-hook-v1.patch

--

Gilles Darold
http://www.darold.net/

Attachment Content-Type Size
command-start-finish-hook-v1.patch text/x-patch 3.8 KB
pg_statement_rollbackv2.tar.gz application/gzip 37.7 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Michael Paquier 2020-11-22 11:11:21 Re: Removal of currtid()/currtid2() and some table AM cleanup
Previous Message James Hilliard 2020-11-22 08:19:30 [PATCH 1/1] Initial mach based shared memory support.