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