Skip to content

Commit 4f896da

Browse files
committed
Arrange for PreventTransactionChain to reject commands submitted as part
of a multi-statement simple-Query message. This bug goes all the way back, but unfortunately is not nearly so easy to fix in existing releases; it is only the recent ProcessUtility API change that makes it fixable in HEAD. Per report from William Garrison.
1 parent 6869563 commit 4f896da

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

src/backend/access/transam/xact.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.237 2007/03/13 14:32:25 petere Exp $
13+
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.238 2007/03/22 19:55:04 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -2503,9 +2503,10 @@ AbortCurrentTransaction(void)
25032503
* completes). Subtransactions are verboten too.
25042504
*
25052505
* isTopLevel: passed down from ProcessUtility to determine whether we are
2506-
* inside a function. (We will always fail if this is false, but it's
2507-
* convenient to centralize the check here instead of making callers do it.)
2508-
* stmtType: statement type name, for error messages.
2506+
* inside a function or multi-query querystring. (We will always fail if
2507+
* this is false, but it's convenient to centralize the check here instead of
2508+
* making callers do it.)
2509+
* stmtType: statement type name, for error messages.
25092510
*/
25102511
void
25112512
PreventTransactionChain(bool isTopLevel, const char *stmtType)
@@ -2537,7 +2538,8 @@ PreventTransactionChain(bool isTopLevel, const char *stmtType)
25372538
ereport(ERROR,
25382539
(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
25392540
/* translator: %s represents an SQL statement name */
2540-
errmsg("%s cannot be executed from a function", stmtType)));
2541+
errmsg("%s cannot be executed from a function or multi-command string",
2542+
stmtType)));
25412543

25422544
/* If we got past IsTransactionBlock test, should be in default state */
25432545
if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&

src/backend/tcop/postgres.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.528 2007/03/13 00:33:42 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.529 2007/03/22 19:55:04 tgl Exp $
1212
*
1313
* NOTES
1414
* this is the "main" module of the postgres backend and
@@ -765,6 +765,7 @@ exec_simple_query(const char *query_string)
765765
ListCell *parsetree_item;
766766
bool save_log_statement_stats = log_statement_stats;
767767
bool was_logged = false;
768+
bool isTopLevel;
768769
char msec_str[32];
769770

770771
/*
@@ -824,6 +825,15 @@ exec_simple_query(const char *query_string)
824825
*/
825826
MemoryContextSwitchTo(oldcontext);
826827

828+
/*
829+
* We'll tell PortalRun it's a top-level command iff there's exactly
830+
* one raw parsetree. If more than one, it's effectively a transaction
831+
* block and we want PreventTransactionChain to reject unsafe commands.
832+
* (Note: we're assuming that query rewrite cannot add commands that are
833+
* significant to PreventTransactionChain.)
834+
*/
835+
isTopLevel = (list_length(parsetree_list) == 1);
836+
827837
/*
828838
* Run through the raw parsetree(s) and process each one.
829839
*/
@@ -944,7 +954,7 @@ exec_simple_query(const char *query_string)
944954
*/
945955
(void) PortalRun(portal,
946956
FETCH_ALL,
947-
true, /* top level */
957+
isTopLevel,
948958
receiver,
949959
receiver,
950960
completionTag);
@@ -1810,7 +1820,7 @@ exec_execute_message(const char *portal_name, long max_rows)
18101820

18111821
completed = PortalRun(portal,
18121822
max_rows,
1813-
true, /* top level */
1823+
true, /* always top level */
18141824
receiver,
18151825
receiver,
18161826
completionTag);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy