Tom Lane wrote:

> Couldn't we do something similar to the design for SQL keyword constants,
> wherein the actual data is in macros in a header file (providing exactly
> one source of truth for each RM) and then various .c files can #include
> that after #defining the macro as they need?

Here are two patches implementing this idea.  The first one is simpler
and just replaces the table in rmgr.c with an appropriate PG_RMGR
define.

The second one touches rmgr.h as well.  That file currently has a list
of #defines with symbolic rmgr names and their numeric IDs.  The
approach in the second patch is to turn these into "extern const RmgrId"
instead, and use a second inclusion of rmgrlist.h in rmgr.c that assigns
them the values as consts.  This has the disadvantage that the array
size RM_MAX_ID cannot use the symbolic RM_SPGIST_ID value, but instead
it needs a literal "16".  Otherwise the compile complains:
error: variably modified ‘RmgrTable’ at file scope

I am not too sure about that second change.  However, I'm a bit uneasy
about leaving a second list of rmgrs around; since we're creating what
should be the canonical list of rmgrs, it makes sense to reduce the two
copies we have.  Better ideas for that second list are welcome.

-- 
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
*** a/src/backend/access/transam/rmgr.c
--- b/src/backend/access/transam/rmgr.c
***************
*** 24,46 ****
  #include "storage/standby.h"
  #include "utils/relmapper.h"
  
  
  const RmgrData RmgrTable[RM_MAX_ID + 1] = {
! 	{"XLOG", xlog_redo, xlog_desc, NULL, NULL, NULL},
! 	{"Transaction", xact_redo, xact_desc, NULL, NULL, NULL},
! 	{"Storage", smgr_redo, smgr_desc, NULL, NULL, NULL},
! 	{"CLOG", clog_redo, clog_desc, NULL, NULL, NULL},
! 	{"Database", dbase_redo, dbase_desc, NULL, NULL, NULL},
! 	{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL},
! 	{"MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL},
! 	{"RelMap", relmap_redo, relmap_desc, NULL, NULL, NULL},
! 	{"Standby", standby_redo, standby_desc, NULL, NULL, NULL},
! 	{"Heap2", heap2_redo, heap2_desc, NULL, NULL, NULL},
! 	{"Heap", heap_redo, heap_desc, NULL, NULL, NULL},
! 	{"Btree", btree_redo, btree_desc, btree_xlog_startup, btree_xlog_cleanup, btree_safe_restartpoint},
! 	{"Hash", hash_redo, hash_desc, NULL, NULL, NULL},
! 	{"Gin", gin_redo, gin_desc, gin_xlog_startup, gin_xlog_cleanup, gin_safe_restartpoint},
! 	{"Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup, NULL},
! 	{"Sequence", seq_redo, seq_desc, NULL, NULL, NULL},
! 	{"SPGist", spg_redo, spg_desc, spg_xlog_startup, spg_xlog_cleanup, NULL}
  };
--- 24,32 ----
  #include "storage/standby.h"
  #include "utils/relmapper.h"
  
+ #define PG_RMGR(name,redo,desc,startup,cleanup,restartpoint) \
+ 	{ name, redo, desc, startup, cleanup, restartpoint },
  
  const RmgrData RmgrTable[RM_MAX_ID + 1] = {
! #include "access/rmgrlist.h"
  };
*** /dev/null
--- b/src/include/access/rmgrlist.h
***************
*** 0 ****
--- 1,39 ----
+ /*---------------------------------------------------------------------------
+  * rmgrlist.h
+  *
+  * The resource manager list is kept in its own source file for possible
+  * use by automatic tools.  The exact representation of a rmgr is determined
+  * by the PG_RMGR macro, which is not defined in this file; it can be
+  * defined by the caller for special purposes.
+  *
+  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * src/include/access/rmgrlist.h
+  *---------------------------------------------------------------------------
+  */
+ 
+ /* there is deliberately not an #ifndef RMGRLIST_H here */
+ 
+ /*
+  * List of resource manager entries.
+  */
+ 
+ /* name, redo, desc, startup, cleanup, restartpoint */
+ PG_RMGR("XLOG", xlog_redo, xlog_desc, NULL, NULL, NULL)
+ PG_RMGR("Transaction", xact_redo, xact_desc, NULL, NULL, NULL)
+ PG_RMGR("Storage", smgr_redo, smgr_desc, NULL, NULL, NULL)
+ PG_RMGR("CLOG", clog_redo, clog_desc, NULL, NULL, NULL)
+ PG_RMGR("Database", dbase_redo, dbase_desc, NULL, NULL, NULL)
+ PG_RMGR("Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL)
+ PG_RMGR("MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL)
+ PG_RMGR("RelMap", relmap_redo, relmap_desc, NULL, NULL, NULL)
+ PG_RMGR("Standby", standby_redo, standby_desc, NULL, NULL, NULL)
+ PG_RMGR("Heap2", heap2_redo, heap2_desc, NULL, NULL, NULL)
+ PG_RMGR("Heap", heap_redo, heap_desc, NULL, NULL, NULL)
+ PG_RMGR("Btree", btree_redo, btree_desc, btree_xlog_startup, btree_xlog_cleanup, btree_safe_restartpoint)
+ PG_RMGR("Hash", hash_redo, hash_desc, NULL, NULL, NULL)
+ PG_RMGR("Gin", gin_redo, gin_desc, gin_xlog_startup, gin_xlog_cleanup, gin_safe_restartpoint)
+ PG_RMGR("Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup, NULL)
+ PG_RMGR("Sequence", seq_redo, seq_desc, NULL, NULL, NULL)
+ PG_RMGR("SPGist", spg_redo, spg_desc, spg_xlog_startup, spg_xlog_cleanup, NULL)
*** a/src/backend/access/transam/rmgr.c
--- b/src/backend/access/transam/rmgr.c
***************
*** 24,46 ****
  #include "storage/standby.h"
  #include "utils/relmapper.h"
  
  
  const RmgrData RmgrTable[RM_MAX_ID + 1] = {
! 	{"XLOG", xlog_redo, xlog_desc, NULL, NULL, NULL},
! 	{"Transaction", xact_redo, xact_desc, NULL, NULL, NULL},
! 	{"Storage", smgr_redo, smgr_desc, NULL, NULL, NULL},
! 	{"CLOG", clog_redo, clog_desc, NULL, NULL, NULL},
! 	{"Database", dbase_redo, dbase_desc, NULL, NULL, NULL},
! 	{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL},
! 	{"MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL},
! 	{"RelMap", relmap_redo, relmap_desc, NULL, NULL, NULL},
! 	{"Standby", standby_redo, standby_desc, NULL, NULL, NULL},
! 	{"Heap2", heap2_redo, heap2_desc, NULL, NULL, NULL},
! 	{"Heap", heap_redo, heap_desc, NULL, NULL, NULL},
! 	{"Btree", btree_redo, btree_desc, btree_xlog_startup, btree_xlog_cleanup, btree_safe_restartpoint},
! 	{"Hash", hash_redo, hash_desc, NULL, NULL, NULL},
! 	{"Gin", gin_redo, gin_desc, gin_xlog_startup, gin_xlog_cleanup, gin_safe_restartpoint},
! 	{"Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup, NULL},
! 	{"Sequence", seq_redo, seq_desc, NULL, NULL, NULL},
! 	{"SPGist", spg_redo, spg_desc, spg_xlog_startup, spg_xlog_cleanup, NULL}
  };
--- 24,39 ----
  #include "storage/standby.h"
  #include "utils/relmapper.h"
  
+ #define PG_RMGR(symname,num,name,redo,desc,startup,cleanup,restartpoint) \
+ 	{ name, redo, desc, startup, cleanup, restartpoint },
  
  const RmgrData RmgrTable[RM_MAX_ID + 1] = {
! #include "access/rmgrlist.h"
  };
+ 
+ #undef PG_RMGR
+ 
+ #define PG_RMGR(symname,num,name,redo,desc,startup,cleanup,restartpoint) \
+ 	const RmgrId symname = num;
+ #include "access/rmgrlist.h"
+ #undef PG_RMGR
*** a/src/include/access/rmgr.h
--- b/src/include/access/rmgr.h
***************
*** 16,39 **** typedef uint8 RmgrId;
   * Note: RM_MAX_ID could be as much as 255 without breaking the XLOG file
   * format, but we keep it small to minimize the size of RmgrTable[].
   */
! #define RM_XLOG_ID				0
! #define RM_XACT_ID				1
! #define RM_SMGR_ID				2
! #define RM_CLOG_ID				3
! #define RM_DBASE_ID				4
! #define RM_TBLSPC_ID			5
! #define RM_MULTIXACT_ID			6
! #define RM_RELMAP_ID			7
! #define RM_STANDBY_ID			8
! #define RM_HEAP2_ID				9
! #define RM_HEAP_ID				10
! #define RM_BTREE_ID				11
! #define RM_HASH_ID				12
! #define RM_GIN_ID				13
! #define RM_GIST_ID				14
! #define RM_SEQ_ID				15
! #define RM_SPGIST_ID			16
  
! #define RM_MAX_ID				RM_SPGIST_ID
  
  #endif   /* RMGR_H */
--- 16,28 ----
   * Note: RM_MAX_ID could be as much as 255 without breaking the XLOG file
   * format, but we keep it small to minimize the size of RmgrTable[].
   */
! #define PG_RMGR(symname,id,name,redo,desc,startup,cleanup,restartpoint) \
! 	extern const RmgrId symname;
  
! #include "access/rmgrlist.h"
! #undef PG_RMGR
! 
! /* beware! must be kept in sync with rmgrlist.h */
! #define RM_MAX_ID				16
  
  #endif   /* RMGR_H */
*** /dev/null
--- b/src/include/access/rmgrlist.h
***************
*** 0 ****
--- 1,42 ----
+ /*---------------------------------------------------------------------------
+  * rmgrlist.h
+  *
+  * The resource manager list is kept in its own source file for possible
+  * use by automatic tools.  The exact representation of a rmgr is determined
+  * by the PG_RMGR macro, which is not defined in this file; it can be
+  * defined by the caller for special purposes.
+  *
+  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * src/include/access/rmgrlist.h
+  *---------------------------------------------------------------------------
+  */
+ 
+ /* there is deliberately not an #ifndef RMGRLIST_H here */
+ 
+ /*
+  * List of resource manager entries.
+  *
+  * Beware!  The numerical value of the last entry must be kept in sync with
+  * the RM_MAX_ID in rmgr.h.
+  */
+ 
+ /* symname, id, name, redo, desc, startup, cleanup, restartpoint */
+ PG_RMGR(RM_XLOG_ID, 0, "XLOG", xlog_redo, xlog_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_XACT_ID, 1, "Transaction", xact_redo, xact_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_SMGR_ID, 2, "Storage", smgr_redo, smgr_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_CLOG_ID, 3, "CLOG", clog_redo, clog_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_DBASE_ID, 4, "Database", dbase_redo, dbase_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_TBLSPC_ID, 5, "Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_MULTIXACT_ID, 6, "MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_RELMAP_ID, 7, "RelMap", relmap_redo, relmap_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_STANDBY_ID, 8, "Standby", standby_redo, standby_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_HEAP2_ID, 9, "Heap2", heap2_redo, heap2_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_HEAP_ID, 10, "Heap", heap_redo, heap_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_BTREE_ID, 11, "Btree", btree_redo, btree_desc, btree_xlog_startup, btree_xlog_cleanup, btree_safe_restartpoint)
+ PG_RMGR(RM_HASH_ID, 12, "Hash", hash_redo, hash_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_GIN_ID, 13, "Gin", gin_redo, gin_desc, gin_xlog_startup, gin_xlog_cleanup, gin_safe_restartpoint)
+ PG_RMGR(RM_GIST_ID, 14, "Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup, NULL)
+ PG_RMGR(RM_SEQ_ID, 15, "Sequence", seq_redo, seq_desc, NULL, NULL, NULL)
+ PG_RMGR(RM_SPGIST_ID, 16, "SPGist", spg_redo, spg_desc, spg_xlog_startup, spg_xlog_cleanup, NULL)
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to