Simplify hash_xlog_split_allocate_page()
authorPeter Eisentraut <[email protected]>
Tue, 2 Dec 2025 08:10:02 +0000 (09:10 +0100)
committerPeter Eisentraut <[email protected]>
Tue, 2 Dec 2025 08:18:54 +0000 (09:18 +0100)
Instead of complicated pointer arithmetic, overlay a uint32 array and
just access the array members.  That's safe thanks to
XLogRecGetBlockData() returning a MAXALIGNed buffer.

Reviewed-by: Bertrand Drouvot <[email protected]>
Reviewed-by: Jacob Champion <[email protected]>
Discussion: https://www.postgresql.org/message-id/flat/aSQy2JawavlVlEB0%40ip-10-97-1-34.eu-west-3.compute.internal

src/backend/access/hash/hash_xlog.c

index 2a0145f3c9b18afaafb6149ba2dae6ac0ad84fd9..ad2e36d2ed93e52d3b778da4f1c798f2185c4e8f 100644 (file)
@@ -314,8 +314,6 @@ hash_xlog_split_allocate_page(XLogReaderState *record)
        Buffer          oldbuf;
        Buffer          newbuf;
        Buffer          metabuf;
-       Size            datalen PG_USED_FOR_ASSERTS_ONLY;
-       char       *data;
        XLogRedoAction action;
 
        /*
@@ -375,6 +373,10 @@ hash_xlog_split_allocate_page(XLogReaderState *record)
        {
                Page            page;
                HashMetaPage metap;
+               Size            datalen;
+               char       *data;
+               uint32     *uidata;
+               int                     uidatacount;
 
                page = BufferGetPage(metabuf);
                metap = HashPageGetMeta(page);
@@ -382,34 +384,31 @@ hash_xlog_split_allocate_page(XLogReaderState *record)
 
                data = XLogRecGetBlockData(record, 2, &datalen);
 
+               /*
+                * This cast is ok because XLogRecGetBlockData() returns a MAXALIGNed
+                * buffer.
+                */
+               uidata = (uint32 *) data;
+               uidatacount = 0;
+
                if (xlrec->flags & XLH_SPLIT_META_UPDATE_MASKS)
                {
-                       uint32          lowmask;
-                       uint32     *highmask;
-
-                       /* extract low and high masks. */
-                       memcpy(&lowmask, data, sizeof(uint32));
-                       highmask = (uint32 *) ((char *) data + sizeof(uint32));
+                       uint32          lowmask = uidata[uidatacount++];
+                       uint32          highmask = uidata[uidatacount++];
 
                        /* update metapage */
                        metap->hashm_lowmask = lowmask;
-                       metap->hashm_highmask = *highmask;
-
-                       data += sizeof(uint32) * 2;
+                       metap->hashm_highmask = highmask;
                }
 
                if (xlrec->flags & XLH_SPLIT_META_UPDATE_SPLITPOINT)
                {
-                       uint32          ovflpoint;
-                       uint32     *ovflpages;
-
-                       /* extract information of overflow pages. */
-                       memcpy(&ovflpoint, data, sizeof(uint32));
-                       ovflpages = (uint32 *) ((char *) data + sizeof(uint32));
+                       uint32          ovflpoint = uidata[uidatacount++];
+                       uint32          ovflpages = uidata[uidatacount++];
 
                        /* update metapage */
-                       metap->hashm_spares[ovflpoint] = *ovflpages;
                        metap->hashm_ovflpoint = ovflpoint;
+                       metap->hashm_spares[ovflpoint] = ovflpages;
                }
 
                MarkBufferDirty(metabuf);