mirror of
https://github.com/postgres/postgres.git
synced 2025-09-09 13:09:39 +03:00
Make replace_relid() leave argument unmodified
There are a lot of situations when we share the same pointer to a Bitmapset structure across different places. In order to evade undesirable side effects replace_relid() function should always return a copy. Reported-by: Richard Guo Discussion: https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.com Reviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
This commit is contained in:
@@ -1522,6 +1522,10 @@ replace_varno_walker(Node *node, ReplaceVarnoContext *ctx)
|
||||
|
||||
/*
|
||||
* Substitute newId by oldId in relids.
|
||||
*
|
||||
* We must make a copy of the original Bitmapset before making any
|
||||
* modifications, because the same pointer to it might be shared among
|
||||
* different places.
|
||||
*/
|
||||
static Bitmapset *
|
||||
replace_relid(Relids relids, int oldId, int newId)
|
||||
@@ -1529,12 +1533,13 @@ replace_relid(Relids relids, int oldId, int newId)
|
||||
if (oldId < 0)
|
||||
return relids;
|
||||
|
||||
/* Delete relid without substitution. */
|
||||
if (newId < 0)
|
||||
/* Delete relid without substitution. */
|
||||
return bms_del_member(relids, oldId);
|
||||
return bms_del_member(bms_copy(relids), oldId);
|
||||
|
||||
/* Substitute newId for oldId. */
|
||||
if (bms_is_member(oldId, relids))
|
||||
return bms_add_member(bms_del_member(relids, oldId), newId);
|
||||
return bms_add_member(bms_del_member(bms_copy(relids), oldId), newId);
|
||||
|
||||
return relids;
|
||||
}
|
||||
|
Reference in New Issue
Block a user