mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Fix up run-time partition pruning's use of relcache's partition data.
The previous coding saved pointers into the partitioned table's relcache entry, but then closed the relcache entry, causing those pointers to nominally become dangling. Actual trouble would be seen in the field only if a relcache flush occurred mid-query, but that's hardly out of the question. While we could fix this by copying all the data in question at query start, it seems better to just hold the relcache entry open for the whole query. While at it, improve the handling of support-function lookups: do that once per query not once per pruning test. There's still something to be desired here, in that we fail to exploit the possibility of caching data across queries in the fn_extra fields of the relcache's FmgrInfo structs, which could happen if we just used those structs in-place rather than copying them. However, combining that with the possibility of per-query lookups of cross-type comparison functions seems to require changes in the APIs of a lot of the pruning support functions, so it's too invasive to consider as part of this patch. A win would ensue only for complex partition key data types (e.g. arrays), so it may not be worth the trouble. David Rowley and Tom Lane Discussion: https://postgr.es/m/17850.1528755844@sss.pgh.pa.us
This commit is contained in:
6
src/backend/utils/cache/relcache.c
vendored
6
src/backend/utils/cache/relcache.c
vendored
@ -2471,6 +2471,7 @@ RelationClearRelation(Relation relation, bool rebuild)
|
||||
keep_tupdesc = equalTupleDescs(relation->rd_att, newrel->rd_att);
|
||||
keep_rules = equalRuleLocks(relation->rd_rules, newrel->rd_rules);
|
||||
keep_policies = equalRSDesc(relation->rd_rsdesc, newrel->rd_rsdesc);
|
||||
/* partkey is immutable once set up, so we can always keep it */
|
||||
keep_partkey = (relation->rd_partkey != NULL);
|
||||
keep_partdesc = equalPartitionDescs(relation->rd_partkey,
|
||||
relation->rd_partdesc,
|
||||
@ -2515,7 +2516,7 @@ RelationClearRelation(Relation relation, bool rebuild)
|
||||
SWAPFIELD(Form_pg_class, rd_rel);
|
||||
/* ... but actually, we don't have to update newrel->rd_rel */
|
||||
memcpy(relation->rd_rel, newrel->rd_rel, CLASS_TUPLE_SIZE);
|
||||
/* preserve old tupledesc and rules if no logical change */
|
||||
/* preserve old tupledesc, rules, policies if no logical change */
|
||||
if (keep_tupdesc)
|
||||
SWAPFIELD(TupleDesc, rd_att);
|
||||
if (keep_rules)
|
||||
@ -2529,13 +2530,12 @@ RelationClearRelation(Relation relation, bool rebuild)
|
||||
SWAPFIELD(Oid, rd_toastoid);
|
||||
/* pgstat_info must be preserved */
|
||||
SWAPFIELD(struct PgStat_TableStatus *, pgstat_info);
|
||||
/* partition key must be preserved, if we have one */
|
||||
/* preserve old partitioning info if no logical change */
|
||||
if (keep_partkey)
|
||||
{
|
||||
SWAPFIELD(PartitionKey, rd_partkey);
|
||||
SWAPFIELD(MemoryContext, rd_partkeycxt);
|
||||
}
|
||||
/* preserve old partdesc if no logical change */
|
||||
if (keep_partdesc)
|
||||
{
|
||||
SWAPFIELD(PartitionDesc, rd_partdesc);
|
||||
|
Reference in New Issue
Block a user