*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.237 2007/03/13 14:32:25 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.238 2007/03/22 19:55:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* completes). Subtransactions are verboten too.
*
* isTopLevel: passed down from ProcessUtility to determine whether we are
- * inside a function. (We will always fail if this is false, but it's
- * convenient to centralize the check here instead of making callers do it.)
- * stmtType: statement type name, for error messages.
+ * inside a function or multi-query querystring. (We will always fail if
+ * this is false, but it's convenient to centralize the check here instead of
+ * making callers do it.)
+ * stmtType: statement type name, for error messages.
*/
void
PreventTransactionChain(bool isTopLevel, const char *stmtType)
ereport(ERROR,
(errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
/* translator: %s represents an SQL statement name */
- errmsg("%s cannot be executed from a function", stmtType)));
+ errmsg("%s cannot be executed from a function or multi-command string",
+ stmtType)));
/* If we got past IsTransactionBlock test, should be in default state */
if (CurrentTransactionState->blockState != TBLOCK_DEFAULT &&
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.528 2007/03/13 00:33:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.529 2007/03/22 19:55:04 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
ListCell *parsetree_item;
bool save_log_statement_stats = log_statement_stats;
bool was_logged = false;
+ bool isTopLevel;
char msec_str[32];
/*
*/
MemoryContextSwitchTo(oldcontext);
+ /*
+ * We'll tell PortalRun it's a top-level command iff there's exactly
+ * one raw parsetree. If more than one, it's effectively a transaction
+ * block and we want PreventTransactionChain to reject unsafe commands.
+ * (Note: we're assuming that query rewrite cannot add commands that are
+ * significant to PreventTransactionChain.)
+ */
+ isTopLevel = (list_length(parsetree_list) == 1);
+
/*
* Run through the raw parsetree(s) and process each one.
*/
*/
(void) PortalRun(portal,
FETCH_ALL,
- true, /* top level */
+ isTopLevel,
receiver,
receiver,
completionTag);
completed = PortalRun(portal,
max_rows,
- true, /* top level */
+ true, /* always top level */
receiver,
receiver,
completionTag);