diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 7a7177c550..5cb573f06f 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -5171,8 +5171,9 @@ ANY num_sync ( ).
+ Sets the cost threshold for which a given plan node will consider
+ performing JIT compilation for itself. xref linkend="jit"/> must also
+ be enabled.
Performing JIT costs planning time but can
accelerate query execution.
Setting this to -1 disables JIT compilation.
@@ -5189,10 +5190,11 @@ ANY num_sync ( num_sync ( jitFlags = PGJIT_NONE;
+
+ /*
+ * For values scans, expressions are only used once, so ensure we don't
+ * enable JIT for them.
+ */
+ if (IsA(plan, ValuesScan))
+ return;
+
+ /* Determine which JIT options to enable for this plan node */
+ if (jit_enabled && jit_above_cost >= 0 &&
+ plan->total_cost > jit_above_cost)
+ {
+ plan->jitFlags |= PGJIT_PERFORM;
+
+ /*
+ * Decide how much effort should be put into generating better code.
+ */
+ if (jit_optimize_above_cost >= 0 &&
+ plan->total_cost > jit_optimize_above_cost)
+ plan->jitFlags |= PGJIT_OPT3;
+ if (jit_inline_above_cost >= 0 &&
+ plan->total_cost > jit_inline_above_cost)
+ plan->jitFlags |= PGJIT_INLINE;
+
+ /*
+ * Decide which operations should be JITed.
+ */
+ if (jit_expressions)
+ plan->jitFlags |= PGJIT_EXPR;
+ if (jit_tuple_deforming)
+ plan->jitFlags |= PGJIT_DEFORM;
+
+ /* Record the maximum flags used by any plan node */
+ root->glob->jitFlags |= plan->jitFlags;
+ }
+}
+
/*
* create_scan_plan
* Create a scan plan for the parent relation of 'best_path'.
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index b40a112c25..ef9806887d 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -353,6 +353,8 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
glob->parallelModeOK = false;
}
+ glob->jitFlags = PGJIT_NONE;
+
/*
* glob->parallelModeNeeded is normally set to false here and changed to
* true during plan creation if a Gather or Gather Merge plan is actually
@@ -532,32 +534,7 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
result->utilityStmt = parse->utilityStmt;
result->stmt_location = parse->stmt_location;
result->stmt_len = parse->stmt_len;
-
- result->jitFlags = PGJIT_NONE;
- if (jit_enabled && jit_above_cost >= 0 &&
- top_plan->total_cost > jit_above_cost)
- {
- result->jitFlags |= PGJIT_PERFORM;
-
- /*
- * Decide how much effort should be put into generating better code.
- */
- if (jit_optimize_above_cost >= 0 &&
- top_plan->total_cost > jit_optimize_above_cost)
- result->jitFlags |= PGJIT_OPT3;
- if (jit_inline_above_cost >= 0 &&
- top_plan->total_cost > jit_inline_above_cost)
- result->jitFlags |= PGJIT_INLINE;
-
- /*
- * Decide which operations should be JITed.
- */
- if (jit_expressions)
- result->jitFlags |= PGJIT_EXPR;
- if (jit_tuple_deforming)
- result->jitFlags |= PGJIT_DEFORM;
- }
-
+ result->jitFlags = glob->jitFlags;
if (glob->partition_directory != NULL)
DestroyPartitionDirectory(glob->partition_directory);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index cf832d7f90..02b8a57c92 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -589,9 +589,9 @@ typedef struct EState
struct dsa_area *es_query_dsa;
/*
- * JIT information. es_jit_flags indicates whether JIT should be performed
- * and with which options. es_jit is created on-demand when JITing is
- * performed.
+ * JIT information. es_jit_flags indicates the possible set of JIT options
+ * that each plan node may make use of. es_jit is created on-demand when
+ * JITing is performed.
*
* es_jit_worker_instr is the combined, on demand allocated,
* instrumentation from all workers. The leader's instrumentation is kept
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 485d1b06c9..dcfc401fb0 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -146,6 +146,8 @@ typedef struct PlannerGlobal
char maxParallelHazard; /* worst PROPARALLEL hazard level */
+ int jitFlags; /* OR mask of jitFlags for each plan node */
+
PartitionDirectory partition_directory; /* partition descriptors */
} PlannerGlobal;
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 83e01074ed..aa7547bf6c 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -59,7 +59,8 @@ typedef struct PlannedStmt
bool parallelModeNeeded; /* parallel mode required to execute? */
- int jitFlags; /* which forms of JIT should be performed */
+ int jitFlags; /* OR mask of JIT flags which plan nodes may
+ * use */
struct Plan *planTree; /* tree of Plan nodes */
@@ -135,7 +136,10 @@ typedef struct Plan
bool parallel_aware; /* engage parallel-aware logic? */
bool parallel_safe; /* OK to use as part of parallel plan? */
- /*
+ int jitFlags; /* which forms of JIT should be performed on
+ * this node */
+
+ /*
* Common structural data for all Plan types.
*/
int plan_node_id; /* unique across entire final plan tree */