pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
May cause infinite loop when initializing rel-cache contains partitioned table
3+ messages / 3 participants
[nested] [flat]

* May cause infinite loop when initializing rel-cache contains partitioned table
@ 2017-05-05 08:26  甄明洋 <18612389267@yeah.net>
  0 siblings, 1 reply; 3+ messages in thread

From: 甄明洋 @ 2017-05-05 08:26 UTC (permalink / raw)
  To: pgsql-hackers

The function of  initializing rel-cache is RelationCacheInitializePhase3 and in src/backend/utils/cache/relcache.c file.
When initializing the partition description information, we forget to check if partition key or descriptor is NULL. 
Therefore, after the loop restarts, the partition information will be initialized again, resulting in an infinite loop.
Code:
/*
* Reload partition key and descriptor for a partitioned table.
*/
if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
RelationBuildPartitionKey(relation);
Assert(relation->rd_partkey != NULL);


RelationBuildPartitionDesc(relation);
Assert(relation->rd_partdesc != NULL);


restart = true;
}

^ permalink  raw  reply  [nested|flat] 3+ messages in thread

* Re: May cause infinite loop when initializing rel-cache contains partitioned table
@ 2017-05-08 09:07  Amit Langote <Langote_Amit_f8@lab.ntt.co.jp>
  parent: 甄明洋 <18612389267@yeah.net>
  0 siblings, 1 reply; 3+ messages in thread

From: Amit Langote @ 2017-05-08 09:07 UTC (permalink / raw)
  To: 甄明洋 <18612389267@yeah.net>; pgsql-hackers

Hi,

On 2017/05/05 17:26, 甄明洋 wrote:
> The function of  initializing rel-cache is RelationCacheInitializePhase3 and in src/backend/utils/cache/relcache.c file.
> When initializing the partition description information, we forget to check if partition key or descriptor is NULL. 
> Therefore, after the loop restarts, the partition information will be initialized again, resulting in an infinite loop.
> Code:
> /*
> * Reload partition key and descriptor for a partitioned table.
> */
> if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
> {
> RelationBuildPartitionKey(relation);
> Assert(relation->rd_partkey != NULL);
> 
> 
> RelationBuildPartitionDesc(relation);
> Assert(relation->rd_partdesc != NULL);
> 
> 
> restart = true;
> }

Thanks for bringing it to the notice.  The above code should follow what's
done for other fields that are initialized by
RelationCacheInitializePhase3().  Although, since none of the entries in
the relcache init file are partitioned tables, infinite loop won't occur
in practice, but it's a good idea to fix the code anyway.

Attached patch does that.

Thanks,
Amit

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Attachments:

  [text/x-diff] 0001-Check-partitioning-fields-are-NULL-in-RelationCacheI.patch (1.2K, ../../57e3c5e2-454f-72c0-c568-46deae7e3091@lab.ntt.co.jp/2-0001-Check-partitioning-fields-are-NULL-in-RelationCacheI.patch)
  download | inline diff:
From 6706999b159a76a3eb812eb3f7aad6e066a1c587 Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Mon, 8 May 2017 18:03:09 +0900
Subject: [PATCH] Check partitioning fields are NULL in
 RelationCacheInitializePhase3

---
 src/backend/utils/cache/relcache.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 30789c1edc..c3721d9e43 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -3858,13 +3858,20 @@ RelationCacheInitializePhase3(void)
 		}
 
 		/*
-		 * Reload partition key and descriptor for a partitioned table.
+		 * Reload the partition key and descriptor for a partitioned table.
 		 */
-		if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+		if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
+			relation->rd_partkey == NULL)
 		{
 			RelationBuildPartitionKey(relation);
 			Assert(relation->rd_partkey != NULL);
 
+			restart = true;
+		}
+
+		if (relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE &&
+			relation->rd_partdesc == NULL)
+		{
 			RelationBuildPartitionDesc(relation);
 			Assert(relation->rd_partdesc != NULL);
 
-- 
2.11.0

^ permalink  raw  reply  [nested|flat] 3+ messages in thread

* Re: May cause infinite loop when initializing rel-cache contains partitioned table
@ 2017-05-10 03:56  Robert Haas <robertmhaas@gmail.com>
  parent: Amit Langote <Langote_Amit_f8@lab.ntt.co.jp>
  0 siblings, 0 replies; 3+ messages in thread

From: Robert Haas @ 2017-05-10 03:56 UTC (permalink / raw)
  To: Amit Langote <Langote_Amit_f8@lab.ntt.co.jp>; +Cc: 甄明洋 <18612389267@yeah.net>; pgsql-hackers

On Mon, May 8, 2017 at 5:07 AM, Amit Langote
<Langote_Amit_f8@lab.ntt.co.jp> wrote:
> Thanks for bringing it to the notice.  The above code should follow what's
> done for other fields that are initialized by
> RelationCacheInitializePhase3().  Although, since none of the entries in
> the relcache init file are partitioned tables, infinite loop won't occur
> in practice, but it's a good idea to fix the code anyway.
>
> Attached patch does that.

Committed.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers



^ permalink  raw  reply  [nested|flat] 3+ messages in thread


end of thread, other threads:[~2017-05-10 03:56 UTC | newest]

Thread overview: 3+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2017-05-05 08:26 May cause infinite loop when initializing rel-cache contains partitioned table 甄明洋 <18612389267@yeah.net>
2017-05-08 09:07 ` Amit Langote <Langote_Amit_f8@lab.ntt.co.jp>
2017-05-10 03:56   ` Robert Haas <robertmhaas@gmail.com>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox