1 /***********************************************************************************************************************************
2 Harness for PostgreSQL Interface
3 ***********************************************************************************************************************************/
4 #include "build.auto.h"
5 
6 #include "common/assert.h"
7 
8 #include "common/harnessDebug.h"
9 #include "common/harnessPostgres.h"
10 
11 /***********************************************************************************************************************************
12 Interface definition
13 ***********************************************************************************************************************************/
14 uint32_t hrnPgInterfaceCatalogVersion083(void);
15 void hrnPgInterfaceControl083(PgControl pgControl, unsigned char *buffer);
16 void hrnPgInterfaceWal083(PgWal pgWal, unsigned char *buffer);
17 
18 uint32_t hrnPgInterfaceCatalogVersion084(void);
19 void hrnPgInterfaceControl084(PgControl pgControl, unsigned char *buffer);
20 void hrnPgInterfaceWal084(PgWal pgWal, unsigned char *buffer);
21 
22 uint32_t hrnPgInterfaceCatalogVersion090(void);
23 void hrnPgInterfaceControl090(PgControl pgControl, unsigned char *buffer);
24 void hrnPgInterfaceWal090(PgWal pgWal, unsigned char *buffer);
25 
26 uint32_t hrnPgInterfaceCatalogVersion091(void);
27 void hrnPgInterfaceControl091(PgControl pgControl, unsigned char *buffer);
28 void hrnPgInterfaceWal091(PgWal pgWal, unsigned char *buffer);
29 
30 uint32_t hrnPgInterfaceCatalogVersion092(void);
31 void hrnPgInterfaceControl092(PgControl pgControl, unsigned char *buffer);
32 void hrnPgInterfaceWal092(PgWal pgWal, unsigned char *buffer);
33 
34 uint32_t hrnPgInterfaceCatalogVersion093(void);
35 void hrnPgInterfaceControl093(PgControl pgControl, unsigned char *buffer);
36 void hrnPgInterfaceWal093(PgWal pgWal, unsigned char *buffer);
37 
38 uint32_t hrnPgInterfaceCatalogVersion094(void);
39 void hrnPgInterfaceControl094(PgControl pgControl, unsigned char *buffer);
40 void hrnPgInterfaceWal094(PgWal pgWal, unsigned char *buffer);
41 
42 uint32_t hrnPgInterfaceCatalogVersion095(void);
43 void hrnPgInterfaceControl095(PgControl pgControl, unsigned char *buffer);
44 void hrnPgInterfaceWal095(PgWal pgWal, unsigned char *buffer);
45 
46 uint32_t hrnPgInterfaceCatalogVersion096(void);
47 void hrnPgInterfaceControl096(PgControl pgControl, unsigned char *buffer);
48 void hrnPgInterfaceWal096(PgWal pgWal, unsigned char *buffer);
49 
50 uint32_t hrnPgInterfaceCatalogVersion100(void);
51 void hrnPgInterfaceControl100(PgControl pgControl, unsigned char *buffer);
52 void hrnPgInterfaceWal100(PgWal pgWal, unsigned char *buffer);
53 
54 uint32_t hrnPgInterfaceCatalogVersion110(void);
55 void hrnPgInterfaceControl110(PgControl pgControl, unsigned char *buffer);
56 void hrnPgInterfaceWal110(PgWal pgWal, unsigned char *buffer);
57 
58 uint32_t hrnPgInterfaceCatalogVersion120(void);
59 void hrnPgInterfaceControl120(PgControl pgControl, unsigned char *buffer);
60 void hrnPgInterfaceWal120(PgWal pgWal, unsigned char *buffer);
61 
62 uint32_t hrnPgInterfaceCatalogVersion130(void);
63 void hrnPgInterfaceControl130(PgControl pgControl, unsigned char *buffer);
64 void hrnPgInterfaceWal130(PgWal pgWal, unsigned char *buffer);
65 
66 uint32_t hrnPgInterfaceCatalogVersion140(void);
67 void hrnPgInterfaceControl140(PgControl pgControl, unsigned char *buffer);
68 void hrnPgInterfaceWal140(PgWal pgWal, unsigned char *buffer);
69 
70 typedef struct HrnPgInterface
71 {
72     // Version of PostgreSQL supported by this interface
73     unsigned int version;
74 
75     // Catalog version
76     unsigned int (*catalogVersion)(void);
77 
78     // Create pg_control
79     void (*control)(PgControl, unsigned char *);
80 
81     // Create WAL header
82     void (*wal)(PgWal, unsigned char *);
83 } HrnPgInterface;
84 
85 static const HrnPgInterface hrnPgInterface[] =
86 {
87     {
88         .version = PG_VERSION_14,
89 
90         .catalogVersion = hrnPgInterfaceCatalogVersion140,
91         .control = hrnPgInterfaceControl140,
92         .wal = hrnPgInterfaceWal140,
93     },
94     {
95         .version = PG_VERSION_13,
96 
97         .catalogVersion = hrnPgInterfaceCatalogVersion130,
98         .control = hrnPgInterfaceControl130,
99         .wal = hrnPgInterfaceWal130,
100     },
101     {
102         .version = PG_VERSION_12,
103 
104         .catalogVersion = hrnPgInterfaceCatalogVersion120,
105         .control = hrnPgInterfaceControl120,
106         .wal = hrnPgInterfaceWal120,
107     },
108     {
109         .version = PG_VERSION_11,
110 
111         .catalogVersion = hrnPgInterfaceCatalogVersion110,
112         .control = hrnPgInterfaceControl110,
113         .wal = hrnPgInterfaceWal110,
114     },
115     {
116         .version = PG_VERSION_10,
117 
118         .catalogVersion = hrnPgInterfaceCatalogVersion100,
119         .control = hrnPgInterfaceControl100,
120         .wal = hrnPgInterfaceWal100,
121     },
122     {
123         .version = PG_VERSION_96,
124 
125         .catalogVersion = hrnPgInterfaceCatalogVersion096,
126         .control = hrnPgInterfaceControl096,
127         .wal = hrnPgInterfaceWal096,
128     },
129     {
130         .version = PG_VERSION_95,
131 
132         .catalogVersion = hrnPgInterfaceCatalogVersion095,
133         .control = hrnPgInterfaceControl095,
134         .wal = hrnPgInterfaceWal095,
135     },
136     {
137         .version = PG_VERSION_94,
138 
139         .catalogVersion = hrnPgInterfaceCatalogVersion094,
140         .control = hrnPgInterfaceControl094,
141         .wal = hrnPgInterfaceWal094,
142     },
143     {
144         .version = PG_VERSION_93,
145 
146         .catalogVersion = hrnPgInterfaceCatalogVersion093,
147         .control = hrnPgInterfaceControl093,
148         .wal = hrnPgInterfaceWal093,
149     },
150     {
151         .version = PG_VERSION_92,
152 
153         .catalogVersion = hrnPgInterfaceCatalogVersion092,
154         .control = hrnPgInterfaceControl092,
155         .wal = hrnPgInterfaceWal092,
156     },
157     {
158         .version = PG_VERSION_91,
159         .catalogVersion = hrnPgInterfaceCatalogVersion091,
160         .control = hrnPgInterfaceControl091,
161         .wal = hrnPgInterfaceWal091,
162     },
163     {
164         .version = PG_VERSION_90,
165 
166         .catalogVersion = hrnPgInterfaceCatalogVersion090,
167         .control = hrnPgInterfaceControl090,
168         .wal = hrnPgInterfaceWal090,
169     },
170     {
171         .version = PG_VERSION_84,
172 
173         .catalogVersion = hrnPgInterfaceCatalogVersion084,
174         .control = hrnPgInterfaceControl084,
175         .wal = hrnPgInterfaceWal084,
176     },
177     {
178         .version = PG_VERSION_83,
179 
180         .catalogVersion = hrnPgInterfaceCatalogVersion083,
181         .control = hrnPgInterfaceControl083,
182         .wal = hrnPgInterfaceWal083,
183     },
184 };
185 
186 /***********************************************************************************************************************************
187 Get the interface for a PostgreSQL version
188 ***********************************************************************************************************************************/
189 static const HrnPgInterface *
hrnPgInterfaceVersion(unsigned int pgVersion)190 hrnPgInterfaceVersion(unsigned int pgVersion)
191 {
192     FUNCTION_HARNESS_BEGIN();
193         FUNCTION_HARNESS_PARAM(UINT, pgVersion);
194     FUNCTION_HARNESS_END();
195 
196     const HrnPgInterface *result = NULL;
197 
198     for (unsigned int interfaceIdx = 0; interfaceIdx < sizeof(hrnPgInterface) / sizeof(HrnPgInterface); interfaceIdx++)
199     {
200         if (hrnPgInterface[interfaceIdx].version == pgVersion)
201         {
202             result = &hrnPgInterface[interfaceIdx];
203             break;
204         }
205     }
206 
207     // If the version was not found then error
208     if (result == NULL)
209         THROW_FMT(AssertError, "invalid " PG_NAME " version %u", pgVersion);
210 
211     FUNCTION_HARNESS_RETURN(STRUCT, result);
212 }
213 
214 /**********************************************************************************************************************************/
215 unsigned int
hrnPgCatalogVersion(unsigned int pgVersion)216 hrnPgCatalogVersion(unsigned int pgVersion)
217 {
218     FUNCTION_HARNESS_BEGIN();
219         FUNCTION_HARNESS_PARAM(UINT, pgVersion);
220     FUNCTION_HARNESS_END();
221 
222     FUNCTION_HARNESS_RETURN(UINT, hrnPgInterfaceVersion(pgVersion)->catalogVersion());
223 }
224 
225 /**********************************************************************************************************************************/
226 Buffer *
hrnPgControlToBuffer(PgControl pgControl)227 hrnPgControlToBuffer(PgControl pgControl)
228 {
229     FUNCTION_HARNESS_BEGIN();
230         FUNCTION_HARNESS_PARAM(PG_CONTROL, pgControl);
231     FUNCTION_HARNESS_END();
232 
233     // Set defaults if values are not passed
234     pgControl.pageSize = pgControl.pageSize == 0 ? PG_PAGE_SIZE_DEFAULT : pgControl.pageSize;
235     pgControl.walSegmentSize = pgControl.walSegmentSize == 0 ? PG_WAL_SEGMENT_SIZE_DEFAULT : pgControl.walSegmentSize;
236     pgControl.catalogVersion = pgControl.catalogVersion == 0 ?
237         hrnPgInterfaceVersion(pgControl.version)->catalogVersion() : pgControl.catalogVersion;
238 
239     // Create the buffer and clear it
240     Buffer *result = bufNew(HRN_PG_CONTROL_SIZE);
241     memset(bufPtr(result), 0, bufSize(result));
242     bufUsedSet(result, bufSize(result));
243 
244     // Generate pg_control
245     hrnPgInterfaceVersion(pgControl.version)->control(pgControl, bufPtr(result));
246 
247     FUNCTION_HARNESS_RETURN(BUFFER, result);
248 }
249 
250 /**********************************************************************************************************************************/
251 void
hrnPgWalToBuffer(PgWal pgWal,Buffer * walBuffer)252 hrnPgWalToBuffer(PgWal pgWal, Buffer *walBuffer)
253 {
254     FUNCTION_HARNESS_BEGIN();
255         FUNCTION_HARNESS_PARAM(PG_WAL, pgWal);
256         FUNCTION_HARNESS_PARAM(BUFFER, walBuffer);
257     FUNCTION_TEST_END();
258 
259     ASSERT(walBuffer != NULL);
260 
261     // Set default WAL segment size if not specified
262     if (pgWal.size == 0)
263         pgWal.size = PG_WAL_SEGMENT_SIZE_DEFAULT;
264 
265     // Generate WAL
266     hrnPgInterfaceVersion(pgWal.version)->wal(pgWal, bufPtr(walBuffer));
267 
268     FUNCTION_HARNESS_RETURN_VOID();
269 }
270