1 /*-------------------------------------------------------------------------
2  *
3  * spgdesc.c
4  *	  rmgr descriptor routines for access/spgist/spgxlog.c
5  *
6  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/backend/access/rmgrdesc/spgdesc.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include "postgres.h"
16 
17 #include "access/spgxlog.h"
18 
19 void
spg_desc(StringInfo buf,XLogReaderState * record)20 spg_desc(StringInfo buf, XLogReaderState *record)
21 {
22 	char	   *rec = XLogRecGetData(record);
23 	uint8		info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
24 
25 	switch (info)
26 	{
27 		case XLOG_SPGIST_ADD_LEAF:
28 			{
29 				spgxlogAddLeaf *xlrec = (spgxlogAddLeaf *) rec;
30 
31 				appendStringInfo(buf, "off: %u, headoff: %u, parentoff: %u, nodeI: %u",
32 								 xlrec->offnumLeaf, xlrec->offnumHeadLeaf,
33 								 xlrec->offnumParent, xlrec->nodeI);
34 				if (xlrec->newPage)
35 					appendStringInfoString(buf, " (newpage)");
36 				if (xlrec->storesNulls)
37 					appendStringInfoString(buf, " (nulls)");
38 			}
39 			break;
40 		case XLOG_SPGIST_MOVE_LEAFS:
41 			{
42 				spgxlogMoveLeafs *xlrec = (spgxlogMoveLeafs *) rec;
43 
44 				appendStringInfo(buf, "nmoves: %u, parentoff: %u, nodeI: %u",
45 								 xlrec->nMoves,
46 								 xlrec->offnumParent, xlrec->nodeI);
47 				if (xlrec->newPage)
48 					appendStringInfoString(buf, " (newpage)");
49 				if (xlrec->replaceDead)
50 					appendStringInfoString(buf, " (replacedead)");
51 				if (xlrec->storesNulls)
52 					appendStringInfoString(buf, " (nulls)");
53 			}
54 			break;
55 		case XLOG_SPGIST_ADD_NODE:
56 			{
57 				spgxlogAddNode *xlrec = (spgxlogAddNode *) rec;
58 
59 				appendStringInfo(buf, "off: %u, newoff: %u, parentBlk: %d, "
60 								 "parentoff: %u, nodeI: %u",
61 								 xlrec->offnum,
62 								 xlrec->offnumNew,
63 								 xlrec->parentBlk,
64 								 xlrec->offnumParent,
65 								 xlrec->nodeI);
66 				if (xlrec->newPage)
67 					appendStringInfoString(buf, " (newpage)");
68 			}
69 			break;
70 		case XLOG_SPGIST_SPLIT_TUPLE:
71 			{
72 				spgxlogSplitTuple *xlrec = (spgxlogSplitTuple *) rec;
73 
74 				appendStringInfo(buf, "prefixoff: %u, postfixoff: %u",
75 								 xlrec->offnumPrefix,
76 								 xlrec->offnumPostfix);
77 				if (xlrec->newPage)
78 					appendStringInfoString(buf, " (newpage)");
79 				if (xlrec->postfixBlkSame)
80 					appendStringInfoString(buf, " (same)");
81 			}
82 			break;
83 		case XLOG_SPGIST_PICKSPLIT:
84 			{
85 				spgxlogPickSplit *xlrec = (spgxlogPickSplit *) rec;
86 
87 				appendStringInfo(buf, "ndelete: %u, ninsert: %u, inneroff: %u, "
88 								 "parentoff: %u, nodeI: %u",
89 								 xlrec->nDelete, xlrec->nInsert,
90 								 xlrec->offnumInner,
91 								 xlrec->offnumParent, xlrec->nodeI);
92 				if (xlrec->innerIsParent)
93 					appendStringInfoString(buf, " (innerIsParent)");
94 				if (xlrec->storesNulls)
95 					appendStringInfoString(buf, " (nulls)");
96 				if (xlrec->isRootSplit)
97 					appendStringInfoString(buf, " (isRootSplit)");
98 			}
99 			break;
100 		case XLOG_SPGIST_VACUUM_LEAF:
101 			{
102 				spgxlogVacuumLeaf *xlrec = (spgxlogVacuumLeaf *) rec;
103 
104 				appendStringInfo(buf, "ndead: %u, nplaceholder: %u, nmove: %u, nchain: %u",
105 								 xlrec->nDead, xlrec->nPlaceholder,
106 								 xlrec->nMove, xlrec->nChain);
107 			}
108 			break;
109 		case XLOG_SPGIST_VACUUM_ROOT:
110 			{
111 				spgxlogVacuumRoot *xlrec = (spgxlogVacuumRoot *) rec;
112 
113 				appendStringInfo(buf, "ndelete: %u",
114 								 xlrec->nDelete);
115 			}
116 			break;
117 		case XLOG_SPGIST_VACUUM_REDIRECT:
118 			{
119 				spgxlogVacuumRedirect *xlrec = (spgxlogVacuumRedirect *) rec;
120 
121 				appendStringInfo(buf, "ntoplaceholder: %u, firstplaceholder: %u, newestredirectxid: %u",
122 								 xlrec->nToPlaceholder,
123 								 xlrec->firstPlaceholder,
124 								 xlrec->newestRedirectXid);
125 			}
126 			break;
127 	}
128 }
129 
130 const char *
spg_identify(uint8 info)131 spg_identify(uint8 info)
132 {
133 	const char *id = NULL;
134 
135 	switch (info & ~XLR_INFO_MASK)
136 	{
137 		case XLOG_SPGIST_ADD_LEAF:
138 			id = "ADD_LEAF";
139 			break;
140 		case XLOG_SPGIST_MOVE_LEAFS:
141 			id = "MOVE_LEAFS";
142 			break;
143 		case XLOG_SPGIST_ADD_NODE:
144 			id = "ADD_NODE";
145 			break;
146 		case XLOG_SPGIST_SPLIT_TUPLE:
147 			id = "SPLIT_TUPLE";
148 			break;
149 		case XLOG_SPGIST_PICKSPLIT:
150 			id = "PICKSPLIT";
151 			break;
152 		case XLOG_SPGIST_VACUUM_LEAF:
153 			id = "VACUUM_LEAF";
154 			break;
155 		case XLOG_SPGIST_VACUUM_ROOT:
156 			id = "VACUUM_ROOT";
157 			break;
158 		case XLOG_SPGIST_VACUUM_REDIRECT:
159 			id = "VACUUM_REDIRECT";
160 			break;
161 	}
162 
163 	return id;
164 }
165