0003-Free-ec_derives_list-in-ec_clear_derived_cl-20250325.patch

text/x-patch

Filename: 0003-Free-ec_derives_list-in-ec_clear_derived_cl-20250325.patch
Type: text/x-patch
Part: 2
Message: Re: Reducing memory consumed by RestrictInfo list translations in partitionwise join planning

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch 0003
Subject: Free ec_derives_list in ec_clear_derived_clauses()
File+
src/backend/optimizer/path/equivclass.c 4 5
From 7b559921c64a00bd023e53f98866347fa753de33 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Tue, 25 Mar 2025 14:38:59 +0530
Subject: [PATCH 3/3] Free ec_derives_list in ec_clear_derived_clauses()

remove_rel_from_eclass() and process_equivalence() used to set
EquivalenceClass::ec_derives to NIL when resetting the derived clauses before
that code was replaced by a call to ec_clear_derived_clauses().
update_eclasses(), on the other hand, freed the list before setting it to NIL.
That code was also replaced by ec_clear_derived_clauses(). Net effect being we
lost the list_free() under update_eclasses().

Given that ec_derives_list can grow large when there thousands of partitions or
joins, it's better to just free the list instead of just forgetting it as we do
at other places like try_partitionwise_join(). The memory used by the list being
freed should not be referenced anywhere so it's safe to do so. Any new code
which uses ec_clear_derived_clauses() will be required to make sure that the
memory is not referenced as well. Net effect is less memory consumption and
better compliance. Hence change ec_clear_derived_clauses() to free
ec_derives_list as well.

Author: Ashutosh Bapat
Reported-by: Amit Langote
---
 src/backend/optimizer/path/equivclass.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c
index b4987b466c4..ee314a8d5b8 100644
--- a/src/backend/optimizer/path/equivclass.c
+++ b/src/backend/optimizer/path/equivclass.c
@@ -3563,16 +3563,15 @@ ec_add_clause_to_derives_hash(EquivalenceClass *ec, RestrictInfo *rinfo)
  *      Reset ec_derives_list and ec_derives_hash.
  *
  * We destroy the hash table explicitly, since it may consume significant
- * space. The list is simply cleared by setting it to NIL; we do not
- * explicitly free it.
- *
- * XXX: When thousands of partitions are involved, the list can become
- * sizable. It might be worth freeing it explicitly in such cases.
+ * space. When thousands of partitions are involved, the list may become
+ * sizable hence free it as well, even though we do not usually free lists.
  */
 void
 ec_clear_derived_clauses(EquivalenceClass *ec)
 {
 	ec->ec_derives_list = NIL;
+	list_free(ec->ec_derives_list);
+
 	if (ec->ec_derives_hash)
 	{
 		derives_destroy(ec->ec_derives_hash);
-- 
2.34.1