mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
Create an infrastructure for parallel computation in PostgreSQL.
This does four basic things. First, it provides convenience routines to coordinate the startup and shutdown of parallel workers. Second, it synchronizes various pieces of state (e.g. GUCs, combo CID mappings, transaction snapshot) from the parallel group leader to the worker processes. Third, it prohibits various operations that would result in unsafe changes to that state while parallelism is active. Finally, it propagates events that would result in an ErrorResponse, NoticeResponse, or NotifyResponse message being sent to the client from the parallel workers back to the master, from which they can then be sent on to the client. Robert Haas, Amit Kapila, Noah Misch, Rushabh Lathia, Jeevan Chalke. Suggestions and review from Andres Freund, Heikki Linnakangas, Noah Misch, Simon Riggs, Euler Taveira, and Jim Nasby.
This commit is contained in:
@ -23,6 +23,7 @@
|
||||
#include "commands/trigger.h"
|
||||
#include "executor/executor.h"
|
||||
#include "executor/spi_priv.h"
|
||||
#include "miscadmin.h"
|
||||
#include "tcop/pquery.h"
|
||||
#include "tcop/utility.h"
|
||||
#include "utils/builtins.h"
|
||||
@ -1322,13 +1323,14 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
|
||||
}
|
||||
|
||||
/*
|
||||
* If told to be read-only, we'd better check for read-only queries. This
|
||||
* can't be done earlier because we need to look at the finished, planned
|
||||
* queries. (In particular, we don't want to do it between GetCachedPlan
|
||||
* and PortalDefineQuery, because throwing an error between those steps
|
||||
* would result in leaking our plancache refcount.)
|
||||
* If told to be read-only, or in parallel mode, verify that this query
|
||||
* is in fact read-only. This can't be done earlier because we need to
|
||||
* look at the finished, planned queries. (In particular, we don't want
|
||||
* to do it between GetCachedPlan and PortalDefineQuery, because throwing
|
||||
* an error between those steps would result in leaking our plancache
|
||||
* refcount.)
|
||||
*/
|
||||
if (read_only)
|
||||
if (read_only || IsInParallelMode())
|
||||
{
|
||||
ListCell *lc;
|
||||
|
||||
@ -1337,11 +1339,16 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
|
||||
Node *pstmt = (Node *) lfirst(lc);
|
||||
|
||||
if (!CommandIsReadOnly(pstmt))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
/* translator: %s is a SQL statement name */
|
||||
errmsg("%s is not allowed in a non-volatile function",
|
||||
CreateCommandTag(pstmt))));
|
||||
{
|
||||
if (read_only)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
/* translator: %s is a SQL statement name */
|
||||
errmsg("%s is not allowed in a non-volatile function",
|
||||
CreateCommandTag(pstmt))));
|
||||
else
|
||||
PreventCommandIfParallelMode(CreateCommandTag(pstmt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2129,6 +2136,9 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
|
||||
errmsg("%s is not allowed in a non-volatile function",
|
||||
CreateCommandTag(stmt))));
|
||||
|
||||
if (IsInParallelMode() && !CommandIsReadOnly(stmt))
|
||||
PreventCommandIfParallelMode(CreateCommandTag(stmt));
|
||||
|
||||
/*
|
||||
* If not read-only mode, advance the command counter before each
|
||||
* command and update the snapshot.
|
||||
|
Reference in New Issue
Block a user