Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
9d14146
Undo thinko in commit e78d1d6d4.
tglsfdc Jun 10, 2026
9d33a5a
xml2: Fix crash with namespace nodes in xpath_nodeset()
michaelpq Jun 11, 2026
987440b
Disallow negative values for max_retention_duration.
Jun 11, 2026
eb4e722
Fix race with timeline selection in logical decoding during promotion
michaelpq Jun 11, 2026
0e1f1ed
seg: Fix seg_out() to preserve the upper boundary's certainty indicator
hlinnaka Jun 11, 2026
79c65b9
Fix parsing of parenthesised OLD/NEW in RETURNING list.
deanrasheed Jun 11, 2026
7dd1532
IS JSON/JSON(): Protect against expressions uncoercible to text
alvherre Jun 11, 2026
3692a62
Fix translatable string construction
alvherre Jun 11, 2026
99db753
Fix type confusion in AddRelsyncInvalidationMessage
robertmhaas Jun 11, 2026
44196fd
Fix md5_password_warnings for role and database settings
MasaoFujii Jun 11, 2026
389bd4c
amcheck: Fix missing allequalimage corruption report
MasaoFujii Jun 12, 2026
8bf257a
Fix handling of namespace nodes in xpath() (xml)
michaelpq Jun 12, 2026
0e47bb5
Fix out-of-bounds write in RI fast-path batch on re-entry
amitlan Jun 12, 2026
67bd944
doc: fix reference for finding replication slots to drop
MasaoFujii Jun 12, 2026
4113873
Confine RI fast-path batching to the top transaction level
amitlan Jun 12, 2026
a8ee70b
Fix second race with timeline selection during promotion
michaelpq Jun 12, 2026
0b74df6
Update expected regression test output for xml_2.out
michaelpq Jun 12, 2026
5459223
Fix translatable string construction in psql
alvherre Jun 12, 2026
3e3d787
Adjust cross-version upgrade tests for seg_out() fix
adunstan Jun 12, 2026
da1eff0
amcheck: Use correct varlena size accessor in bt_normalize_tuple()
akorotkov Jun 13, 2026
0131e8f
Fix oversight in commit aa1f93a33.
Jun 14, 2026
2963dde
Doc: remove stale entry for removed aclitem[] ~ aclitem operator.
tglsfdc Jun 14, 2026
b78cd2b
Trim regression test expected output for xml
michaelpq Jun 15, 2026
e051188
Fix PQdescribePrepared with more than 7498 params
hlinnaka Jun 15, 2026
ca69696
Modernize pg_bsd_indent's error/warning reporting code.
tglsfdc Jun 15, 2026
8ebbf79
Doc: reword discussion of asterisk after table names in FROM.
tglsfdc Jun 15, 2026
6678b58
doc: Fix "Prev" link.
nathan-bossart Jun 15, 2026
a75bd48
Clean up quoting of variable strings within replication commands.
tglsfdc Jun 15, 2026
0dd93de
Fix inconsistencies with pg_restore --statistics[-only]
michaelpq Jun 15, 2026
d3b345e
pg_dump: Remove dead code in TAP tests
michaelpq Jun 15, 2026
e5f94c4
Fix various query jumble comments
david-rowley Jun 16, 2026
f6e4ec0
Reject oversized MCV lists in pg_restore_extended_stats()
michaelpq Jun 16, 2026
3f32804
Fix int32 overflow in ltree_compare()
hlinnaka Jun 16, 2026
ae39bd2
pg_restore: Use dependency-based matching for STATISTICS DATA
michaelpq Jun 16, 2026
e2a8cab
concurrent repack: check there are no leftover toast attribs
alvherre Jun 16, 2026
f50c329
logical decoding: Correctly free speculative insertion
alvherre Jun 16, 2026
9e28c0b
doc PG 19 relnotes: update to current
bmomjian Jun 16, 2026
9285737
Fix another instability in recovery TAP test 004_timeline_switch
michaelpq Jun 16, 2026
4e5920e
Fix to not allow null treatment to non window functions.
tatsuo-ishii Jun 17, 2026
68ace96
Fix RI fast-path for domain-typed FK columns
amitlan Jun 17, 2026
ab3023a
Fix error message typo.
tatsuo-ishii Jun 17, 2026
1f7dfe8
Add tuple deformation test for virtual generated columns
david-rowley Jun 17, 2026
f29299c
Silence uninitialized variable warning with some compiler versions
hlinnaka Jun 17, 2026
3048e81
Fix pgstat_count_io_op_time() calls passing incorrect information
michaelpq Jun 17, 2026
d2cea63
vacuumdb: Fix --missing-stats-only for partitioned indexes.
nathan-bossart Jun 17, 2026
da82fbb
jsonb_plperl, jsonb_plpython: Fix unguarded recursion and loops.
tglsfdc Jun 17, 2026
6222233
oauth_validator: Print captured stderr after call-count failure
jchampio Jun 17, 2026
4bd477d
libpq-oauth: Print libcurl version with OAUTHDEBUG_UNSAFE_TRACE
jchampio Jun 17, 2026
fd5ea2e
oauth: Skip call-count test for libcurl 8.20.0
jchampio Jun 17, 2026
e5c4058
Avoid errors during ALTER SUBSCRIPTION.
jeff-davis Jun 17, 2026
62c09cd
doc PG 19 relnotes: mention pg_dump{all} & standard_conforming_strings
bmomjian Jun 17, 2026
64797ad
Fix ALTER DOMAIN VALIDATE CONSTRAINT locking
MasaoFujii Jun 18, 2026
2dab2ce
doc PG 19 relnotes: remove VALIDATE CONSTRAINT lock item
bmomjian Jun 18, 2026
34b198b
doc PG 19 relnotes: update to current
bmomjian Jun 18, 2026
77b6dd9
Doc: Clarify that publication exclusions track table identity.
Jun 18, 2026
850b921
Fix PANIC with track_functions due to concurrent drop of pgstats entries
michaelpq Jun 18, 2026
bdae2c2
Avoid stale slot access after dropping obsolete synced slots.
Jun 18, 2026
29fb598
Make GetSnapshotData() more resilient on out-of-memory errors
michaelpq Jun 18, 2026
ff8bec8
Create TOAST table for partitions made by MERGE/SPLIT PARTITION
akorotkov Jun 18, 2026
7ca548f
Revert non-text output formats for pg_dumpall
adunstan Jun 15, 2026
b56a3d6
python tests: add the libpq ctypes layer and in-process Session
adunstan Jun 6, 2026
05bcb36
python tests: add the PostgresServer framework and pytest fixtures
adunstan Jun 6, 2026
ee9c5cc
python tests: add the pgtap plugin and wire pytest into the meson build
adunstan Jun 6, 2026
c2cc3bf
python tests: add SSL, LDAP, Kerberos, OAuth and pg_regress helpers
adunstan Jun 6, 2026
f012c3a
python tests: add README for the pytest/session framework
adunstan Jun 8, 2026
4e57853
python tests: convert the psql TAP suite to pytest
adunstan Jun 20, 2026
ed63530
python tests: convert the pg_ctl TAP suite to pytest
adunstan Jun 20, 2026
afa5635
python tests: convert the libpq TAP suite to pytest
adunstan Jun 20, 2026
9f8f090
python tests: convert recovery 001_stream_rep to pytest
adunstan Jun 20, 2026
b847e4c
python tests: convert subscription 001_rep_changes to pytest
adunstan Jun 20, 2026
a2f02fe
ci: run the pytest suite in CI
adunstan Jun 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions .github/workflows/pg-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ env:
-Dplperl=enabled
-Dplpython=enabled
-Dpltcl=enabled
-Dpytest=enabled
-Dreadline=enabled
-Dssl=openssl
-Dtap_tests=enabled
Expand Down Expand Up @@ -668,6 +669,15 @@ jobs:

