[bug fix] Savepoint-related statements terminates connection - Mailing list pgsql-hackers

From Tsunakawa, Takayuki
Subject [bug fix] Savepoint-related statements terminates connection
Date
Msg-id 0A3221C70F24FB45833433255569204D1F6BE40D@G01JPEXMBYT05
Whole thread Raw
Responses Re: [bug fix] Savepoint-related statements terminates connection  (Ashutosh Bapat <ashutosh.bapat@enterprisedb.com>)
List pgsql-hackers
Hello,

I found a trivial bug that terminates the connection.  The attached patch fixes this.


PROBLEM
========================================

Savepoint-related statements in a multi-command query terminates the connection unexpectedly, as follows.

$ psql -d postgres -c "SELECT 1; SAVEPOINT sp"
FATAL:  DefineSavepoint: unexpected state STARTED
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
connection to server was lost


CAUSE
========================================

1. In exec_simple_query(), isTopLevel is set to false.

    isTopLevel = (list_length(parsetree_list) == 1);

Then it is passed to PortalRun().

        (void) PortalRun(portal,
                         FETCH_ALL,
                         isTopLevel,
                         receiver,
                         receiver,
                         completionTag);

2. The isTopLevel flag is passed through ProcessUtility() to RequireTransactionChain().

                            RequireTransactionChain(isTopLevel, "SAVEPOINT");


3. CheckTransactionChain() returns successfully here:

    /*
     * inside a function call?
     */
    if (!isTopLevel)
        return;


4. Finally, unexpectedly called DefineSavepoint() reports invalid transaction block state.

            /* These cases are invalid. */
        case TBLOCK_DEFAULT:
        case TBLOCK_STARTED:
...
            elog(FATAL, "DefineSavepoint: unexpected state %s",
                 BlockStateAsString(s->blockState));



SOLUTION
========================================

The manual page says "Savepoints can only be established when inside a transaction block."  So just check for it.

https://www.postgresql.org/docs/devel/static/sql-savepoint.html


RESULT AFTER FIX
========================================

$ psql -d postgres -c "SELECT 1; SAVEPOINT sp"
ERROR:  SAVEPOINT can only be used in transaction blocks


Regards
Takayuki Tsunakawa


Attachment

pgsql-hackers by date:

Previous
From: Michael Paquier
Date:
Subject: Re: Implementation of SASLprep for SCRAM-SHA-256
Next
From: Amit Langote
Date:
Subject: Re: Partitioned tables and relfilenode