Age Owner Branch data TLA Line data Source code
1 : : /*--------------------------------------------------------------------------
2 : : *
3 : : * test_ginpostinglist.c
4 : : * Test varbyte-encoding in ginpostinglist.c
5 : : *
6 : : * Copyright (c) 2019-2024, PostgreSQL Global Development Group
7 : : *
8 : : * IDENTIFICATION
9 : : * src/test/modules/test_ginpostinglist/test_ginpostinglist.c
10 : : *
11 : : * -------------------------------------------------------------------------
12 : : */
13 : : #include "postgres.h"
14 : :
15 : : #include "access/gin_private.h"
16 : : #include "access/ginblock.h"
17 : : #include "access/htup_details.h"
18 : : #include "fmgr.h"
19 : :
1691 heikki.linnakangas@i 20 :CBC 1 : PG_MODULE_MAGIC;
21 : :
22 : 2 : PG_FUNCTION_INFO_V1(test_ginpostinglist);
23 : :
24 : : /*
25 : : * Encodes a pair of TIDs, and decodes it back. The first TID is always
26 : : * (0, 1), the second one is formed from the blk/off arguments. The 'maxsize'
27 : : * argument is passed to ginCompressPostingList(); it can be used to test the
28 : : * overflow checks.
29 : : *
30 : : * The reason that we test a pair, instead of just a single TID, is that
31 : : * the GinPostingList stores the first TID as is, and the varbyte-encoding
32 : : * is only used for the deltas between TIDs. So testing a single TID would
33 : : * not exercise the varbyte encoding at all.
34 : : *
35 : : * This function prints NOTICEs to describe what is tested, and how large the
36 : : * resulting GinPostingList is. Any incorrect results, e.g. if the encode +
37 : : * decode round trip doesn't return the original input, are reported as
38 : : * ERRORs.
39 : : */
40 : : static void
41 : 4 : test_itemptr_pair(BlockNumber blk, OffsetNumber off, int maxsize)
42 : : {
43 : : ItemPointerData orig_itemptrs[2];
44 : : ItemPointer decoded_itemptrs;
45 : : GinPostingList *pl;
46 : : int nwritten;
47 : : int ndecoded;
48 : :
49 [ + - ]: 4 : elog(NOTICE, "testing with (%u, %d), (%u, %d), max %d bytes",
50 : : 0, 1, blk, off, maxsize);
51 : 4 : ItemPointerSet(&orig_itemptrs[0], 0, 1);
52 : 4 : ItemPointerSet(&orig_itemptrs[1], blk, off);
53 : :
54 : : /* Encode, and decode it back */
55 : 4 : pl = ginCompressPostingList(orig_itemptrs, 2, maxsize, &nwritten);
56 [ + - ]: 4 : elog(NOTICE, "encoded %d item pointers to %zu bytes",
57 : : nwritten, SizeOfGinPostingList(pl));
58 : :
59 [ - + ]: 4 : if (SizeOfGinPostingList(pl) > maxsize)
1691 heikki.linnakangas@i 60 [ # # ]:UBC 0 : elog(ERROR, "overflow: result was %zu bytes, max %d",
61 : : SizeOfGinPostingList(pl), maxsize);
62 : :
1691 heikki.linnakangas@i 63 :CBC 4 : decoded_itemptrs = ginPostingListDecode(pl, &ndecoded);
64 [ - + ]: 4 : if (nwritten != ndecoded)
1691 heikki.linnakangas@i 65 [ # # ]:UBC 0 : elog(NOTICE, "encoded %d itemptrs, %d came back", nwritten, ndecoded);
66 : :
67 : : /* Check the result */
1691 heikki.linnakangas@i 68 [ - + ]:CBC 4 : if (!ItemPointerEquals(&orig_itemptrs[0], &decoded_itemptrs[0]))
1691 heikki.linnakangas@i 69 [ # # ]:UBC 0 : elog(ERROR, "mismatch on first itemptr: (%u, %d) vs (%u, %d)",
70 : : 0, 1,
71 : : ItemPointerGetBlockNumber(&decoded_itemptrs[0]),
72 : : ItemPointerGetOffsetNumber(&decoded_itemptrs[0]));
73 : :
1691 heikki.linnakangas@i 74 [ + + ]:CBC 4 : if (ndecoded == 2 &&
75 [ - + ]: 3 : !ItemPointerEquals(&orig_itemptrs[0], &decoded_itemptrs[0]))
76 : : {
1691 heikki.linnakangas@i 77 [ # # ]:UBC 0 : elog(ERROR, "mismatch on second itemptr: (%u, %d) vs (%u, %d)",
78 : : 0, 1,
79 : : ItemPointerGetBlockNumber(&decoded_itemptrs[0]),
80 : : ItemPointerGetOffsetNumber(&decoded_itemptrs[0]));
81 : : }
1691 heikki.linnakangas@i 82 :CBC 4 : }
83 : :
84 : : /*
85 : : * SQL-callable entry point to perform all tests.
86 : : */
87 : : Datum
88 : 1 : test_ginpostinglist(PG_FUNCTION_ARGS)
89 : : {
90 : 1 : test_itemptr_pair(0, 2, 14);
91 : 1 : test_itemptr_pair(0, MaxHeapTuplesPerPage, 14);
92 : 1 : test_itemptr_pair(MaxBlockNumber, MaxHeapTuplesPerPage, 14);
93 : 1 : test_itemptr_pair(MaxBlockNumber, MaxHeapTuplesPerPage, 16);
94 : :
95 : 1 : PG_RETURN_VOID();
96 : : }
|