mirror of
https://github.com/postgres/postgres.git
synced 2025-11-19 13:42:17 +03:00
Reduce memory used by partitionwise joins
Specifically, this commit reduces the memory consumed by the SpecialJoinInfos that are allocated for child joins in try_partitionwise_join() by freeing them at the end of creating paths for each child join. A SpecialJoinInfo allocated for a given child join is a copy of the parent join's SpecialJoinInfo, which contains the translated copies of the various Relids bitmapsets and semi_rhs_exprs, which is a List of Nodes. The newly added freeing step frees the struct itself and the various bitmapsets, but not semi_rhs_exprs, because there's no handy function to free the memory of Node trees. Author: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> Reviewed-by: Richard Guo <guofenglinux@gmail.com> Reviewed-by: Amit Langote <amitlangote09@gmail.com> Reviewed-by: Andrey Lepikhov <a.lepikhov@postgrespro.ru> Reviewed-by: Tomas Vondra <tomas.vondra@enterprisedb.com> Discussion: https://postgr.es/m/CAExHW5tHqEf3ASVqvFFcghYGPfpy7o3xnvhHwBGbJFMRH8KjNw@mail.gmail.com
This commit is contained in:
@@ -45,6 +45,7 @@ static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1,
|
||||
static SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root,
|
||||
SpecialJoinInfo *parent_sjinfo,
|
||||
Relids left_relids, Relids right_relids);
|
||||
static void free_child_join_sjinfo(SpecialJoinInfo *child_sjinfo);
|
||||
static void compute_partition_bounds(PlannerInfo *root, RelOptInfo *rel1,
|
||||
RelOptInfo *rel2, RelOptInfo *joinrel,
|
||||
SpecialJoinInfo *parent_sjinfo,
|
||||
@@ -1659,6 +1660,7 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
child_restrictlist);
|
||||
|
||||
pfree(appinfos);
|
||||
free_child_join_sjinfo(child_sjinfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1666,6 +1668,9 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
* Construct the SpecialJoinInfo for a child-join by translating
|
||||
* SpecialJoinInfo for the join between parents. left_relids and right_relids
|
||||
* are the relids of left and right side of the join respectively.
|
||||
*
|
||||
* If translations are added to or removed from this function, consider
|
||||
* updating free_child_join_sjinfo() accordingly.
|
||||
*/
|
||||
static SpecialJoinInfo *
|
||||
build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
|
||||
@@ -1705,6 +1710,37 @@ build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
|
||||
return sjinfo;
|
||||
}
|
||||
|
||||
/*
|
||||
* free_child_join_sjinfo
|
||||
* Free memory consumed by a SpecialJoinInfo created by
|
||||
* build_child_join_sjinfo()
|
||||
*
|
||||
* Only members that are translated copies of their counterpart in the parent
|
||||
* SpecialJoinInfo are freed here.
|
||||
*/
|
||||
static void
|
||||
free_child_join_sjinfo(SpecialJoinInfo *sjinfo)
|
||||
{
|
||||
/*
|
||||
* Dummy SpecialJoinInfos of inner joins do not have any translated fields
|
||||
* and hence no fields that to be freed.
|
||||
*/
|
||||
if (sjinfo->jointype != JOIN_INNER)
|
||||
{
|
||||
bms_free(sjinfo->min_lefthand);
|
||||
bms_free(sjinfo->min_righthand);
|
||||
bms_free(sjinfo->syn_lefthand);
|
||||
bms_free(sjinfo->syn_righthand);
|
||||
|
||||
/*
|
||||
* semi_rhs_exprs may in principle be freed, but a simple pfree() does
|
||||
* not suffice, so we leave it alone.
|
||||
*/
|
||||
}
|
||||
|
||||
pfree(sjinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
* compute_partition_bounds
|
||||
* Compute the partition bounds for a join rel from those for inputs
|
||||
|
||||
Reference in New Issue
Block a user