99#include "postgres.h"
1010
1111#include "access/brin_xlog.h"
12+ #include "access/neon_xlog.h"
1213#include "access/clog.h"
1314#include "access/commit_ts.h"
1415#include "access/generic_xlog.h"
2223#include "access/spgxlog.h"
2324#include "access/xact.h"
2425#include "access/xlog_internal.h"
26+ #include "access/rmgrdesc_utils.h"
2527#include "catalog/storage_xlog.h"
2628#include "commands/dbcommands_xlog.h"
2729#include "commands/sequence.h"
@@ -45,6 +47,158 @@ static char CustomNumericNames[RM_N_CUSTOM_IDS][CUSTOM_NUMERIC_NAME_LEN] = {{0}}
4547static RmgrDescData CustomRmgrDesc [RM_N_CUSTOM_IDS ] = {{0 }};
4648static bool CustomRmgrDescInitialized = false;
4749
50+ /*
51+ * NOTE: "keyname" argument cannot have trailing spaces or punctuation
52+ * characters
53+ */
54+ static void
55+ infobits_desc (StringInfo buf , uint8 infobits , const char * keyname )
56+ {
57+ appendStringInfo (buf , "%s: [" , keyname );
58+
59+ Assert (buf -> data [buf -> len - 1 ] != ' ' );
60+
61+ if (infobits & XLHL_XMAX_IS_MULTI )
62+ appendStringInfoString (buf , "IS_MULTI, " );
63+ if (infobits & XLHL_XMAX_LOCK_ONLY )
64+ appendStringInfoString (buf , "LOCK_ONLY, " );
65+ if (infobits & XLHL_XMAX_EXCL_LOCK )
66+ appendStringInfoString (buf , "EXCL_LOCK, " );
67+ if (infobits & XLHL_XMAX_KEYSHR_LOCK )
68+ appendStringInfoString (buf , "KEYSHR_LOCK, " );
69+ if (infobits & XLHL_KEYS_UPDATED )
70+ appendStringInfoString (buf , "KEYS_UPDATED, " );
71+
72+ if (buf -> data [buf -> len - 1 ] == ' ' )
73+ {
74+ /* Truncate-away final unneeded ", " */
75+ Assert (buf -> data [buf -> len - 2 ] == ',' );
76+ buf -> len -= 2 ;
77+ buf -> data [buf -> len ] = '\0' ;
78+ }
79+
80+ appendStringInfoString (buf , "]" );
81+ }
82+
83+ static void
84+ neon_rm_desc (StringInfo buf , XLogReaderState * record )
85+ {
86+ char * rec = XLogRecGetData (record );
87+ uint8 info = XLogRecGetInfo (record ) & ~XLR_INFO_MASK ;
88+
89+ info &= XLOG_NEON_OPMASK ;
90+
91+ if (info == XLOG_NEON_HEAP_INSERT )
92+ {
93+ xl_neon_heap_insert * xlrec = (xl_neon_heap_insert * ) rec ;
94+
95+ appendStringInfo (buf , "off: %u, flags: 0x%02X" ,
96+ xlrec -> offnum ,
97+ xlrec -> flags );
98+ }
99+ else if (info == XLOG_NEON_HEAP_DELETE )
100+ {
101+ xl_neon_heap_delete * xlrec = (xl_neon_heap_delete * ) rec ;
102+
103+ appendStringInfo (buf , "xmax: %u, off: %u, " ,
104+ xlrec -> xmax , xlrec -> offnum );
105+ infobits_desc (buf , xlrec -> infobits_set , "infobits" );
106+ appendStringInfo (buf , ", flags: 0x%02X" , xlrec -> flags );
107+ }
108+ else if (info == XLOG_NEON_HEAP_UPDATE )
109+ {
110+ xl_neon_heap_update * xlrec = (xl_neon_heap_update * ) rec ;
111+
112+ appendStringInfo (buf , "old_xmax: %u, old_off: %u, " ,
113+ xlrec -> old_xmax , xlrec -> old_offnum );
114+ infobits_desc (buf , xlrec -> old_infobits_set , "old_infobits" );
115+ appendStringInfo (buf , ", flags: 0x%02X, new_xmax: %u, new_off: %u" ,
116+ xlrec -> flags , xlrec -> new_xmax , xlrec -> new_offnum );
117+ }
118+ else if (info == XLOG_NEON_HEAP_HOT_UPDATE )
119+ {
120+ xl_neon_heap_update * xlrec = (xl_neon_heap_update * ) rec ;
121+
122+ appendStringInfo (buf , "old_xmax: %u, old_off: %u, " ,
123+ xlrec -> old_xmax , xlrec -> old_offnum );
124+ infobits_desc (buf , xlrec -> old_infobits_set , "old_infobits" );
125+ appendStringInfo (buf , ", flags: 0x%02X, new_xmax: %u, new_off: %u" ,
126+ xlrec -> flags , xlrec -> new_xmax , xlrec -> new_offnum );
127+ }
128+ else if (info == XLOG_NEON_HEAP_LOCK )
129+ {
130+ xl_neon_heap_lock * xlrec = (xl_neon_heap_lock * ) rec ;
131+
132+ appendStringInfo (buf , "xmax: %u, off: %u, " ,
133+ xlrec -> xmax , xlrec -> offnum );
134+ infobits_desc (buf , xlrec -> infobits_set , "infobits" );
135+ appendStringInfo (buf , ", flags: 0x%02X" , xlrec -> flags );
136+ }
137+ else if (info == XLOG_NEON_HEAP_MULTI_INSERT )
138+ {
139+ xl_neon_heap_multi_insert * xlrec = (xl_neon_heap_multi_insert * ) rec ;
140+ bool isinit = (XLogRecGetInfo (record ) & XLOG_NEON_INIT_PAGE ) != 0 ;
141+
142+ appendStringInfo (buf , "ntuples: %d, flags: 0x%02X" , xlrec -> ntuples ,
143+ xlrec -> flags );
144+
145+ if (XLogRecHasBlockData (record , 0 ) && !isinit )
146+ {
147+ appendStringInfoString (buf , ", offsets:" );
148+ array_desc (buf , xlrec -> offsets , sizeof (OffsetNumber ),
149+ xlrec -> ntuples , & offset_elem_desc , NULL );
150+ }
151+ }
152+ }
153+
154+ static const char *
155+ neon_rm_identify (uint8 info )
156+ {
157+ const char * id = NULL ;
158+
159+ switch (info & ~XLR_INFO_MASK )
160+ {
161+ case XLOG_NEON_HEAP_INSERT :
162+ id = "INSERT" ;
163+ break ;
164+ case XLOG_NEON_HEAP_INSERT | XLOG_NEON_INIT_PAGE :
165+ id = "INSERT+INIT" ;
166+ break ;
167+ case XLOG_NEON_HEAP_DELETE :
168+ id = "DELETE" ;
169+ break ;
170+ case XLOG_NEON_HEAP_UPDATE :
171+ id = "UPDATE" ;
172+ break ;
173+ case XLOG_NEON_HEAP_UPDATE | XLOG_NEON_INIT_PAGE :
174+ id = "UPDATE+INIT" ;
175+ break ;
176+ case XLOG_NEON_HEAP_HOT_UPDATE :
177+ id = "HOT_UPDATE" ;
178+ break ;
179+ case XLOG_NEON_HEAP_HOT_UPDATE | XLOG_HEAP_INIT_PAGE :
180+ id = "HOT_UPDATE+INIT" ;
181+ break ;
182+ case XLOG_NEON_HEAP_LOCK :
183+ id = "LOCK" ;
184+ break ;
185+ case XLOG_NEON_HEAP_MULTI_INSERT :
186+ id = "MULTI_INSERT" ;
187+ break ;
188+ case XLOG_NEON_HEAP_MULTI_INSERT | XLOG_NEON_INIT_PAGE :
189+ id = "MULTI_INSERT+INIT" ;
190+ break ;
191+ }
192+
193+ return id ;
194+ }
195+
196+ const static RmgrDescData NeonRmgr = {
197+ .rm_name = "neon" ,
198+ .rm_desc = neon_rm_desc ,
199+ .rm_identify = neon_rm_identify ,
200+ };
201+
48202/*
49203 * No information on custom resource managers; just print the ID.
50204 */
@@ -92,6 +246,11 @@ GetRmgrDesc(RmgrId rmid)
92246 return & RmgrDescTable [rmid ];
93247 else
94248 {
249+ if (rmid == RM_NEON_ID ) {
250+ /* Neon RMGR is a custom RMGR, but we have its definition */
251+ return & NeonRmgr ;
252+ }
253+
95254 if (!CustomRmgrDescInitialized )
96255 initialize_custom_rmgrs ();
97256 return & CustomRmgrDesc [rmid - RM_MIN_CUSTOM_ID ];
0 commit comments