3535#include "access/relation.h"
3636#include "access/sysattr.h"
3737#include "access/table.h"
38+ #include "access/tableam.h"
3839#include "access/transam.h"
3940#include "access/xact.h"
4041#include "access/xlog.h"
@@ -98,6 +99,8 @@ static void AddNewRelationTuple(Relation pg_class_desc,
9899 Oid reloftype ,
99100 Oid relowner ,
100101 char relkind ,
102+ TransactionId relfrozenxid ,
103+ TransactionId relminmxid ,
101104 Datum relacl ,
102105 Datum reloptions );
103106static ObjectAddress AddNewRelationType (const char * typeName ,
@@ -300,7 +303,9 @@ heap_create(const char *relname,
300303 char relpersistence ,
301304 bool shared_relation ,
302305 bool mapped_relation ,
303- bool allow_system_table_mods )
306+ bool allow_system_table_mods ,
307+ TransactionId * relfrozenxid ,
308+ MultiXactId * relminmxid )
304309{
305310 bool create_storage ;
306311 Relation rel ;
@@ -327,6 +332,9 @@ heap_create(const char *relname,
327332 get_namespace_name (relnamespace ), relname ),
328333 errdetail ("System catalog modifications are currently disallowed." )));
329334
335+ * relfrozenxid = InvalidTransactionId ;
336+ * relminmxid = InvalidMultiXactId ;
337+
330338 /* Handle reltablespace for specific relkinds. */
331339 switch (relkind )
332340 {
@@ -400,13 +408,36 @@ heap_create(const char *relname,
400408 /*
401409 * Have the storage manager create the relation's disk file, if needed.
402410 *
403- * We only create the main fork here, other forks will be created on
404- * demand.
411+ * For relations the callback creates both the main and the init fork, for
412+ * indexes only the main fork is created. The other forks will be created
413+ * on demand.
405414 */
406415 if (create_storage )
407416 {
408417 RelationOpenSmgr (rel );
409- RelationCreateStorage (rel -> rd_node , relpersistence );
418+
419+ switch (rel -> rd_rel -> relkind )
420+ {
421+ case RELKIND_VIEW :
422+ case RELKIND_COMPOSITE_TYPE :
423+ case RELKIND_FOREIGN_TABLE :
424+ case RELKIND_PARTITIONED_TABLE :
425+ case RELKIND_PARTITIONED_INDEX :
426+ Assert (false);
427+ break ;
428+
429+ case RELKIND_INDEX :
430+ case RELKIND_SEQUENCE :
431+ RelationCreateStorage (rel -> rd_node , relpersistence );
432+ break ;
433+
434+ case RELKIND_RELATION :
435+ case RELKIND_TOASTVALUE :
436+ case RELKIND_MATVIEW :
437+ table_relation_set_new_filenode (rel , relpersistence ,
438+ relfrozenxid , relminmxid );
439+ break ;
440+ }
410441 }
411442
412443 return rel ;
@@ -892,6 +923,8 @@ AddNewRelationTuple(Relation pg_class_desc,
892923 Oid reloftype ,
893924 Oid relowner ,
894925 char relkind ,
926+ TransactionId relfrozenxid ,
927+ TransactionId relminmxid ,
895928 Datum relacl ,
896929 Datum reloptions )
897930{
@@ -928,40 +961,8 @@ AddNewRelationTuple(Relation pg_class_desc,
928961 break ;
929962 }
930963
931- /* Initialize relfrozenxid and relminmxid */
932- if (relkind == RELKIND_RELATION ||
933- relkind == RELKIND_MATVIEW ||
934- relkind == RELKIND_TOASTVALUE )
935- {
936- /*
937- * Initialize to the minimum XID that could put tuples in the table.
938- * We know that no xacts older than RecentXmin are still running, so
939- * that will do.
940- */
941- new_rel_reltup -> relfrozenxid = RecentXmin ;
942-
943- /*
944- * Similarly, initialize the minimum Multixact to the first value that
945- * could possibly be stored in tuples in the table. Running
946- * transactions could reuse values from their local cache, so we are
947- * careful to consider all currently running multis.
948- *
949- * XXX this could be refined further, but is it worth the hassle?
950- */
951- new_rel_reltup -> relminmxid = GetOldestMultiXactId ();
952- }
953- else
954- {
955- /*
956- * Other relation types will not contain XIDs, so set relfrozenxid to
957- * InvalidTransactionId. (Note: a sequence does contain a tuple, but
958- * we force its xmin to be FrozenTransactionId always; see
959- * commands/sequence.c.)
960- */
961- new_rel_reltup -> relfrozenxid = InvalidTransactionId ;
962- new_rel_reltup -> relminmxid = InvalidMultiXactId ;
963- }
964-
964+ new_rel_reltup -> relfrozenxid = relfrozenxid ;
965+ new_rel_reltup -> relminmxid = relminmxid ;
965966 new_rel_reltup -> relowner = relowner ;
966967 new_rel_reltup -> reltype = new_type_oid ;
967968 new_rel_reltup -> reloftype = reloftype ;
@@ -1089,6 +1090,8 @@ heap_create_with_catalog(const char *relname,
10891090 Oid new_type_oid ;
10901091 ObjectAddress new_type_addr ;
10911092 Oid new_array_oid = InvalidOid ;
1093+ TransactionId relfrozenxid ;
1094+ MultiXactId relminmxid ;
10921095
10931096 pg_class_desc = table_open (RelationRelationId , RowExclusiveLock );
10941097
@@ -1220,7 +1223,9 @@ heap_create_with_catalog(const char *relname,
12201223 relpersistence ,
12211224 shared_relation ,
12221225 mapped_relation ,
1223- allow_system_table_mods );
1226+ allow_system_table_mods ,
1227+ & relfrozenxid ,
1228+ & relminmxid );
12241229
12251230 Assert (relid == RelationGetRelid (new_rel_desc ));
12261231
@@ -1319,6 +1324,8 @@ heap_create_with_catalog(const char *relname,
13191324 reloftypeid ,
13201325 ownerid ,
13211326 relkind ,
1327+ relfrozenxid ,
1328+ relminmxid ,
13221329 PointerGetDatum (relacl ),
13231330 reloptions );
13241331
@@ -1407,14 +1414,6 @@ heap_create_with_catalog(const char *relname,
14071414 if (oncommit != ONCOMMIT_NOOP )
14081415 register_on_commit_action (relid , oncommit );
14091416
1410- /*
1411- * Unlogged objects need an init fork, except for partitioned tables which
1412- * have no storage at all.
1413- */
1414- if (relpersistence == RELPERSISTENCE_UNLOGGED &&
1415- relkind != RELKIND_PARTITIONED_TABLE )
1416- heap_create_init_fork (new_rel_desc );
1417-
14181417 /*
14191418 * ok, the relation has been cataloged, so close our relations and return
14201419 * the OID of the newly created relation.
@@ -1425,27 +1424,6 @@ heap_create_with_catalog(const char *relname,
14251424 return relid ;
14261425}
14271426
1428- /*
1429- * Set up an init fork for an unlogged table so that it can be correctly
1430- * reinitialized on restart. An immediate sync is required even if the
1431- * page has been logged, because the write did not go through
1432- * shared_buffers and therefore a concurrent checkpoint may have moved
1433- * the redo pointer past our xlog record. Recovery may as well remove it
1434- * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE
1435- * record. Therefore, logging is necessary even if wal_level=minimal.
1436- */
1437- void
1438- heap_create_init_fork (Relation rel )
1439- {
1440- Assert (rel -> rd_rel -> relkind == RELKIND_RELATION ||
1441- rel -> rd_rel -> relkind == RELKIND_MATVIEW ||
1442- rel -> rd_rel -> relkind == RELKIND_TOASTVALUE );
1443- RelationOpenSmgr (rel );
1444- smgrcreate (rel -> rd_smgr , INIT_FORKNUM , false);
1445- log_smgrcreate (& rel -> rd_smgr -> smgr_rnode .node , INIT_FORKNUM );
1446- smgrimmedsync (rel -> rd_smgr , INIT_FORKNUM );
1447- }
1448-
14491427/*
14501428 * RelationRemoveInheritance
14511429 *
@@ -3168,8 +3146,8 @@ heap_truncate_one_rel(Relation rel)
31683146 if (rel -> rd_rel -> relkind == RELKIND_PARTITIONED_TABLE )
31693147 return ;
31703148
3171- /* Truncate the actual file (and discard buffers) */
3172- RelationTruncate (rel , 0 );
3149+ /* Truncate the underlying relation */
3150+ table_relation_nontransactional_truncate (rel );
31733151
31743152 /* If the relation has indexes, truncate the indexes too */
31753153 RelationTruncateIndexes (rel );
@@ -3180,7 +3158,7 @@ heap_truncate_one_rel(Relation rel)
31803158 {
31813159 Relation toastrel = table_open (toastrelid , AccessExclusiveLock );
31823160
3183- RelationTruncate (toastrel , 0 );
3161+ table_relation_nontransactional_truncate (toastrel );
31843162 RelationTruncateIndexes (toastrel );
31853163 /* keep the lock... */
31863164 table_close (toastrel , NoLock );
0 commit comments