summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index b2656283251..174210be6cf 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -23,6 +23,7 @@
#include "access/sysattr.h"
#include "access/xact.h"
#include "catalog/pg_constraint_fn.h"
+#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
#include "executor/executor.h"
#include "executor/nodeAgg.h"
@@ -241,12 +242,26 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
* time and execution time, so don't generate a parallel plan if we're in
* serializable mode.
*/
- glob->parallelModeOK = (cursorOptions & CURSOR_OPT_PARALLEL_OK) != 0 &&
- IsUnderPostmaster && dynamic_shared_memory_type != DSM_IMPL_NONE &&
- parse->commandType == CMD_SELECT && !parse->hasModifyingCTE &&
- parse->utilityStmt == NULL && max_parallel_workers_per_gather > 0 &&
- !IsParallelWorker() && !IsolationIsSerializable() &&
- !has_parallel_hazard((Node *) parse, true);
+ if ((cursorOptions & CURSOR_OPT_PARALLEL_OK) != 0 &&
+ IsUnderPostmaster &&
+ dynamic_shared_memory_type != DSM_IMPL_NONE &&
+ parse->commandType == CMD_SELECT &&
+ parse->utilityStmt == NULL &&
+ !parse->hasModifyingCTE &&
+ max_parallel_workers_per_gather > 0 &&
+ !IsParallelWorker() &&
+ !IsolationIsSerializable())
+ {
+ /* all the cheap tests pass, so scan the query tree */
+ glob->maxParallelHazard = max_parallel_hazard(parse);
+ glob->parallelModeOK = (glob->maxParallelHazard != PROPARALLEL_UNSAFE);
+ }
+ else
+ {
+ /* skip the query tree scan, just assume it's unsafe */
+ glob->maxParallelHazard = PROPARALLEL_UNSAFE;
+ glob->parallelModeOK = false;
+ }
/*
* glob->parallelModeNeeded should tell us whether it's necessary to
@@ -1802,7 +1817,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
* computed by partial paths.
*/
if (current_rel->partial_pathlist &&
- !has_parallel_hazard((Node *) scanjoin_target->exprs, false))
+ is_parallel_safe(root, (Node *) scanjoin_target->exprs))
{
/* Apply the scan/join target to each partial path */
foreach(lc, current_rel->partial_pathlist)
@@ -1948,8 +1963,8 @@ grouping_planner(PlannerInfo *root, bool inheritance_update,
* query.
*/
if (current_rel->consider_parallel &&
- !has_parallel_hazard(parse->limitOffset, false) &&
- !has_parallel_hazard(parse->limitCount, false))
+ is_parallel_safe(root, parse->limitOffset) &&
+ is_parallel_safe(root, parse->limitCount))
final_rel->consider_parallel = true;
/*
@@ -3326,8 +3341,8 @@ create_grouping_paths(PlannerInfo *root,
* target list and HAVING quals are parallel-safe.
*/
if (input_rel->consider_parallel &&
- !has_parallel_hazard((Node *) target->exprs, false) &&
- !has_parallel_hazard((Node *) parse->havingQual, false))
+ is_parallel_safe(root, (Node *) target->exprs) &&
+ is_parallel_safe(root, (Node *) parse->havingQual))
grouped_rel->consider_parallel = true;
/*
@@ -3881,8 +3896,8 @@ create_window_paths(PlannerInfo *root,
* target list and active windows for non-parallel-safe constructs.
*/
if (input_rel->consider_parallel &&
- !has_parallel_hazard((Node *) output_target->exprs, false) &&
- !has_parallel_hazard((Node *) activeWindows, false))
+ is_parallel_safe(root, (Node *) output_target->exprs) &&
+ is_parallel_safe(root, (Node *) activeWindows))
window_rel->consider_parallel = true;
/*
@@ -4272,7 +4287,7 @@ create_ordered_paths(PlannerInfo *root,
* target list is parallel-safe.
*/
if (input_rel->consider_parallel &&
- !has_parallel_hazard((Node *) target->exprs, false))
+ is_parallel_safe(root, (Node *) target->exprs))
ordered_rel->consider_parallel = true;
/*