Skip to content

Commit 6611256

Browse files
committed
Fix portability issues in pg_amcheck's 004_verify_heapam.pl.
Test postgres#12 overwrote a 1-byte varlena header to make it look like the initial byte of a 4-byte varlena header, but the results were endian-dependent. Also, the byte "abc" that followed the overwritten byte would be interpreted differently depending on endian-ness. Overwrite 4 bytes instead, in an endian-aware manner. Test postgres#13 accidentally managed to depend on TOAST_MAX_CHUNK_SIZE, which varies slightly depending on MAXIMUM_ALIGNOF. That's not the point anyway, so make the regexp insensitive to the expected number of chunks. Mark Dilger Discussion: http://postgr.es/m/A80D68F6-E38F-482D-9522-E2FB6AAFE8A1@enterprisedb.com
1 parent 02b5940 commit 6611256

File tree

1 file changed

+42
-30
lines changed

1 file changed

+42
-30
lines changed

src/bin/pg_amcheck/t/004_verify_heapam.pl

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@
5353
# We choose to read and write binary copies of our table's tuples, using perl's
5454
# pack() and unpack() functions. Perl uses a packing code system in which:
5555
#
56+
# l = "signed 32-bit Long",
5657
# L = "Unsigned 32-bit Long",
5758
# S = "Unsigned 16-bit Short",
5859
# C = "Unsigned 8-bit Octet",
59-
# c = "signed 8-bit octet",
6060
# q = "signed 64-bit quadword"
6161
#
6262
# Each tuple in our table has a layout as follows:
@@ -72,16 +72,16 @@
7272
# xx t_hoff: x offset = 22 C
7373
# xx t_bits: x offset = 23 C
7474
# xx xx xx xx xx xx xx xx 'a': xxxxxxxx offset = 24 q
75-
# xx xx xx xx xx xx xx xx 'b': xxxxxxxx offset = 32 Cccccccc
76-
# xx xx xx xx xx xx xx xx 'c': xxxxxxxx offset = 40 SSSS
77-
# xx xx xx xx xx xx xx xx : xxxxxxxx ...continued SSSS
78-
# xx xx : xx ...continued S
75+
# xx xx xx xx xx xx xx xx 'b': xxxxxxxx offset = 32 CCCCCCCC
76+
# xx xx xx xx xx xx xx xx 'c': xxxxxxxx offset = 40 CCllLL
77+
# xx xx xx xx xx xx xx xx : xxxxxxxx ...continued
78+
# xx xx : xx ...continued
7979
#
8080
# We could choose to read and write columns 'b' and 'c' in other ways, but
8181
# it is convenient enough to do it this way. We define packing code
8282
# constants here, where they can be compared easily against the layout.
8383

84-
use constant HEAPTUPLE_PACK_CODE => 'LLLSSSSSCCqCcccccccSSSSSSSSS';
84+
use constant HEAPTUPLE_PACK_CODE => 'LLLSSSSSCCqCCCCCCCCCCllLL';
8585
use constant HEAPTUPLE_PACK_LENGTH => 58; # Total size
8686