- name: Test world
shell: *su_postgres_shell
# The pytest suite loads libpq in-process via ctypes. Here libpq is
# AddressSanitizer-instrumented, and ASan must come first in the link
# order; dlopening it into an otherwise uninstrumented python aborts
# with "ASan runtime does not come first". Preload the ASan runtime
# for the test run to satisfy that (a no-op for the already-instrumented
# server/client binaries). Scoped to this step so the build is
# unaffected; detect_leaks is already disabled via ASAN_OPTIONS.
env:
ADDITIONAL_SETUP: export LD_PRELOAD="$(gcc -print-file-name=libasan.so)"
run: *meson_test_world_cmd

- *linux_collect_cores_step
Expand Down Expand Up @@ -710,6 +720,8 @@ jobs:
openssl
p5.34-io-tty
p5.34-ipc-run
py312-pexpect
py312-pytest
python312
tcl
zstd
Expand Down Expand Up @@ -869,6 +881,7 @@ jobs:
-Dldap=enabled
-Dplperl=enabled
-Dplpython=enabled
-Dpytest=enabled
-Dssl=openssl
-Dtap_tests=enabled

Expand Down Expand Up @@ -956,9 +969,11 @@ jobs:
- name: Install dependencies
shell: pwsh
run: |
# meson is not preinstalled on windows-2022. Install via pip
# meson is not preinstalled on windows-2022. Install via pip.
# pytest enables the Python test suite (pexpect is omitted: it needs
# a pty, which Windows lacks, and the interactive tests importorskip).
echo ::group::pip
python -m pip install --upgrade meson
python -m pip install --upgrade meson pytest
if (!$?) { throw 'cmdfail' }
echo ::endgroup::

