[bug fix] Savepoint-related statements terminates connection

From: "Tsunakawa, Takayuki" <tsunakawa(dot)takay(at)jp(dot)fujitsu(dot)com>
To: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: [bug fix] Savepoint-related statements terminates connection
Date: 2017-03-31 07:10:44
Message-ID: 0A3221C70F24FB45833433255569204D1F6BE40D@G01JPEXMBYT05
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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 Content-Type Size
savept-in-multi-cmd.patch application/octet-stream 1.6 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Amit Langote 2017-03-31 07:17:05 Re: Partitioned tables and relfilenode
Previous Message Michael Paquier 2017-03-31 07:10:03 Re: Implementation of SASLprep for SCRAM-SHA-256