[bug fix] Savepoint-related statements terminates connection
Tsunakawa, Takayuki <tsunakawa.takay@jp.fujitsu.com>
From: "Tsunakawa, Takayuki" <tsunakawa.takay@jp.fujitsu.com>
To: "pgsql-hackers@postgresql.org" <pgsql-hackers@postgresql.org>
Date: 2017-03-31T07:10:44Z
Lists: pgsql-hackers
Attachments
- savept-in-multi-cmd.patch (application/octet-stream) patch
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
Commits
-
Improve documentation about behavior of multi-statement Query messages.
- b976499480bd 11.0 landed
-
Fix handling of savepoint commands within multi-statement Query strings.
- 6eb52da3948d 11.0 landed
-
Arrange for PreventTransactionChain to reject commands submitted as part
- 4f896dac17f7 8.3.0 cited