Expand Down Expand Up @@ -1096,6 +1111,7 @@ jobs:
${MINGW_PACKAGE_PREFIX}-meson \
${MINGW_PACKAGE_PREFIX}-perl \
${MINGW_PACKAGE_PREFIX}-pkgconf \
${MINGW_PACKAGE_PREFIX}-python-pytest \
${MINGW_PACKAGE_PREFIX}-readline \
${MINGW_PACKAGE_PREFIX}-zlib \
${MINGW_PACKAGE_PREFIX}-zstd
Expand Down
18 changes: 10 additions & 8 deletions contrib/amcheck/verify_nbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,14 +336,16 @@ bt_index_check_callback(Relation indrel, Relation heaprel, void *state, bool rea
if (indrel->rd_opfamily[i] == INTERVAL_BTREE_FAM_OID)
{
has_interval_ops = true;
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" metapage incorrectly indicates that deduplication is safe",
RelationGetRelationName(indrel)),
has_interval_ops
? errhint("This is known of \"interval\" indexes last built on a version predating 2023-11.")
: 0));
break;
}

ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" metapage incorrectly indicates that deduplication is safe",
RelationGetRelationName(indrel)),
has_interval_ops
? errhint("This is known of \"interval\" indexes last built on a version predating 2023-11.")
: 0));
}