8787
# Read a tuple of our table from a heap page.
@@ -121,15 +121,12 @@ sub read_tuple
121121
b_body5 => shift,
122122
b_body6 => shift,
123123
b_body7 => shift,
124-
c1 => shift,
125-
c2 => shift,
126-
c3 => shift,
127-
c4 => shift,
128-
c5 => shift,
129-
c6 => shift,
130-
c7 => shift,
131-
c8 => shift,
132-
c9 => shift);
124+
c_va_header => shift,
125+
c_va_vartag => shift,
126+
c_va_rawsize => shift,
127+
c_va_extsize => shift,
128+
c_va_valueid => shift,
129+
c_va_toastrelid => shift);
133130
# Stitch together the text for column 'b'
134131
$tup{b} = join('', map { chr($tup{"b_body$_"}) } (1..7));
135132
return \%tup;
@@ -168,15 +165,12 @@ sub write_tuple
168165
$tup->{b_body5},
169166
$tup->{b_body6},
170167
$tup->{b_body7},
171-
$tup->{c1},
172-
$tup->{c2},
173-
$tup->{c3},
174-
$tup->{c4},
175-
$tup->{c5},
176-
$tup->{c6},
177-
$tup->{c7},
178-
$tup->{c8},
179-
$tup->{c9});
168+
$tup->{c_va_header},
169+
$tup->{c_va_vartag},
170+
$tup->{c_va_rawsize},
171+
$tup->{c_va_extsize},
172+
$tup->{c_va_valueid},
173+
$tup->{c_va_toastrelid});
180174
seek($fh, $offset, 0)
181175
or BAIL_OUT("seek failed: $!");
182176
defined(syswrite($fh, $buffer, HEAPTUPLE_PACK_LENGTH))
@@ -273,6 +267,7 @@ sub write_tuple
273267
or BAIL_OUT("open failed: $!");
274268
binmode $file;
275269

270+
my $ENDIANNESS;
276271
for (my $tupidx = 0; $tupidx < ROWCOUNT; $tupidx++)
277272
{
278273
my $offnum = $tupidx + 1; # offnum is 1-based, not zero-based
@@ -289,6 +284,9 @@ sub write_tuple
289284
plan skip_all => qq(Page layout differs from our expectations: expected (12345678, "abcdefg"), got ($a, "$b"));
290285
exit;
291286
}
287+
288+
# Determine endianness of current platform from the 1-byte varlena header
289+
$ENDIANNESS = $tup->{b_header} == 0x11 ? "little" : "big";
292290
}
293291
close($file)
294292
or BAIL_OUT("close failed: $!");
@@ -459,22 +457,36 @@ sub header
459457
}
460458
elsif ($offnum == 12)
461459
{
462-
# Corrupt the bits in column 'b' 1-byte varlena header
463-
$tup->{b_header} = 0x80;
460+
# Overwrite column 'b' 1-byte varlena header and initial characters to
461+
# look like a long 4-byte varlena
462+
#
463+
# On little endian machines, bytes ending in two zero bits (xxxxxx00 bytes)
464+
# are 4-byte length word, aligned, uncompressed data (up to 1G). We set the
465+
# high six bits to 111111 and the lower two bits to 00, then the next three
466+
# bytes with 0xFF using 0xFCFFFFFF.
467+
#
468+
# On big endian machines, bytes starting in two zero bits (00xxxxxx bytes)
469+
# are 4-byte length word, aligned, uncompressed data (up to 1G). We set the
470+
# low six bits to 111111 and the high two bits to 00, then the next three
471+
# bytes with 0xFF using 0x3FFFFFFF.
472+
#
473+
$tup->{b_header} = $ENDIANNESS eq 'little' ? 0xFC : 0x3F;
474+
$tup->{b_body1} = 0xFF;
475+
$tup->{b_body2} = 0xFF;
476+
$tup->{b_body3} = 0xFF;
464477

465478
$header = header(0, $offnum, 1);
466479
push @expected,
467-
qr/${header}attribute 1 with length 4294967295 ends at offset 416848000 beyond total tuple length 58/;
480+
qr/${header}attribute \d+ with length \d+ ends at offset \d+ beyond total tuple length \d+/;
468481
}
469482
elsif ($offnum == 13)
470483
{
471484
# Corrupt the bits in column 'c' toast pointer
472-
$tup->{c6} = 41;
473-
$tup->{c7} = 41;
485+
$tup->{c_va_valueid} = 0xFFFFFFFF;
474486

475487
$header = header(0, $offnum, 2);
476488
push @expected,
477-
qr/${header}final toast chunk number 0 differs from expected value 6/,
489+
qr/${header}final toast chunk number 0 differs from expected value \d+/,
478490
qr/${header}toasted value for attribute 2 missing from toast table/;
479491
}
480492
elsif ($offnum == 14)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy