]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix incorrect computations of length of null bitmap in pageinspect.
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 4 Jan 2018 19:59:00 +0000 (14:59 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 4 Jan 2018 19:59:00 +0000 (14:59 -0500)
Instead of using our standard macro for this calculation, this code
did it itself ... and got it wrong, leading to incorrect display of
the null bitmap in some cases.  Noted and fixed by Maksim Milyutin.

In passing, remove a uselessly duplicative error check.

Errors were introduced in commit d6061f83a; back-patch to 9.6
where that came in.

Maksim Milyutin, reviewed by Andrey Borodin

Discussion: https://postgr.es/m/ec295792-a69f-350f-6287-25a20e8f31d5@gmail.com

contrib/pageinspect/heapfuncs.c

index f8ac343cc196e41721e0d243587bb8b5a3147263..76d2cd1d278e10aeb465245ba93cc4bab1b2e1e8 100644 (file)
@@ -232,7 +232,7 @@ heap_page_items(PG_FUNCTION_ARGS)
                                        int                     bits_len;
 
                                        bits_len =
-                                               ((tuphdr->t_infomask2 & HEAP_NATTS_MASK) / 8 + 1) * 8;
+                                               BITMAPLEN(HeapTupleHeaderGetNatts(tuphdr)) * BITS_PER_BYTE;
                                        values[11] = CStringGetTextDatum(
                                                                         bits_to_text(tuphdr->t_bits, bits_len));
                                }
@@ -434,24 +434,19 @@ tuple_data_split(PG_FUNCTION_ARGS)
                int                     bits_str_len;
                int                     bits_len;
 
-               bits_len = (t_infomask2 & HEAP_NATTS_MASK) / 8 + 1;
+               bits_len = BITMAPLEN(t_infomask2 & HEAP_NATTS_MASK) * BITS_PER_BYTE;
                if (!t_bits_str)
                        ereport(ERROR,
                                        (errcode(ERRCODE_DATA_CORRUPTED),
                                         errmsg("argument of t_bits is null, but it is expected to be null and %d character long",
-                                                       bits_len * 8)));
+                                                       bits_len)));
 
                bits_str_len = strlen(t_bits_str);
-               if ((bits_str_len % 8) != 0)
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_DATA_CORRUPTED),
-                                        errmsg("length of t_bits is not a multiple of eight")));
-
-               if (bits_len * 8 != bits_str_len)
+               if (bits_len != bits_str_len)
                        ereport(ERROR,
                                        (errcode(ERRCODE_DATA_CORRUPTED),
                                         errmsg("unexpected length of t_bits %u, expected %d",
-                                                       bits_str_len, bits_len * 8)));
+                                                       bits_str_len, bits_len)));
 
                /* do the conversion */
                t_bits = text_to_bits(t_bits_str, bits_str_len);