This doesn't yet really work.
#include "catalog/catalog.h"
#include "catalog/index.h"
#include "catalog/pg_am_d.h"
+#include "catalog/storage_xlog.h"
#include "executor/executor.h"
#include "pgstat.h"
#include "storage/lmgr.h"
pfree(isnull);
}
+/*
+ * Set up an init fork for an unlogged table so that it can be correctly
+ * reinitialized on restart. An immediate sync is required even if the
+ * page has been logged, because the write did not go through
+ * shared_buffers and therefore a concurrent checkpoint may have moved
+ * the redo pointer past our xlog record. Recovery may as well remove it
+ * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE
+ * record. Therefore, logging is necessary even if wal_level=minimal.
+ */
+static void
+heap_create_init_fork(Relation rel)
+{
+ Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
+ rel->rd_rel->relkind == RELKIND_MATVIEW ||
+ rel->rd_rel->relkind == RELKIND_TOASTVALUE);
+ RelationOpenSmgr(rel);
+ smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
+ log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
+ smgrimmedsync(rel->rd_smgr, INIT_FORKNUM);
+}
+
+
static const TableAmRoutine heapam_methods = {
.type = T_TableAmRoutine,
.scan_analyze_next_block = heapam_scan_analyze_next_block,
.scan_analyze_next_tuple = heapam_scan_analyze_next_tuple,
.relation_copy_for_cluster = heap_copy_for_cluster,
+ .relation_create_init_fork = heap_create_init_fork,
.relation_sync = heap_sync,
.begin_index_fetch = heapam_begin_index_fetch,
#include "access/htup_details.h"
#include "access/multixact.h"
#include "access/sysattr.h"
+#include "access/tableam.h"
#include "access/transam.h"
#include "access/xact.h"
#include "access/xlog.h"
*/
if (relpersistence == RELPERSISTENCE_UNLOGGED &&
relkind != RELKIND_PARTITIONED_TABLE)
- heap_create_init_fork(new_rel_desc);
+ table_create_init_fork(new_rel_desc);
/*
* ok, the relation has been cataloged, so close our relations and return
return relid;
}
-/*
- * Set up an init fork for an unlogged table so that it can be correctly
- * reinitialized on restart. An immediate sync is required even if the
- * page has been logged, because the write did not go through
- * shared_buffers and therefore a concurrent checkpoint may have moved
- * the redo pointer past our xlog record. Recovery may as well remove it
- * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE
- * record. Therefore, logging is necessary even if wal_level=minimal.
- */
-void
-heap_create_init_fork(Relation rel)
-{
- Assert(rel->rd_rel->relkind == RELKIND_RELATION ||
- rel->rd_rel->relkind == RELKIND_MATVIEW ||
- rel->rd_rel->relkind == RELKIND_TOASTVALUE);
- RelationOpenSmgr(rel);
- smgrcreate(rel->rd_smgr, INIT_FORKNUM, false);
- log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM);
- smgrimmedsync(rel->rd_smgr, INIT_FORKNUM);
-}
-
/*
* RelationRemoveInheritance
*
RelationSetNewRelfilenode(rel, rel->rd_rel->relpersistence,
RecentXmin, minmulti);
if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
- heap_create_init_fork(rel);
+ table_create_init_fork(rel);
heap_relid = RelationGetRelid(rel);
toastrel->rd_rel->relpersistence,
RecentXmin, minmulti);
if (toastrel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
- heap_create_init_fork(toastrel);
+ table_create_init_fork(toastrel);
heap_close(toastrel, NoLock);
}
BlockNumber relallvisible;
double density;
+#if 0
+ /*
+ * If the relation contains any specific EstimateRelSize
+ * function, use that instead of the regular default heap method.
+ */
+ if (rel->rd_tableamroutine &&
+ rel->rd_tableamroutine->EstimateRelSize)
+ {
+ rel->rd_tableamroutine->EstimateRelSize(rel, attr_widths, pages,
+ tuples, allvisfrac);
+ return;
+ }
+#endif
+
switch (rel->rd_rel->relkind)
{
case RELKIND_RELATION:
HeapTuple tuple;
Form_pg_class classform;
+
+#if 0
+ /*
+ * If the relation contains any specific SetNewFilenode
+ * function, use that instead of the regular default heap method.
+ */
+ if (relation->rd_tableamroutine &&
+ relation->rd_tableamroutine->SetNewFileNode)
+ {
+ relation->rd_tableamroutine->SetNewFileNode(relation, persistence,
+ freezeXid, minmulti);
+ return;
+ }
+#endif
+
/* Indexes, sequences must have Invalid frozenxid; other rels must not */
Assert((relation->rd_rel->relkind == RELKIND_INDEX ||
relation->rd_rel->relkind == RELKIND_SEQUENCE) ?
TransactionId OldestXmin, TransactionId FreezeXid, MultiXactId MultiXactCutoff,
double *num_tuples, double *tups_vacuumed, double *tups_recently_dead);
+typedef void (*RelationCreateInitFork_function)(Relation rel);
+typedef void (*RelationSetNewFileNode_function)(Relation relation, char persistence,
+ TransactionId freezeXid, MultiXactId minmulti);
typedef void (*RelationSync_function) (Relation relation);
+typedef void (*RelationEstimateSize_function)(Relation rel, int32 *attr_widths,
+ BlockNumber *pages, double *tuples, double *allvisfrac);
+
typedef const TupleTableSlotOps* (*SlotCallbacks_function) (Relation relation);
RelationScanAnalyzeNextBlock_function scan_analyze_next_block;
RelationScanAnalyzeNextTuple_function scan_analyze_next_tuple;
RelationCopyForCluster_function relation_copy_for_cluster;
+
+ RelationCreateInitFork_function relation_create_init_fork;
+ RelationSetNewFileNode_function relation_set_new_filenode;
RelationSync_function relation_sync;
+ RelationEstimateSize_function relation_estimate_size;
/* Operations on relation scans */
ScanBegin_function scan_begin;
num_tuples, tups_vacuumed, tups_recently_dead);
}
+static inline void
+table_create_init_fork(Relation rel)
+{
+ rel->rd_tableamroutine->relation_create_init_fork(rel);
+}
+
+static inline void
+table_set_new_filenode(Relation rel, char persistence,
+ TransactionId freezeXid, MultiXactId minmulti)
+{
+ rel->rd_tableamroutine->relation_set_new_filenode(rel, persistence,
+ freezeXid, minmulti);
+}
+
/*
* table_sync - sync a heap, for use when no WAL has been written
*/
rel->rd_tableamroutine->relation_sync(rel);
}
+static inline void
+table_estimate_size(Relation rel, int32 *attr_widths,
+ BlockNumber *pages, double *tuples, double *allvisfrac)
+{
+ rel->rd_tableamroutine->relation_estimate_size(rel, attr_widths,
+ pages, tuples, allvisfrac);
+}
+
static inline double
table_index_build_scan(Relation heapRelation,
Relation indexRelation,
Oid relrewrite,
ObjectAddress *typaddress);
-extern void heap_create_init_fork(Relation rel);
-
extern void heap_drop_with_catalog(Oid relid);
extern void heap_truncate(List *relids);