Skip to content

Commit 6611256

Browse files
committed
Fix portability issues in pg_amcheck's 004_verify_heapam.pl.
Test #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 #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)