Hi,
(Astute observers will notice that Claude loves the sound of its own
voice - or my voice which it's trying to emulate - a lot more than I do.
I have trimmed the text quite a bit.)
Tom observed in [1] that nothing in the buildfarm builds a cluster
with locale C and encoding UTF8, that this is where the recent
to_date() crash went undetected, and that the animal configuration had
no way to ask for one. I've taught the buildfarm client to accept an
encoding alongside the locale. However, it's not yet released, because
running an animal that way turned up two things, and the second
explains in part why the first went unnoticed for as long as it did.
1. test_regex_utf8 depends on the ctype, not just the encoding
The file decides whether to run by looking at the encoding alone:
SELECT getdatabaseencoding() <> 'UTF8' AS skip_test \gset
but two of its cases also depend on the database ctype, so it fails in a
database with encoding UTF8 and locale C:
@@ -152,7 +152,7 @@
test_regex
-----------------
{0,REG_ULOCALE}
- {xᔀሷ}
+ {x}
(2 rows)
select * from test_regex('[[:lower:]]+', E'xᔀሷ', 'L');
@@ -166,7 +166,7 @@
test_regex
-----------------
{0,REG_ULOCALE}
- {xᔀሷ}
+ {x}
(2 rows)
The new output is the correct one: under ctype C, isgraph() and
isprint() are
false for anything outside ASCII, so only the x matches. The cases are
[[:graph:]] and [[:print:]] over E'xᔀሷ'. It isn't really about the regex
code;
the same difference shows up in plain SQL in two clusters differing only in
locale.
Those two are the only ctype-dependent assertions in the file —
everything else
uses explicit code point ranges such as [\u1000-\u2000], or an input with a
separator (x*, x_*) that ends the match inside ASCII, which is presumably
deliberate.
Patches 0001 (for 15 and 16) and 0002 (for 17+) attached.
0002 gives the two cases an explicit collation:
select * from test_regex('[[:graph:]]+', E'xᔀሷ' COLLATE pg_c_utf8,
'L');
select * from test_regex('[[:print:]]+', E'xᔀሷ' COLLATE pg_c_utf8,
'L');
test_regex.c already threads PG_GET_COLLATION() into the compile, and
pg_c_utf8 exists in every UTF8 database, which is the only place this file
runs. That returns {xᔀሷ} in a C+UTF8 database and in en_US.utf8, so the
result
lines in the expected file don't change at all — only the echoed query text
does. It seems to me strictly better than what's there now, since the cases
stop depending on how the animal happened to be initdb'd.
On 15 and 16 there's no collation to point at — ucs_basic has
collctype C, the builtin provider is 17+, and ICU depends on the build
— so 0001 just adds a second expected file with the C-ctype answers,
the way json_encoding.sql does for its two encodings.
I did consider just neutralising the two inputs, by putting a space or a
tab in
front of the non-ASCII characters the way x* and x_* already do elsewhere in
that block. It works and it backpatches everywhere. I'd be sorry to do it,
though: those two cases are the only ones in the file that exercise Unicode
ctype at all, and after such a change they would pass even if the ctype
lookup
for non-ASCII were completely broken.
2. collate.linux.utf8 has never run on a meson build
While checking whether anything else fails in a C+UTF8 database, I found
that
collate.linux.utf8 wasn't running on my build at all. Its guard includes
version() !~ 'linux-gnu'
and meson builds don't produce that string:
meson PostgreSQL 20devel on aarch64-linux, compiled by
gcc-13.3.0, 64-bit
autoconf PostgreSQL 20devel on aarch64-unknown-linux-gnu, compiled
by gcc ...
meson.build composes the platform part from host_machine.cpu_family() and
host_system, which gives <cpu>-linux on any platform and never carries
the ABI
suffix, where configure substitutes the GNU host triplet. On master
that file quits at its guard after 11 lines on an unpatched meson build, and
runs to 1196 lines with the patch below applied. That's been the case since
meson support went in, in 16.
infinite_recurse is the other test that matches on the platform string,
and it
gets it the other way round: it means to skip itself on ppc64 Linux
because of
a kernel bug, and on a meson build the match will never fire, so it will be
running the case it's meant to stay away from. I don't have a ppc64
machine to
confirm that end of it, so that part is a reading of the code rather than
something I've observed.
I think this wants fixing at both ends.
0003 relaxes the two guards so they match either spelling: "-linux[-,]" for
collate.linux.utf8 and "powerpc64[^,]*-linux" for infinite_recurse.
Keeping the
punctuation on either side confines the match to the platform field. Neither
pattern excludes musl, but collate.linux.utf8's other conditions already
require a set of glibc locales to be present, so a musl box still skips.
That's
test-only, so I'd backpatch it to 16 and get the coverage back
everywhere it's
been missing.
0004 makes the meson build report the GNU host triplet, by asking the
compiler
for it with -dumpmachine where it supports that and falling back to the
present
behaviour otherwise. That seems to me worth doing on its own account --
version()
ought to say the same thing whichever way you built, and things other
than these
two tests may look at it -- but it changes a user-visible string, so
master and
19 only. If people don't want to change the way this is done on meson,
that's
fine - patch 0003 will fix the test issue alone. But I thought it would
be good
to make meson behave the same as autoconf.
Waking this test on the meson animals may turn some of them red if they
don't have
the required locales, but that hasn't been a problem with autoconf
animals, so I
don't think we need any extra guards at this stage.
cheers
andrew
[1] https://postgr.es/m/3665293.1786715742%40sss.pgh.pa.us
--
Andrew Dunstan
EDB: https://www.enterprisedb.com
From fad93be0420654c19fa89053121cb8381abdee7f Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <[email protected]>
Date: Sat, 22 Aug 2026 17:45:54 -0400
Subject: [PATCH 1/4] Provide a C-ctype variant expected file for test_regex_utf8
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
test_regex_utf8 decides whether to run by looking at the database
encoding alone, but two of its cases, [[:graph:]] and [[:print:]] over
E'xᔀሷ', depend on the ctype as well. In a database with encoding
UTF8 and locale C they match just the x, because isgraph() and isprint()
are false for anything outside ASCII, and the file fails. That is the
right answer for such a database; the test was wrong to assume there
could only be one.
Fix by providing a second expected file holding the C-ctype answers.
This applies to REL_15_STABLE and REL_16_STABLE only.
---
.../test_regex/expected/test_regex_utf8_2.out | 206 ++++++++++++++++++
1 file changed, 206 insertions(+)
create mode 100644 src/test/modules/test_regex/expected/test_regex_utf8_2.out
diff --git a/src/test/modules/test_regex/expected/test_regex_utf8_2.out b/src/test/modules/test_regex/expected/test_regex_utf8_2.out
new file mode 100644
index 00000000000..46693c8b74f
--- /dev/null
+++ b/src/test/modules/test_regex/expected/test_regex_utf8_2.out
@@ -0,0 +1,206 @@
+/*
+ * This test must be run in a database with UTF-8 encoding,
+ * because other encodings don't support all the characters used.
+ */
+SELECT getdatabaseencoding() <> 'UTF8'
+ AS skip_test \gset
+\if :skip_test
+\quit
+\endif
+set client_encoding = utf8;
+set standard_conforming_strings = on;
+-- Run the Tcl test cases that require Unicode
+-- expectMatch 9.44 EMP* {a[\u00fe-\u0507][\u00ff-\u0300]b} \
+-- "a\u0102\u02ffb" "a\u0102\u02ffb"
+select * from test_regex('a[\u00fe-\u0507][\u00ff-\u0300]b', E'a\u0102\u02ffb', 'EMP*');
+ test_regex
+----------------------------------------
+ {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT}
+ {aĂ˿b}
+(2 rows)
+
+-- expectMatch 13.27 P "a\\U00001234x" "a\u1234x" "a\u1234x"
+select * from test_regex('a\U00001234x', E'a\u1234x', 'P');
+ test_regex
+-------------------
+ {0,REG_UNONPOSIX}
+ {aሴx}
+(2 rows)
+
+-- expectMatch 13.28 P {a\U00001234x} "a\u1234x" "a\u1234x"
+select * from test_regex('a\U00001234x', E'a\u1234x', 'P');
+ test_regex
+-------------------
+ {0,REG_UNONPOSIX}
+ {aሴx}
+(2 rows)
+
+-- expectMatch 13.29 P "a\\U0001234x" "a\u1234x" "a\u1234x"
+-- Tcl has relaxed their code to allow 1-8 hex digits, but Postgres hasn't
+select * from test_regex('a\U0001234x', E'a\u1234x', 'P');
+ERROR: invalid regular expression: invalid escape \ sequence
+-- expectMatch 13.30 P {a\U0001234x} "a\u1234x" "a\u1234x"
+-- Tcl has relaxed their code to allow 1-8 hex digits, but Postgres hasn't
+select * from test_regex('a\U0001234x', E'a\u1234x', 'P');
+ERROR: invalid regular expression: invalid escape \ sequence
+-- expectMatch 13.31 P "a\\U000012345x" "a\u12345x" "a\u12345x"
+select * from test_regex('a\U000012345x', E'a\u12345x', 'P');
+ test_regex
+-------------------
+ {0,REG_UNONPOSIX}
+ {aሴ5x}
+(2 rows)
+
+-- expectMatch 13.32 P {a\U000012345x} "a\u12345x" "a\u12345x"
+select * from test_regex('a\U000012345x', E'a\u12345x', 'P');
+ test_regex
+-------------------
+ {0,REG_UNONPOSIX}
+ {aሴ5x}
+(2 rows)
+
+-- expectMatch 13.33 P "a\\U1000000x" "a\ufffd0x" "a\ufffd0x"
+-- Tcl allows this as a standalone character, but Postgres doesn't
+select * from test_regex('a\U1000000x', E'a\ufffd0x', 'P');
+ERROR: invalid regular expression: invalid escape \ sequence
+-- expectMatch 13.34 P {a\U1000000x} "a\ufffd0x" "a\ufffd0x"
+-- Tcl allows this as a standalone character, but Postgres doesn't
+select * from test_regex('a\U1000000x', E'a\ufffd0x', 'P');
+ERROR: invalid regular expression: invalid escape \ sequence
+-- Additional tests, not derived from Tcl
+-- Exercise logic around high character ranges a bit more
+select * from test_regex('a
+ [\u1000-\u1100]*
+ [\u3000-\u3100]*
+ [\u1234-\u25ff]+
+ [\u2000-\u35ff]*
+ [\u2600-\u2f00]*
+ \u1236\u1236x',
+ E'a\u1234\u1236\u1236x', 'xEMP');
+ test_regex
+----------------------------------------
+ {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT}
+ {aሴሶሶx}
+(2 rows)
+
+select * from test_regex('[[:alnum:]]*[[:upper:]]*[\u1000-\u2000]*\u1237',
+ E'\u1500\u1237', 'ELMP');
+ test_regex
+----------------------------------------------------
+ {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT,REG_ULOCALE}
+ {ᔀሷ}
+(2 rows)
+
+select * from test_regex('[[:alnum:]]*[[:upper:]]*[\u1000-\u2000]*\u1237',
+ E'A\u1239', 'ELMP');
+ test_regex
+----------------------------------------------------
+ {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT,REG_ULOCALE}
+(1 row)
+
+select * from test_regex('[[:alnum:]]*[[:upper:]]*[\u1000-\u2000]*\u1237',
+ E'\u1500\u1237', 'iELMP');
+ test_regex
+----------------------------------------------------
+ {0,REG_UBBS,REG_UNONPOSIX,REG_UUNPORT,REG_ULOCALE}
+ {ᔀሷ}
+(2 rows)
+
+-- systematically test char classes
+select * from test_regex('[[:alnum:]]+', E'x*\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {x}
+(2 rows)
+
+select * from test_regex('[[:alpha:]]+', E'x*\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {x}
+(2 rows)
+
+select * from test_regex('[[:ascii:]]+', E'x\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {x}
+(2 rows)
+
+select * from test_regex('[[:blank:]]+', E'x \t\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {" "}
+(2 rows)
+
+select * from test_regex('[[:cntrl:]]+', E'x\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+(1 row)
+
+select * from test_regex('[[:digit:]]+', E'x9\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {9}
+(2 rows)
+
+select * from test_regex('[[:graph:]]+', E'x\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {x}
+(2 rows)
+
+select * from test_regex('[[:lower:]]+', E'x\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {x}
+(2 rows)
+
+select * from test_regex('[[:print:]]+', E'x\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {x}
+(2 rows)
+
+select * from test_regex('[[:punct:]]+', E'x.\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {.}
+(2 rows)
+
+select * from test_regex('[[:space:]]+', E'x \t\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {" "}
+(2 rows)
+
+select * from test_regex('[[:upper:]]+', E'xX\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {X}
+(2 rows)
+
+select * from test_regex('[[:xdigit:]]+', E'xa9\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {a9}
+(2 rows)
+
+select * from test_regex('[[:word:]]+', E'x_*\u1500\u1237', 'L');
+ test_regex
+-----------------
+ {0,REG_ULOCALE}
+ {x_}
+(2 rows)
+
--
2.43.0
From 0ee245f919dd45aabc8be245a5f8aa76661909d9 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <[email protected]>
Date: Sat, 22 Aug 2026 17:47:24 -0400
Subject: [PATCH 2/4] Pin two ctype-dependent test_regex_utf8 cases to a fixed
collation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
test_regex_utf8 decides whether to run by looking at the database
encoding alone, but two of its cases, [[:graph:]] and [[:print:]] over
E'xᔀሷ', depend on the ctype as well. In a database with encoding
UTF8 and locale C they match just the x, because isgraph() and isprint()
are false for anything outside ASCII, and the file fails. That is the
right answer for such a database; the test was wrong to assume there
could only be one.
Fix by giving the two cases an explicit collation, so that they exercise
a fixed Unicode ctype instead of whatever the database happened to be
initialized with. test_regex() already passes its input collation down
to the regex compiler. The expected results are unchanged; only the
echoed queries differ.
Backpatch to 17, where the builtin pg_c_utf8 collation appeared.
---
src/test/modules/test_regex/expected/test_regex_utf8.out | 6 ++++--
src/test/modules/test_regex/sql/test_regex_utf8.sql | 6 ++++--
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/test/modules/test_regex/expected/test_regex_utf8.out b/src/test/modules/test_regex/expected/test_regex_utf8.out
index 329780ef400..177eb1cacec 100644
--- a/src/test/modules/test_regex/expected/test_regex_utf8.out
+++ b/src/test/modules/test_regex/expected/test_regex_utf8.out
@@ -147,7 +147,9 @@ select * from test_regex('[[:digit:]]+', E'x9\u1500\u1237', 'L');
{9}
(2 rows)
-select * from test_regex('[[:graph:]]+', E'x\u1500\u1237', 'L');
+-- graph and print depend on the ctype and not just the encoding, so pin them
+-- to a Unicode-aware collation rather than the database's
+select * from test_regex('[[:graph:]]+', E'x\u1500\u1237' COLLATE pg_c_utf8, 'L');
test_regex
-----------------
{0,REG_ULOCALE}
@@ -161,7 +163,7 @@ select * from test_regex('[[:lower:]]+', E'x\u1500\u1237', 'L');
{x}
(2 rows)
-select * from test_regex('[[:print:]]+', E'x\u1500\u1237', 'L');
+select * from test_regex('[[:print:]]+', E'x\u1500\u1237' COLLATE pg_c_utf8, 'L');
test_regex
-----------------
{0,REG_ULOCALE}
diff --git a/src/test/modules/test_regex/sql/test_regex_utf8.sql b/src/test/modules/test_regex/sql/test_regex_utf8.sql
index 1f69f105fd7..d00599b3490 100644
--- a/src/test/modules/test_regex/sql/test_regex_utf8.sql
+++ b/src/test/modules/test_regex/sql/test_regex_utf8.sql
@@ -66,9 +66,11 @@ select * from test_regex('[[:ascii:]]+', E'x\u1500\u1237', 'L');
select * from test_regex('[[:blank:]]+', E'x \t\u1500\u1237', 'L');
select * from test_regex('[[:cntrl:]]+', E'x\u1500\u1237', 'L');
select * from test_regex('[[:digit:]]+', E'x9\u1500\u1237', 'L');
-select * from test_regex('[[:graph:]]+', E'x\u1500\u1237', 'L');
+-- graph and print depend on the ctype and not just the encoding, so pin them
+-- to a Unicode-aware collation rather than the database's
+select * from test_regex('[[:graph:]]+', E'x\u1500\u1237' COLLATE pg_c_utf8, 'L');
select * from test_regex('[[:lower:]]+', E'x\u1500\u1237', 'L');
-select * from test_regex('[[:print:]]+', E'x\u1500\u1237', 'L');
+select * from test_regex('[[:print:]]+', E'x\u1500\u1237' COLLATE pg_c_utf8, 'L');
select * from test_regex('[[:punct:]]+', E'x.\u1500\u1237', 'L');
select * from test_regex('[[:space:]]+', E'x \t\u1500\u1237', 'L');
select * from test_regex('[[:upper:]]+', E'xX\u1500\u1237', 'L');
--
2.43.0
From daa781b2e0e57108ac9425f02ca4eb7a5f3da2d2 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <[email protected]>
Date: Sat, 22 Aug 2026 17:38:06 -0400
Subject: [PATCH 3/4] Make the platform guards in two regression tests match meson
builds
collate.linux.utf8 skips itself unless version() matches "linux-gnu",
and infinite_recurse skips itself when version() matches
"powerpc64[^,]*-linux-gnu". configure substitutes the GNU host triplet
into that string, but the meson build composes it from
host_machine.cpu_family() and host_system, which gives "aarch64-linux"
and never carries the ABI suffix. So ever since meson support arrived
in 16, collate.linux.utf8 has not run at all on a meson build, and
infinite_recurse has been running on ppc64 Linux the very case it means
to stay away from.
Fix by matching "-linux[-,]" and "powerpc64[^,]*-linux", which match
both spellings. Keeping the punctuation on either side confines the
match to the platform field.
Backpatch to 16, where the meson build was introduced.
---
src/test/regress/expected/collate.linux.utf8.out | 2 +-
src/test/regress/expected/collate.linux.utf8_1.out | 2 +-
src/test/regress/expected/infinite_recurse.out | 2 +-
src/test/regress/expected/infinite_recurse_1.out | 2 +-
src/test/regress/sql/collate.linux.utf8.sql | 2 +-
src/test/regress/sql/infinite_recurse.sql | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/test/regress/expected/collate.linux.utf8.out b/src/test/regress/expected/collate.linux.utf8.out
index e0a39e4c300..27b5e57f6db 100644
--- a/src/test/regress/expected/collate.linux.utf8.out
+++ b/src/test/regress/expected/collate.linux.utf8.out
@@ -5,7 +5,7 @@
*/
SELECT getdatabaseencoding() <> 'UTF8' OR
(SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR
- version() !~ 'linux-gnu'
+ version() !~ '-linux[-,]'
AS skip_test \gset
\if :skip_test
\quit
diff --git a/src/test/regress/expected/collate.linux.utf8_1.out b/src/test/regress/expected/collate.linux.utf8_1.out
index ede5fdb5dcc..01faaa9fd1d 100644
--- a/src/test/regress/expected/collate.linux.utf8_1.out
+++ b/src/test/regress/expected/collate.linux.utf8_1.out
@@ -5,7 +5,7 @@
*/
SELECT getdatabaseencoding() <> 'UTF8' OR
(SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR
- version() !~ 'linux-gnu'
+ version() !~ '-linux[-,]'
AS skip_test \gset
\if :skip_test
\quit
diff --git a/src/test/regress/expected/infinite_recurse.out b/src/test/regress/expected/infinite_recurse.out
index aa102fadd83..f86b433b13e 100644
--- a/src/test/regress/expected/infinite_recurse.out
+++ b/src/test/regress/expected/infinite_recurse.out
@@ -10,7 +10,7 @@ create function infinite_recurse() returns int as
-- production kernels, so disable this test on such platforms.
-- (We still create the function, so as not to have a cross-platform
-- difference in the end state of the regression database.)
-SELECT version() ~ 'powerpc64[^,]*-linux-gnu'
+SELECT version() ~ 'powerpc64[^,]*-linux'
AS skip_test \gset
\if :skip_test
\quit
diff --git a/src/test/regress/expected/infinite_recurse_1.out b/src/test/regress/expected/infinite_recurse_1.out
index b2c99a0d0d4..296f24146f0 100644
--- a/src/test/regress/expected/infinite_recurse_1.out
+++ b/src/test/regress/expected/infinite_recurse_1.out
@@ -10,7 +10,7 @@ create function infinite_recurse() returns int as
-- production kernels, so disable this test on such platforms.
-- (We still create the function, so as not to have a cross-platform
-- difference in the end state of the regression database.)
-SELECT version() ~ 'powerpc64[^,]*-linux-gnu'
+SELECT version() ~ 'powerpc64[^,]*-linux'
AS skip_test \gset
\if :skip_test
\quit
diff --git a/src/test/regress/sql/collate.linux.utf8.sql b/src/test/regress/sql/collate.linux.utf8.sql
index 6d726ee9c99..9e627db3abb 100644
--- a/src/test/regress/sql/collate.linux.utf8.sql
+++ b/src/test/regress/sql/collate.linux.utf8.sql
@@ -6,7 +6,7 @@
SELECT getdatabaseencoding() <> 'UTF8' OR
(SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR
- version() !~ 'linux-gnu'
+ version() !~ '-linux[-,]'
AS skip_test \gset
\if :skip_test
\quit
diff --git a/src/test/regress/sql/infinite_recurse.sql b/src/test/regress/sql/infinite_recurse.sql
index 151dba4a7ae..b60a0599d03 100644
--- a/src/test/regress/sql/infinite_recurse.sql
+++ b/src/test/regress/sql/infinite_recurse.sql
@@ -13,7 +13,7 @@ create function infinite_recurse() returns int as
-- (We still create the function, so as not to have a cross-platform
-- difference in the end state of the regression database.)
-SELECT version() ~ 'powerpc64[^,]*-linux-gnu'
+SELECT version() ~ 'powerpc64[^,]*-linux'
AS skip_test \gset
\if :skip_test
\quit
--
2.43.0
From c6b54b4b3850c01212dccb2a518770031b2bebb3 Mon Sep 17 00:00:00 2001
From: Andrew Dunstan <[email protected]>
Date: Sat, 22 Aug 2026 17:21:02 -0400
Subject: [PATCH 4/4] meson: report the GNU host triplet in PG_VERSION_STR
The meson build composed the platform part of PG_VERSION_STR from
host_machine.cpu_family() and host_system, producing strings like
"aarch64-linux", where configure substitutes the GNU host triplet,
"aarch64-unknown-linux-gnu". Two regression tests match against that
string, and both have quietly been doing the wrong thing on meson builds
ever since meson support arrived in 16. collate.linux.utf8 skips itself
unless version() matches "linux-gnu", so it has never run at all;
infinite_recurse skips itself when version() matches
"powerpc64[^,]*-linux-gnu", so on ppc64 Linux it has been running the
very case it is meant to stay away from.
Fix by asking the compiler for its own target triplet with -dumpmachine
where it supports that, falling back to meson's idea of the host
otherwise.
Backpatch to 19
---
meson.build | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/meson.build b/meson.build
index f4cde249242..c0c10367b08 100644
--- a/meson.build
+++ b/meson.build
@@ -3293,10 +3293,23 @@ cdata.set('MEMSET_LOOP_LIMIT', memset_loop_limit)
cdata.set_quoted('DLSUFFIX', dlsuffix)
+# configure substitutes the GNU host triplet into PG_VERSION_STR, and some
+# regression tests match against it: collate.linux.utf8 looks for "linux-gnu",
+# and infinite_recurse looks for "powerpc64[^,]*-linux-gnu". Meson's own idea
+# of the host is just cpu_family-system, which never contains the ABI suffix,
+# so ask the compiler for the triplet when it can tell us.
+host_tuple = '@0@-@1@'.format(host_machine.cpu_family(), host_system)
+if cc.get_id() in ['gcc', 'clang']
+ dumpmachine = run_command(cc.cmd_array(), '-dumpmachine', check: false)
+ if dumpmachine.returncode() == 0 and dumpmachine.stdout().strip() != ''
+ host_tuple = dumpmachine.stdout().strip()
+ endif
+endif
+
# built later than the rest of the version metadata, we need SIZEOF_VOID_P
cdata.set_quoted('PG_VERSION_STR',
- 'PostgreSQL @0@ on @1@-@2@, compiled by @3@-@4@, @5@-bit'.format(
- pg_version, host_machine.cpu_family(), host_system,
+ 'PostgreSQL @0@ on @1@, compiled by @2@-@3@, @4@-bit'.format(
+ pg_version, host_tuple,
cc.get_id(), cc.version(), cdata.get('SIZEOF_VOID_P') * 8,
)
)
--
2.43.0