/* Check index, possibly against table it is an index on */
Expand Down Expand Up @@ -2889,7 +2891,7 @@ bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
ItemPointerGetOffsetNumber(&(itup->t_tid)),
RelationGetRelationName(state->rel))));
else if (!VARATT_IS_COMPRESSED(DatumGetPointer(normalized[i])) &&
VARSIZE(DatumGetPointer(normalized[i])) > TOAST_INDEX_TARGET &&
VARSIZE_ANY(DatumGetPointer(normalized[i])) > TOAST_INDEX_TARGET &&
(att->attstorage == TYPSTORAGE_EXTENDED ||
att->attstorage == TYPSTORAGE_MAIN))
{
Expand Down
15 changes: 15 additions & 0 deletions contrib/jsonb_plperl/jsonb_plperl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <math.h>

#include "fmgr.h"
#include "miscadmin.h"
#include "plperl.h"
#include "utils/fmgrprotos.h"
#include "utils/jsonb.h"
Expand Down Expand Up @@ -66,6 +67,9 @@ Jsonb_to_SV(JsonbContainer *jsonb)
JsonbIterator *it;
JsonbIteratorToken r;

/* this can recurse via JsonbValue_to_SV() */
check_stack_depth();

it = JsonbIteratorInit(jsonb);
r = JsonbIteratorNext(&it, &v, true);

Expand Down Expand Up @@ -179,9 +183,20 @@ SV_to_JsonbValue(SV *in, JsonbInState *jsonb_state, bool is_elem)
dTHX;
JsonbValue out; /* result */

/* this can recurse via AV_to_JsonbValue() or HV_to_JsonbValue() */
check_stack_depth();

/* Dereference references recursively. */
while (SvROK(in))
{
/*
* It's possible for circular references to make this an infinite
* loop. Checking for such a situation seems like much more trouble
* than it's worth, but let's provide a way to break out of the loop.
*/
CHECK_FOR_INTERRUPTS();
in = SvRV(in);
}

switch (SvTYPE(in))
{
Expand Down
7 changes: 7 additions & 0 deletions contrib/jsonb_plpython/jsonb_plpython.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "postgres.h"

#include "miscadmin.h"
#include "plpy_elog.h"
#include "plpy_typeio.h"
#include "plpy_util.h"
Expand Down Expand Up @@ -143,6 +144,9 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb)
JsonbIterator *it;
PyObject *result;

/* this can recurse via PLyObject_FromJsonbValue() */
check_stack_depth();

it = JsonbIteratorInit(jsonb);
r = JsonbIteratorNext(&it, &v, true);

Expand Down Expand Up @@ -410,6 +414,9 @@ PLyObject_ToJsonbValue(PyObject *obj, JsonbInState *jsonb_state, bool is_elem)
{
JsonbValue *out;

/* this can recurse via PLyMapping_ToJsonbValue() */
check_stack_depth();

if (!PyUnicode_Check(obj))
{
if (PySequence_Check(obj))
Expand Down
10 changes: 10 additions & 0 deletions contrib/ltree/expected/ltree.out
Original file line number Diff line number Diff line change
Expand Up @@ -8226,3 +8226,13 @@ DETAIL: Total size of level exceeds the maximum allowed (65535 bytes).
SELECT (repeat('a|', 65535) || 'a')::lquery;
ERROR: lquery level has too many variants
DETAIL: Number of variants exceeds the maximum allowed (65535).
-- Test that ltree_compare() does not overflow with very deep paths.
WITH s AS (SELECT 'a'::ltree AS v),
l AS (SELECT (repeat('a.', 14999) || 'a')::ltree AS v)
SELECT (l.v > s.v) AS gt_ok, (l.v < s.v) AS lt_ok, (l.v = s.v) AS eq_ok
FROM s, l;
gt_ok | lt_ok | eq_ok
-------+-------+-------
t | f | f
(1 row)

1 change: 1 addition & 0 deletions contrib/ltree/ltree.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ bool ltree_execute(ITEM *curitem, void *checkval,
bool calcnot, bool (*chkcond) (void *checkval, ITEM *val));

int ltree_compare(const ltree *a, const ltree *b);
float ltree_compare_distance(const ltree *a, const ltree *b);
bool inner_isparent(const ltree *c, const ltree *p);
bool compare_subnode(ltree_level *t, char *qn, int len, bool prefix, bool ci);
ltree *lca_inner(ltree **a, int len);
Expand Down
6 changes: 3 additions & 3 deletions contrib/ltree/ltree_gist.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,11 @@ ltree_penalty(PG_FUNCTION_ARGS)
ltree_gist *newval = (ltree_gist *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *penalty = (float *) PG_GETARG_POINTER(2);
int siglen = LTREE_GET_SIGLEN();
int32 cmpr,
float cmpr,
cmpl;

cmpl = ltree_compare(LTG_GETLNODE(origval, siglen), LTG_GETLNODE(newval, siglen));
cmpr = ltree_compare(LTG_GETRNODE(newval, siglen), LTG_GETRNODE(origval, siglen));
cmpl = ltree_compare_distance(LTG_GETLNODE(origval, siglen), LTG_GETLNODE(newval, siglen));
cmpr = ltree_compare_distance(LTG_GETRNODE(newval, siglen), LTG_GETRNODE(origval, siglen));

*penalty = Max(cmpl, 0) + Max(cmpr, 0);

Expand Down
49 changes: 43 additions & 6 deletions contrib/ltree/ltree_op.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ PG_FUNCTION_INFO_V1(ltree2text);
PG_FUNCTION_INFO_V1(text2ltree);
PG_FUNCTION_INFO_V1(ltreeparentsel);

/*
* btree-comparison function.
*/
int
ltree_compare(const ltree *a, const ltree *b)
{
Expand All @@ -54,18 +57,52 @@ ltree_compare(const ltree *a, const ltree *b)
{
int res;

if ((res = memcmp(al->name, bl->name, Min(al->len, bl->len))) == 0)
res = memcmp(al->name, bl->name, Min(al->len, bl->len));
if (res == 0)
{
if (al->len != bl->len)
return (int) al->len - (int) bl->len;
}
else
return res;

an--;
bn--;
al = LEVEL_NEXT(al);
bl = LEVEL_NEXT(bl);
}

return a->numlevel - b->numlevel;
}

/*
* Returns a "distance" between a and b. If a < b, the distance is negative,
* consistent with the ltree_compare() ordering.
*/
float
ltree_compare_distance(const ltree *a, const ltree *b)
{
ltree_level *al = LTREE_FIRST(a);
ltree_level *bl = LTREE_FIRST(b);
int an = a->numlevel;
int bn = b->numlevel;

while (an > 0 && bn > 0)
{
int res;

res = memcmp(al->name, bl->name, Min(al->len, bl->len));
if (res == 0)
{
if (al->len != bl->len)
return (al->len - bl->len) * 10 * (an + 1);
return (float) (al->len - bl->len) * 10.0 * (an + 1);
}
else
{
if (res < 0)
res = -1;
return -1.0 * 10.0 * (an + 1);
else
res = 1;
return res * 10 * (an + 1);
return 1.0 * 10.0 * (an + 1);
}

an--;
Expand All @@ -74,7 +111,7 @@ ltree_compare(const ltree *a, const ltree *b)
bl = LEVEL_NEXT(bl);
}

return (a->numlevel - b->numlevel) * 10 * (an + 1);
return ((float) (a->numlevel - b->numlevel)) * 10.0 * (an + 1);
}

#define RUNCMP \
Expand Down
6 changes: 6 additions & 0 deletions contrib/ltree/sql/ltree.sql
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,9 @@ SELECT (repeat('x', 255) || repeat('|' || repeat('x', 255), 256))::lquery;
--- Test for overflow of lquery_level.numvar, with a set of single-char
--- variants in one level.
SELECT (repeat('a|', 65535) || 'a')::lquery;

-- Test that ltree_compare() does not overflow with very deep paths.
WITH s AS (SELECT 'a'::ltree AS v),
l AS (SELECT (repeat('a.', 14999) || 'a')::ltree AS v)
SELECT (l.v > s.v) AS gt_ok, (l.v < s.v) AS lt_ok, (l.v = s.v) AS eq_ok
FROM s, l;
2 changes: 1 addition & 1 deletion contrib/postgres_fdw/postgres_fdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -6024,7 +6024,7 @@ remattrmap_cmp(const void *v1, const void *v2)
const RemoteAttributeMapping *r1 = v1;
const RemoteAttributeMapping *r2 = v2;

return strncmp(r1->remote_attname, r2->remote_attname, NAMEDATALEN);
return strcmp(r1->remote_attname, r2->remote_attname);
}

/*
Expand Down
45 changes: 44 additions & 1 deletion contrib/seg/expected/seg.out
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,8 @@ SELECT '12.345678901234560000000000000000000000000000000000000000000000000000000
12.3457
(1 row)

-- Numbers with certainty indicators
-- Numbers and ranges with certainty indicators. Certainty indicators
-- are stored and preserved on output, but ignored by operators.
SELECT '~6.5'::seg AS seg;
seg
------
Expand Down Expand Up @@ -300,6 +301,48 @@ SELECT '> 6.5'::seg AS seg;
>6.5
(1 row)

SELECT '~1.5 .. 2.5'::seg AS seg;
seg
-------------
~1.5 .. 2.5
(1 row)

SELECT '1.5 .. ~2.5'::seg AS seg;
seg
-------------
1.5 .. ~2.5
(1 row)

SELECT '~1.5 .. ~2.5'::seg AS seg;
seg
--------------
~1.5 .. ~2.5
(1 row)

SELECT '<1.5 .. 2.5'::seg AS seg;
seg
-------------
<1.5 .. 2.5
(1 row)

SELECT '1.5 .. <2.5'::seg AS seg;
seg
-------------
1.5 .. <2.5
(1 row)

SELECT '>1.5 .. 2.5'::seg AS seg;
seg
-------------
>1.5 .. 2.5
(1 row)

SELECT '1.5 .. >2.5'::seg AS seg;
seg
-------------
1.5 .. >2.5
(1 row)

-- Open intervals
SELECT '0..'::seg AS seg;
seg
Expand Down
2 changes: 1 addition & 1 deletion contrib/seg/seg.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ seg_out(PG_FUNCTION_ARGS)
{
/* print the upper boundary if exists */
p += sprintf(p, " ");
if (seg->u_ext == '>' || seg->u_ext == '<' || seg->l_ext == '~')
if (seg->u_ext == '>' || seg->u_ext == '<' || seg->u_ext == '~')
p += sprintf(p, "%c", seg->u_ext);
p += restore(p, seg->upper, seg->u_sigd);
}
Expand Down
11 changes: 10 additions & 1 deletion contrib/seg/sql/seg.sql
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,23 @@ SELECT '12.34567890123456'::seg AS seg;
-- Same, with a very long input
SELECT '12.3456789012345600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'::seg AS seg;

-- Numbers with certainty indicators
-- Numbers and ranges with certainty indicators. Certainty indicators
-- are stored and preserved on output, but ignored by operators.
SELECT '~6.5'::seg AS seg;
SELECT '<6.5'::seg AS seg;
SELECT '>6.5'::seg AS seg;
SELECT '~ 6.5'::seg AS seg;
SELECT '< 6.5'::seg AS seg;
SELECT '> 6.5'::seg AS seg;

SELECT '~1.5 .. 2.5'::seg AS seg;
SELECT '1.5 .. ~2.5'::seg AS seg;
SELECT '~1.5 .. ~2.5'::seg AS seg;
SELECT '<1.5 .. 2.5'::seg AS seg;
SELECT '1.5 .. <2.5'::seg AS seg;
SELECT '>1.5 .. 2.5'::seg AS seg;
SELECT '1.5 .. >2.5'::seg AS seg;

-- Open intervals
SELECT '0..'::seg AS seg;
SELECT '0...'::seg AS seg;
Expand Down
Loading
Loading