diff options
author | Amit Kapila <akapila@postgresql.org> | 2021-03-12 15:14:41 +0530 |
---|---|---|
committer | Amit Kapila <akapila@postgresql.org> | 2021-03-12 15:14:41 +0530 |
commit | e2cda3c20a61c76e497fb2ebb6d2b2ae8c43c014 (patch) | |
tree | bc36e932c603b30cf13b3273acd988ea281d92e1 /src | |
parent | 57dcc2ef3320de3e1aef6f668601e6ad2bdf88c4 (diff) | |
download | postgresql-e2cda3c20a61c76e497fb2ebb6d2b2ae8c43c014.tar.gz postgresql-e2cda3c20a61c76e497fb2ebb6d2b2ae8c43c014.zip |
Fix use of relcache TriggerDesc field introduced by commit 05c8482f7f.
The commit added code which used a relcache TriggerDesc field across
another cache access, which it shouldn't because the relcache doesn't
guarantee it won't get moved.
Diagnosed-by: Tom Lane
Author: Greg Nancarrow
Reviewed-by: Hou Zhijie, Amit Kapila
Discussion: https://postgr.es/m/2309260.1615485644@sss.pgh.pa.us
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 7e25f94293e..12754fdb2ba 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -114,7 +114,7 @@ static bool target_rel_max_parallel_hazard(max_parallel_hazard_context *context) static bool target_rel_max_parallel_hazard_recurse(Relation relation, CmdType command_type, max_parallel_hazard_context *context); -static bool target_rel_trigger_max_parallel_hazard(TriggerDesc *trigdesc, +static bool target_rel_trigger_max_parallel_hazard(Relation rel, max_parallel_hazard_context *context); static bool target_rel_index_max_parallel_hazard(Relation rel, max_parallel_hazard_context *context); @@ -926,7 +926,7 @@ target_rel_max_parallel_hazard_recurse(Relation rel, /* * If any triggers exist, check that they are parallel-safe. */ - if (target_rel_trigger_max_parallel_hazard(rel->trigdesc, context)) + if (target_rel_trigger_max_parallel_hazard(rel, context)) return true; /* @@ -952,23 +952,29 @@ target_rel_max_parallel_hazard_recurse(Relation rel, /* * target_rel_trigger_max_parallel_hazard * - * Finds the maximum parallel-mode hazard level for the specified trigger data. + * Finds the maximum parallel-mode hazard level for the specified relation's + * trigger data. */ static bool -target_rel_trigger_max_parallel_hazard(TriggerDesc *trigdesc, +target_rel_trigger_max_parallel_hazard(Relation rel, max_parallel_hazard_context *context) { int i; - if (trigdesc == NULL) + if (rel->trigdesc == NULL) return false; - for (i = 0; i < trigdesc->numtriggers; i++) + /* + * Care is needed here to avoid using the same relcache TriggerDesc field + * across other cache accesses, because relcache doesn't guarantee that it + * won't move. + */ + for (i = 0; i < rel->trigdesc->numtriggers; i++) { int trigtype; - Trigger *trigger = &trigdesc->triggers[i]; + Oid tgfoid = rel->trigdesc->triggers[i].tgfoid; - if (max_parallel_hazard_test(func_parallel(trigger->tgfoid), context)) + if (max_parallel_hazard_test(func_parallel(tgfoid), context)) return true; /* @@ -977,7 +983,7 @@ target_rel_trigger_max_parallel_hazard(TriggerDesc *trigdesc, * on insert/update and this isn't supported in a parallel worker (but * is safe in the parallel leader). */ - trigtype = RI_FKey_trigger_type(trigger->tgfoid); + trigtype = RI_FKey_trigger_type(tgfoid); if (trigtype == RI_TRIGGER_FK) { if (max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) |