Repair ALTER EXTENSION ... SET SCHEMA.
[pgsql.git] / src / test / modules / test_slru / test_slru.c
blob068a21f125f7877dd196b2662071a10c5e3a142b
1 /*--------------------------------------------------------------------------
3 * test_slru.c
4 * Test correctness of SLRU functions.
6 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
9 * IDENTIFICATION
10 * src/test/modules/test_slru/test_slru.c
12 * -------------------------------------------------------------------------
15 #include "postgres.h"
17 #include "access/slru.h"
18 #include "access/transam.h"
19 #include "miscadmin.h"
20 #include "storage/fd.h"
21 #include "storage/ipc.h"
22 #include "storage/shmem.h"
23 #include "utils/builtins.h"
25 PG_MODULE_MAGIC;
28 * SQL-callable entry points
30 PG_FUNCTION_INFO_V1(test_slru_page_write);
31 PG_FUNCTION_INFO_V1(test_slru_page_writeall);
32 PG_FUNCTION_INFO_V1(test_slru_page_read);
33 PG_FUNCTION_INFO_V1(test_slru_page_readonly);
34 PG_FUNCTION_INFO_V1(test_slru_page_exists);
35 PG_FUNCTION_INFO_V1(test_slru_page_sync);
36 PG_FUNCTION_INFO_V1(test_slru_page_delete);
37 PG_FUNCTION_INFO_V1(test_slru_page_truncate);
38 PG_FUNCTION_INFO_V1(test_slru_delete_all);
40 /* Number of SLRU page slots */
41 #define NUM_TEST_BUFFERS 16
43 static SlruCtlData TestSlruCtlData;
44 #define TestSlruCtl (&TestSlruCtlData)
46 static shmem_request_hook_type prev_shmem_request_hook = NULL;
47 static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
49 static bool
50 test_slru_scan_cb(SlruCtl ctl, char *filename, int64 segpage, void *data)
52 elog(NOTICE, "Calling test_slru_scan_cb()");
53 return SlruScanDirCbDeleteAll(ctl, filename, segpage, data);
56 Datum
57 test_slru_page_write(PG_FUNCTION_ARGS)
59 int64 pageno = PG_GETARG_INT64(0);
60 char *data = text_to_cstring(PG_GETARG_TEXT_PP(1));
61 int slotno;
62 LWLock *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
64 LWLockAcquire(lock, LW_EXCLUSIVE);
65 slotno = SimpleLruZeroPage(TestSlruCtl, pageno);
67 /* these should match */
68 Assert(TestSlruCtl->shared->page_number[slotno] == pageno);
70 /* mark the page as dirty so as it would get written */
71 TestSlruCtl->shared->page_dirty[slotno] = true;
72 TestSlruCtl->shared->page_status[slotno] = SLRU_PAGE_VALID;
74 /* write given data to the page, up to the limit of the page */
75 strncpy(TestSlruCtl->shared->page_buffer[slotno], data,
76 BLCKSZ - 1);
78 SimpleLruWritePage(TestSlruCtl, slotno);
79 LWLockRelease(lock);
81 PG_RETURN_VOID();
84 Datum
85 test_slru_page_writeall(PG_FUNCTION_ARGS)
87 SimpleLruWriteAll(TestSlruCtl, true);
88 PG_RETURN_VOID();
91 Datum
92 test_slru_page_read(PG_FUNCTION_ARGS)
94 int64 pageno = PG_GETARG_INT64(0);
95 bool write_ok = PG_GETARG_BOOL(1);
96 char *data = NULL;
97 int slotno;
98 LWLock *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
100 /* find page in buffers, reading it if necessary */
101 LWLockAcquire(lock, LW_EXCLUSIVE);
102 slotno = SimpleLruReadPage(TestSlruCtl, pageno,
103 write_ok, InvalidTransactionId);
104 data = (char *) TestSlruCtl->shared->page_buffer[slotno];
105 LWLockRelease(lock);
107 PG_RETURN_TEXT_P(cstring_to_text(data));
110 Datum
111 test_slru_page_readonly(PG_FUNCTION_ARGS)
113 int64 pageno = PG_GETARG_INT64(0);
114 char *data = NULL;
115 int slotno;
116 LWLock *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
118 /* find page in buffers, reading it if necessary */
119 slotno = SimpleLruReadPage_ReadOnly(TestSlruCtl,
120 pageno,
121 InvalidTransactionId);
122 Assert(LWLockHeldByMe(lock));
123 data = (char *) TestSlruCtl->shared->page_buffer[slotno];
124 LWLockRelease(lock);
126 PG_RETURN_TEXT_P(cstring_to_text(data));
129 Datum
130 test_slru_page_exists(PG_FUNCTION_ARGS)
132 int64 pageno = PG_GETARG_INT64(0);
133 bool found;
134 LWLock *lock = SimpleLruGetBankLock(TestSlruCtl, pageno);
136 LWLockAcquire(lock, LW_EXCLUSIVE);
137 found = SimpleLruDoesPhysicalPageExist(TestSlruCtl, pageno);
138 LWLockRelease(lock);
140 PG_RETURN_BOOL(found);
143 Datum
144 test_slru_page_sync(PG_FUNCTION_ARGS)
146 int64 pageno = PG_GETARG_INT64(0);
147 FileTag ftag;
148 char path[MAXPGPATH];
150 /* note that this flushes the full file a segment is located in */
151 ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
152 SlruSyncFileTag(TestSlruCtl, &ftag, path);
154 elog(NOTICE, "Called SlruSyncFileTag() for segment %lld on path %s",
155 (long long) ftag.segno, path);
157 PG_RETURN_VOID();
160 Datum
161 test_slru_page_delete(PG_FUNCTION_ARGS)
163 int64 pageno = PG_GETARG_INT64(0);
164 FileTag ftag;
166 ftag.segno = pageno / SLRU_PAGES_PER_SEGMENT;
167 SlruDeleteSegment(TestSlruCtl, ftag.segno);
169 elog(NOTICE, "Called SlruDeleteSegment() for segment %lld",
170 (long long) ftag.segno);
172 PG_RETURN_VOID();
175 Datum
176 test_slru_page_truncate(PG_FUNCTION_ARGS)
178 int64 pageno = PG_GETARG_INT64(0);
180 SimpleLruTruncate(TestSlruCtl, pageno);
181 PG_RETURN_VOID();
184 Datum
185 test_slru_delete_all(PG_FUNCTION_ARGS)
187 /* this calls SlruScanDirCbDeleteAll() internally, ensuring deletion */
188 SlruScanDirectory(TestSlruCtl, test_slru_scan_cb, NULL);
190 PG_RETURN_VOID();
194 * Module load callbacks and initialization.
197 static void
198 test_slru_shmem_request(void)
200 if (prev_shmem_request_hook)
201 prev_shmem_request_hook();
203 /* reserve shared memory for the test SLRU */
204 RequestAddinShmemSpace(SimpleLruShmemSize(NUM_TEST_BUFFERS, 0));
207 static bool
208 test_slru_page_precedes_logically(int64 page1, int64 page2)
210 return page1 < page2;
213 static void
214 test_slru_shmem_startup(void)
217 * Short segments names are well tested elsewhere so in this test we are
218 * focusing on long names.
220 const bool long_segment_names = true;
221 const char slru_dir_name[] = "pg_test_slru";
222 int test_tranche_id;
223 int test_buffer_tranche_id;
225 if (prev_shmem_startup_hook)
226 prev_shmem_startup_hook();
229 * Create the SLRU directory if it does not exist yet, from the root of
230 * the data directory.
232 (void) MakePGDirectory(slru_dir_name);
234 /* initialize the SLRU facility */
235 test_tranche_id = LWLockNewTrancheId();
236 LWLockRegisterTranche(test_tranche_id, "test_slru_tranche");
238 test_buffer_tranche_id = LWLockNewTrancheId();
239 LWLockRegisterTranche(test_tranche_id, "test_buffer_tranche");
241 TestSlruCtl->PagePrecedes = test_slru_page_precedes_logically;
242 SimpleLruInit(TestSlruCtl, "TestSLRU",
243 NUM_TEST_BUFFERS, 0, slru_dir_name,
244 test_buffer_tranche_id, test_tranche_id, SYNC_HANDLER_NONE,
245 long_segment_names);
248 void
249 _PG_init(void)
251 if (!process_shared_preload_libraries_in_progress)
252 ereport(ERROR,
253 (errmsg("cannot load \"%s\" after startup", "test_slru"),
254 errdetail("\"%s\" must be loaded with shared_preload_libraries.",
255 "test_slru")));
257 prev_shmem_request_hook = shmem_request_hook;
258 shmem_request_hook = test_slru_shmem_request;
260 prev_shmem_startup_hook = shmem_startup_hook;
261 shmem_startup_hook = test_slru_shmem_startup;