From bd7240ab8b331c261d6a5215bee906f8c63f0019 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 31 May 2011 02:02:19 +0200
Subject: [PATCH] Fix file existing errors uppon recreation of an unlogged
 tables indexes _init fork

The error could only occur if a relation got truncated that got a new
relfilenode in the same transaction before because in that case
heap_truncate_one_rel gets called instead of setting a new relfilenode
for all relevant relations.

To fix that simply check for the existance of the fork before recreating it.

To reproduce:
BEGIN;CREATE UNLOGGED TABLE foo (a int PRIMARY KEY);TRUNCATE foo; ROLLBACK;
---
 src/backend/catalog/index.c   |    3 ++-
 src/backend/catalog/storage.c |    2 --
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index a0898e0..d833a09 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1743,7 +1743,8 @@ index_build(Relation heapRelation,
 	/*
 	 * If this is an unlogged index, we need to write out an init fork for it.
 	 */
-	if (heapRelation->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
+	if (heapRelation->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED
+	    && !smgrexists(indexRelation->rd_smgr, FSM_FORKNUM))
 	{
 		RegProcedure ambuildempty = indexRelation->rd_am->ambuildempty;
 
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index 57987be..68a7b30 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -265,8 +265,6 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
 
 	/* Truncate the FSM first if it exists */
 	fsm = smgrexists(rel->rd_smgr, FSM_FORKNUM);
-	if (fsm)
-		FreeSpaceMapTruncateRel(rel, nblocks);
 
 	/* Truncate the visibility map too if it exists. */
 	vm = smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM);
-- 
1.7.5.rc1.16.g9db1.dirty

