]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix test_aio read_buffers() to work without cassert
authorMelanie Plageman <melanieplageman@gmail.com>
Tue, 31 Mar 2026 19:02:52 +0000 (15:02 -0400)
committerMelanie Plageman <melanieplageman@gmail.com>
Tue, 31 Mar 2026 19:02:52 +0000 (15:02 -0400)
In a production build, StartReadBuffers() doesn't populate all fields
of a ReadBuffersOperation for a buffer hit because no callers use them
(they are populated in assert builds).

read_buffers() (a test-only function) relied on some of these fields, so
AIO tests failed on non-assert builds (discovered on the buildfarm after
commit 020c02bd908).

Fix by tracking the required information ourselves in read_buffers() and
avoiding reliance on the ReadBuffersOperation unless we know that we did
IO.

Reported-by: Alexander Lakhin <exclusion@gmail.com>
Author: Melanie Plageman <melanieplageman@gmail.com>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/9ce8f5d8-8ab2-4aa2-b062-c5d74161069c%40gmail.com

src/test/modules/test_aio/test_aio.c

index a8267192cb77cf53cd491dbc2cbebc0c93403618..d7530681192f51974a7a274a0981dd7a8ad2192e 100644 (file)
@@ -719,6 +719,7 @@ read_buffers(PG_FUNCTION_ARGS)
        Buffer     *buffers;
        Datum      *buffers_datum;
        bool       *io_reqds;
+       int                *nblocks_per_io;
 
        Assert(nblocks > 0);
 
@@ -729,6 +730,7 @@ read_buffers(PG_FUNCTION_ARGS)
        buffers = palloc0(sizeof(Buffer) * nblocks);
        buffers_datum = palloc0(sizeof(Datum) * nblocks);
        io_reqds = palloc0(sizeof(bool) * nblocks);
+       nblocks_per_io = palloc0(sizeof(int) * nblocks);
 
        rel = relation_open(relid, AccessShareLock);
        smgr = RelationGetSmgr(rel);
@@ -754,6 +756,7 @@ read_buffers(PG_FUNCTION_ARGS)
                                                                                  startblock + nblocks_done,
                                                                                  &nblocks_this_io,
                                                                                  0);
+               nblocks_per_io[nios] = nblocks_this_io;
                nios++;
                nblocks_done += nblocks_this_io;
        }
@@ -777,7 +780,7 @@ read_buffers(PG_FUNCTION_ARGS)
        for (int nio = 0; nio < nios; nio++)
        {
                ReadBuffersOperation *operation = &operations[nio];
-               int                     nblocks_this_io = operation->nblocks;
+               int                     nblocks_this_io = nblocks_per_io[nio];
                Datum           values[6] = {0};
                bool            nulls[6] = {0};
                ArrayType  *buffers_arr;
@@ -785,9 +788,8 @@ read_buffers(PG_FUNCTION_ARGS)
                /* convert buffer array to datum array */
                for (int i = 0; i < nblocks_this_io; i++)
                {
-                       Buffer          buf = operation->buffers[i];
+                       Buffer          buf = buffers[nblocks_disp + i];
 
-                       Assert(buffers[nblocks_disp + i] == buf);
                        Assert(BufferGetBlockNumber(buf) == startblock + nblocks_disp + i);
 
                        buffers_datum[nblocks_disp + i] = Int32GetDatum(buf);
@@ -809,8 +811,8 @@ read_buffers(PG_FUNCTION_ARGS)
                values[2] = BoolGetDatum(io_reqds[nio]);
                nulls[2] = false;
 
-               /* foreign IO */
-               values[3] = BoolGetDatum(operation->foreign_io);
+               /* foreign IO - only valid when IO was required */
+               values[3] = BoolGetDatum(io_reqds[nio] ? operation->foreign_io : false);
                nulls[3] = false;
 
                /* nblocks */
@@ -827,13 +829,8 @@ read_buffers(PG_FUNCTION_ARGS)
        }
 
        /* release pins on all the buffers */
-       for (int nio = 0; nio < nios; nio++)
-       {
-               ReadBuffersOperation *operation = &operations[nio];
-
-               for (int i = 0; i < operation->nblocks; i++)
-                       ReleaseBuffer(operation->buffers[i]);
-       }
+       for (int i = 0; i < nblocks_done; i++)
+               ReleaseBuffer(buffers[i]);
 
        /*
         * Free explicitly, to have a chance to detect potential issues with too
@@ -843,6 +840,7 @@ read_buffers(PG_FUNCTION_ARGS)
        pfree(buffers);
        pfree(buffers_datum);
        pfree(io_reqds);
+       pfree(nblocks_per_io);
 
        relation_close(rel, NoLock);