2 15.4. Parallel Safety #
4 15.4.1. Parallel Labeling for Functions and Aggregates
6 The planner classifies operations involved in a query as either
7 parallel safe, parallel restricted, or parallel unsafe. A parallel safe
8 operation is one that does not conflict with the use of parallel query.
9 A parallel restricted operation is one that cannot be performed in a
10 parallel worker, but that can be performed in the leader while parallel
11 query is in use. Therefore, parallel restricted operations can never
12 occur below a Gather or Gather Merge node, but can occur elsewhere in a
13 plan that contains such a node. A parallel unsafe operation is one that
14 cannot be performed while parallel query is in use, not even in the
15 leader. When a query contains anything that is parallel unsafe,
16 parallel query is completely disabled for that query.
18 The following operations are always parallel restricted:
19 * Scans of common table expressions (CTEs).
20 * Scans of temporary tables.
21 * Scans of foreign tables, unless the foreign data wrapper has an
22 IsForeignScanParallelSafe API that indicates otherwise.
23 * Plan nodes that reference a correlated SubPlan.
25 15.4.1. Parallel Labeling for Functions and Aggregates #
27 The planner cannot automatically determine whether a user-defined
28 function or aggregate is parallel safe, parallel restricted, or
29 parallel unsafe, because this would require predicting every operation
30 that the function could possibly perform. In general, this is
31 equivalent to the Halting Problem and therefore impossible. Even for
32 simple functions where it could conceivably be done, we do not try,
33 since this would be expensive and error-prone. Instead, all
34 user-defined functions are assumed to be parallel unsafe unless
35 otherwise marked. When using CREATE FUNCTION or ALTER FUNCTION,
36 markings can be set by specifying PARALLEL SAFE, PARALLEL RESTRICTED,
37 or PARALLEL UNSAFE as appropriate. When using CREATE AGGREGATE, the
38 PARALLEL option can be specified with SAFE, RESTRICTED, or UNSAFE as
39 the corresponding value.
41 Functions and aggregates must be marked PARALLEL UNSAFE if they write
42 to the database, change the transaction state (other than by using a
43 subtransaction for error recovery), access sequences, or make
44 persistent changes to settings. Similarly, functions must be marked
45 PARALLEL RESTRICTED if they access temporary tables, client connection
46 state, cursors, prepared statements, or miscellaneous backend-local
47 state that the system cannot synchronize across workers. For example,
48 setseed and random are parallel restricted for this last reason.
50 In general, if a function is labeled as being safe when it is
51 restricted or unsafe, or if it is labeled as being restricted when it
52 is in fact unsafe, it may throw errors or produce wrong answers when
53 used in a parallel query. C-language functions could in theory exhibit
54 totally undefined behavior if mislabeled, since there is no way for the
55 system to protect itself against arbitrary C code, but in most likely
56 cases the result will be no worse than for any other function. If in
57 doubt, it is probably best to label functions as UNSAFE.
59 If a function executed within a parallel worker acquires locks that are
60 not held by the leader, for example by querying a table not referenced
61 in the query, those locks will be released at worker exit, not end of
62 transaction. If you write a function that does this, and this behavior
63 difference is important to you, mark such functions as PARALLEL
64 RESTRICTED to ensure that they execute only in the leader.
66 Note that the query planner does not consider deferring the evaluation
67 of parallel-restricted functions or aggregates involved in the query in
68 order to obtain a superior plan. So, for example, if a WHERE clause
69 applied to a particular table is parallel restricted, the query planner
70 will not consider performing a scan of that table in the parallel
71 portion of a plan. In some cases, it would be possible (and perhaps
72 even efficient) to include the scan of that table in the parallel
73 portion of the query and defer the evaluation of the WHERE clause so
74 that it happens above the Gather node. However, the planner does not do