Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
5f9a56a
Fix handling of R/W expanded datums that are passed to SQL functions.
tglsfdc Aug 10, 2022
e5c72eb
Fix catalog lookup with the wrong snapshot during logical decoding.
Aug 11, 2022
2659c7c
Back-Patch "Add wait_for_subscription_sync for TAP tests."
Aug 12, 2022
377d3fa
doc: clarify DROP EXTENSION dependent members text
bmomjian Aug 12, 2022
1c3449c
doc: improve wal_level docs for the 'minimal' level
bmomjian Aug 12, 2022
e68b35a
doc: clarify CREATE TABLE AS ... IF NOT EXISTS
bmomjian Aug 12, 2022
021defb
doc: document the CREATE INDEX "USING" clause
bmomjian Aug 12, 2022
fc165d0
doc: clarify configuration file for Windows builds
bmomjian Aug 12, 2022
8a8a43c
doc: warn about security issues around log files
bmomjian Aug 12, 2022
cf901ee
doc: add section about heap-only tuples (HOT)
bmomjian Aug 12, 2022
4db1c8c
doc: add missing role attributes to user management section
bmomjian Aug 12, 2022
8183d6b
pg_upgrade: Fix some minor code issues
petere Aug 12, 2022
fa1ee5e
Catch stack overflow when recursing in transformFromClauseItem().
tglsfdc Aug 13, 2022
b02db5c
Avoid misbehavior when hash_table_bytes < bucket_size.
tglsfdc Aug 13, 2022
9133edc
Fix outdated --help message for postgres -f
michaelpq Aug 15, 2022
7c07ddb
Add missing bad-PGconn guards in libpq entry points.
tglsfdc Aug 15, 2022
a71825a
doc: fix wrong tag used in create sequence manual.
tatsuo-ishii Aug 16, 2022
826e57b
Fix replica identity check for a partitioned table.
Aug 16, 2022
b8d4174
doc: Remove reference to tty libpq connstring param
danielgustafsson Aug 16, 2022
d48a4af
Fix assert in logicalmsg_desc
tvondra Aug 16, 2022
920e86b
Fix subtly-incorrect matching of parent and child partitioned indexes.
tglsfdc Aug 18, 2022
c1bdf8a
Add CHECK_FOR_INTERRUPTS while decoding changes.
Aug 23, 2022
0920293
Doc: prefer sysctl to /proc/sys in docs and comments.
tglsfdc Aug 23, 2022
9092ea8
Doc: document possible need to raise kernel's somaxconn limit.
tglsfdc Aug 23, 2022
5a38548
Defend against stack overrun in a few more places.
tglsfdc Aug 24, 2022
f9b6d77
Use correct connection for cancellation in frontend's parallel slots
michaelpq Aug 27, 2022
c3daf01
Doc: fix example of recursive query.
tglsfdc Aug 28, 2022
e3b6a02
Prevent WAL corruption after a standby promotion.
robertmhaas Aug 29, 2022
22180bb
On NetBSD, force dynamic symbol resolution at postmaster start.
tglsfdc Aug 30, 2022
d1f57db
In the Snowball dictionary, don't try to stem excessively-long words.
tglsfdc Aug 31, 2022
47109a9
Prevent long-term memory leakage in autovacuum launcher.
tglsfdc Aug 31, 2022
8d7ca60
doc: simplify WITH clause syntax in CREATE DATABASE
bmomjian Aug 31, 2022
d02ba67
doc: show direction is optional in FETCH/MOVE's FROM/IN syntax
bmomjian Aug 31, 2022
e5ecc39
doc: document the maximum char/varchar length value
bmomjian Aug 31, 2022
bd6ad9d
doc: mention that SET TIME ZONE often needs to be quoted
bmomjian Sep 1, 2022
8b5399e
doc: warn of SECURITY DEFINER schemas for non-sql_body functions
bmomjian Sep 1, 2022
a10a5a5
doc: split out the NATURAL/CROSS JOIN in SELECT syntax
bmomjian Sep 1, 2022
0effb24
doc: clarify that pgcrypto's gen_random_uuid calls core func.
bmomjian Sep 1, 2022
1bbf6a4
doc: use FILTER in aggregate example
bmomjian Sep 1, 2022
8d9b46f
doc: mention "bloom" as a possible index access method
bmomjian Sep 1, 2022
1b38111
doc: in create statistics docs, mention analyze for parent info
bmomjian Sep 1, 2022
f03ffaf
Fix some possibly latent bugs in slab.c
david-rowley Sep 1, 2022
c94c562
Doc: Update struct Trigger definition.
Sep 2, 2022
c7460b6
doc: clarify recursion internal behavior
bmomjian Sep 3, 2022
68d670d
doc: simplify docs about analyze and inheritance/partitions
bmomjian Sep 3, 2022
7fe7ec0
doc: Fix two queries related to jsonb functions
michaelpq Sep 3, 2022
bc985dc
Doc: clarify partitioned table limitations
david-rowley Sep 5, 2022
857b490
Choose FK name correctly during partition attachment
alvherre Sep 8, 2022
463d9e9
Reject bogus output from uuid_create(3).
tglsfdc Sep 9, 2022
a7e1544
Fix possible omission of variable storage markers in ECPG.
tglsfdc Sep 9, 2022
89eba88
Fix NaN comparison in circle_same test
danielgustafsson Sep 12, 2022
5cc1d31
doc: Fix link to FreeBSD documentation project
danielgustafsson Sep 12, 2022
3d95002
Fix RAT check violation from e5c72eb
reshke Mar 16, 2026
493f7c5
Don't reference out-of-bounds array elements in brin_minmax_multi.c
david-rowley Sep 12, 2022
2034027
Expand palloc/pg_malloc API for more type safety
petere Sep 14, 2022
65a5481
Fix incorrect value for "strategy" with deflateParams() in walmethods.c
michaelpq Sep 14, 2022
c04f3d9
postgres_fdw: Avoid 'variable not found in subplan target list' error.
Sep 14, 2022
ae5a900
Detect format-string mistakes in the libpq_pipeline test module.
tglsfdc Sep 15, 2022
15bd047
Improve plpgsql's ability to handle arguments declared as RECORD.
tglsfdc Sep 16, 2022
80bb337
Include c.h instead of postgres.h in src/port/*p{read,write}*.c
anarazel Sep 17, 2022
36e38a4
Make check_usermap() parameter names consistent.
petergeoghegan Sep 17, 2022
c6128eb
Future-proof the recursion inside ExecShutdownNode().
tglsfdc Sep 19, 2022
f512e22
Fix incorrect variable types for origin IDs in decode.c
michaelpq Sep 20, 2022
3387c22
doc: Fix parameter name for pg_create_logical_replication_slot()
michaelpq Sep 20, 2022
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
3 changes: 1 addition & 2 deletions contrib/pax_storage/src/test/regress/expected/geometry.out
Original file line number Diff line number Diff line change
Expand Up @@ -4344,9 +4344,8 @@ SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 ~= c2.f1;
<(100,200),10> | <(100,200),10>
<(100,1),115> | <(100,1),115>
<(3,5),0> | <(3,5),0>
<(3,5),NaN> | <(3,5),0>
<(3,5),NaN> | <(3,5),NaN>
(9 rows)
(8 rows)

-- Overlap with circle
SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 && c2.f1;
Expand Down
79 changes: 79 additions & 0 deletions contrib/postgres_fdw/expected/postgres_fdw.out
Original file line number Diff line number Diff line change
Expand Up @@ -2467,6 +2467,85 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = f

RESET enable_nestloop;
RESET enable_hashjoin;
-- test that add_paths_with_pathkeys_for_rel() arranges for the epq_path to
-- return columns needed by the parent ForeignScan node
EXPLAIN (VERBOSE, COSTS OFF)
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.c3 || ft2.c3, 'foobar') FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100)) ss ON (local_tbl.c1 = ss.c1) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LockRows
Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, (COALESCE((ft1.c3 || ft2.c3), 'foobar'::text)), local_tbl.ctid, ft1.*, ft2.*
-> Merge Left Join
Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, (COALESCE((ft1.c3 || ft2.c3), 'foobar'::text)), local_tbl.ctid, ft1.*, ft2.*
Merge Cond: (local_tbl.c1 = ft1.c1)
-> Index Scan using local_tbl_pkey on public.local_tbl
Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.ctid
-> Materialize
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, (COALESCE((ft1.c3 || ft2.c3), 'foobar'::text))
-> Foreign Scan
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, COALESCE((ft1.c3 || ft2.c3), 'foobar'::text)
Relations: (public.ft1) INNER JOIN (public.ft2)
Remote SQL: SELECT r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8, CASE WHEN (r4.*)::text IS NOT NULL THEN ROW(r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8) END, CASE WHEN (r5.*)::text IS NOT NULL THEN ROW(r5."C 1", r5.c2, r5.c3, r5.c4, r5.c5, r5.c6, r5.c7, r5.c8) END, r5.c3 FROM ("S 1"."T 1" r4 INNER JOIN "S 1"."T 1" r5 ON (((r4."C 1" = r5."C 1")) AND ((r4."C 1" < 100)))) ORDER BY r4."C 1" ASC NULLS LAST
-> Result
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, ft2.c3
-> Sort
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, (COALESCE((ft1.c3 || ft2.c3), 'foobar'::text)), ft2.c3
Sort Key: ft1.c1
-> Hash Join
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, COALESCE((ft1.c3 || ft2.c3), 'foobar'::text), ft2.c3
Hash Cond: (ft1.c1 = ft2.c1)
-> Foreign Scan on public.ft1
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 100))
-> Hash
Output: ft2.*, ft2.c1, ft2.c3
-> Foreign Scan on public.ft2
Output: ft2.*, ft2.c1, ft2.c3
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1"
(29 rows)

ALTER SERVER loopback OPTIONS (DROP extensions);
ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0');
EXPLAIN (VERBOSE, COSTS OFF)
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND ft1.c1 = postgres_fdw_abs(ft2.c2))) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LockRows
Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, local_tbl.ctid, ft1.*, ft2.*
-> Nested Loop Left Join
Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, local_tbl.ctid, ft1.*, ft2.*
Join Filter: (local_tbl.c3 = ft1.c3)
-> Index Scan using local_tbl_pkey on public.local_tbl
Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.ctid
-> Materialize
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*
-> Foreign Scan
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*
Filter: (ft1.c1 = postgres_fdw_abs(ft2.c2))
Relations: (public.ft1) INNER JOIN (public.ft2)
Remote SQL: SELECT r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8, CASE WHEN (r4.*)::text IS NOT NULL THEN ROW(r4."C 1", r4.c2, r4.c3, r4.c4, r4.c5, r4.c6, r4.c7, r4.c8) END, CASE WHEN (r5.*)::text IS NOT NULL THEN ROW(r5."C 1", r5.c2, r5.c3, r5.c4, r5.c5, r5.c6, r5.c7, r5.c8) END, r5.c2 FROM ("S 1"."T 1" r4 INNER JOIN "S 1"."T 1" r5 ON (((r4."C 1" = r5."C 1")) AND ((r4."C 1" < 100)))) ORDER BY r4.c3 ASC NULLS LAST
-> Sort
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, ft2.c2
Sort Key: ft1.c3
-> Merge Join
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, ft2.c2
Merge Cond: ((ft1.c1 = (postgres_fdw_abs(ft2.c2))) AND (ft1.c1 = ft2.c1))
-> Sort
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*
Sort Key: ft1.c1
-> Foreign Scan on public.ft1
Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 100))
-> Sort
Output: ft2.*, ft2.c1, ft2.c2, (postgres_fdw_abs(ft2.c2))
Sort Key: (postgres_fdw_abs(ft2.c2)), ft2.c1
-> Foreign Scan on public.ft2
Output: ft2.*, ft2.c1, ft2.c2, postgres_fdw_abs(ft2.c2)
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST
(32 rows)

ALTER SERVER loopback OPTIONS (DROP fdw_startup_cost);
ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw');
DROP TABLE local_tbl;
-- check join pushdown in situations where multiple userids are involved
CREATE ROLE regress_view_owner SUPERUSER;
Expand Down
49 changes: 49 additions & 0 deletions contrib/postgres_fdw/postgres_fdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -5813,6 +5813,55 @@ add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel,

useful_pathkeys_list = get_useful_pathkeys_for_relation(root, rel);

/*
* Before creating sorted paths, arrange for the passed-in EPQ path, if
* any, to return columns needed by the parent ForeignScan node so that
* they will propagate up through Sort nodes injected below, if necessary.
*/
if (epq_path != NULL && useful_pathkeys_list != NIL)
{
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private;
PathTarget *target = copy_pathtarget(epq_path->pathtarget);

/* Include columns required for evaluating PHVs in the tlist. */
add_new_columns_to_pathtarget(target,
pull_var_clause((Node *) target->exprs,
PVC_RECURSE_PLACEHOLDERS));

/* Include columns required for evaluating the local conditions. */
foreach(lc, fpinfo->local_conds)
{
RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);

add_new_columns_to_pathtarget(target,
pull_var_clause((Node *) rinfo->clause,
PVC_RECURSE_PLACEHOLDERS));
}

/*
* If we have added any new columns, adjust the tlist of the EPQ path.
*
* Note: the plan created using this path will only be used to execute
* EPQ checks, where accuracy of the plan cost and width estimates
* would not be important, so we do not do set_pathtarget_cost_width()
* for the new pathtarget here. See also postgresGetForeignPlan().
*/
if (list_length(target->exprs) > list_length(epq_path->pathtarget->exprs))
{
/* The EPQ path is a join path, so it is projection-capable. */
Assert(is_projection_capable_path(epq_path));

/*
* Use create_projection_path() here, so as to avoid modifying it
* in place.
*/
epq_path = (Path *) create_projection_path(root,
rel,
epq_path,
target);
}
}

/* Create one path for each set of pathkeys we found above. */
foreach(lc, useful_pathkeys_list)
{
Expand Down
13 changes: 13 additions & 0 deletions contrib/postgres_fdw/sql/postgres_fdw.sql
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,19 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = f
AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE;
RESET enable_nestloop;
RESET enable_hashjoin;

-- test that add_paths_with_pathkeys_for_rel() arranges for the epq_path to
-- return columns needed by the parent ForeignScan node
EXPLAIN (VERBOSE, COSTS OFF)
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.c3 || ft2.c3, 'foobar') FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100)) ss ON (local_tbl.c1 = ss.c1) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;

ALTER SERVER loopback OPTIONS (DROP extensions);
ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0');
EXPLAIN (VERBOSE, COSTS OFF)
SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND ft1.c1 = postgres_fdw_abs(ft2.c2))) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl;
ALTER SERVER loopback OPTIONS (DROP fdw_startup_cost);
ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw');

DROP TABLE local_tbl;

-- check join pushdown in situations where multiple userids are involved
Expand Down
2 changes: 1 addition & 1 deletion contrib/test_decoding/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ REGRESS = ddl xact rewrite toast permissions decoding_in_xact \
spill slot truncate stream stats twophase twophase_stream
ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \
oldest_xmin snapshot_transfer subxact_without_top concurrent_stream \
twophase_snapshot
twophase_snapshot catalog_change_snapshot

REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf
ISOLATION_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf
Expand Down
44 changes: 44 additions & 0 deletions contrib/test_decoding/expected/catalog_change_snapshot.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
Parsed test spec with 2 sessions

starting permutation: s0_init s0_begin s0_savepoint s0_truncate s1_checkpoint s1_get_changes s0_commit s0_begin s0_insert s1_checkpoint s1_get_changes s0_commit s1_get_changes
step s0_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding');
?column?
--------
init
(1 row)

step s0_begin: BEGIN;
step s0_savepoint: SAVEPOINT sp1;
step s0_truncate: TRUNCATE tbl1;
step s1_checkpoint: CHECKPOINT;
step s1_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0');
data
----
(0 rows)

step s0_commit: COMMIT;
step s0_begin: BEGIN;
step s0_insert: INSERT INTO tbl1 VALUES (1);
step s1_checkpoint: CHECKPOINT;
step s1_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0');
data
---------------------------------------
BEGIN
table public.tbl1: TRUNCATE: (no-flags)
COMMIT
(3 rows)

step s0_commit: COMMIT;
step s1_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0');
data
-------------------------------------------------------------
BEGIN
table public.tbl1: INSERT: val1[integer]:1 val2[integer]:null
COMMIT
(3 rows)

?column?
--------
stop
(1 row)

39 changes: 39 additions & 0 deletions contrib/test_decoding/specs/catalog_change_snapshot.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Test decoding only the commit record of the transaction that have
# modified catalogs.
setup
{
DROP TABLE IF EXISTS tbl1;
CREATE TABLE tbl1 (val1 integer, val2 integer);
}

teardown
{
DROP TABLE tbl1;
SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot');
}

session "s0"
setup { SET synchronous_commit=on; }
step "s0_init" { SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); }
step "s0_begin" { BEGIN; }
step "s0_savepoint" { SAVEPOINT sp1; }
step "s0_truncate" { TRUNCATE tbl1; }
step "s0_insert" { INSERT INTO tbl1 VALUES (1); }
step "s0_commit" { COMMIT; }

session "s1"
setup { SET synchronous_commit=on; }
step "s1_checkpoint" { CHECKPOINT; }
step "s1_get_changes" { SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0'); }

# For the transaction that TRUNCATEd the table tbl1, the last decoding decodes
# only its COMMIT record, because it starts from the RUNNING_XACTS record emitted
# during the first checkpoint execution. This transaction must be marked as
# containing catalog changes while decoding the COMMIT record and the decoding
# of the INSERT record must read the pg_class with the correct historic snapshot.
#
# Note that in a case where bgwriter wrote the RUNNING_XACTS record between "s0_commit"
# and "s0_begin", this doesn't happen as the decoding starts from the RUNNING_XACTS
# record written by bgwriter. One might think we can either stop the bgwriter or
# increase LOG_SNAPSHOT_INTERVAL_MS but it's not practical via tests.
permutation "s0_init" "s0_begin" "s0_savepoint" "s0_truncate" "s1_checkpoint" "s1_get_changes" "s0_commit" "s0_begin" "s0_insert" "s1_checkpoint" "s1_get_changes" "s0_commit" "s1_get_changes"
12 changes: 12 additions & 0 deletions contrib/uuid-ossp/uuid-ossp.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,18 @@ uuid_generate_internal(int v, unsigned char *ns, const char *ptr, int len)
{
strlcpy(strbuf, str, 37);

/*
* In recent NetBSD, uuid_create() has started
* producing v4 instead of v1 UUIDs. Check the
* version field and complain if it's not v1.
*/
if (strbuf[14] != '1')
ereport(ERROR,
(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
/* translator: %c will be a hex digit */
errmsg("uuid_create() produced a version %c UUID instead of the expected version 1",
strbuf[14])));

/*
* PTR, if set, replaces the trailing characters of
* the uuid; this is to support v1mc, where a random
Expand Down
4 changes: 1 addition & 3 deletions doc/src/sgml/acronyms.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -299,9 +299,7 @@
<term><acronym>HOT</acronym></term>
<listitem>
<para>
<ulink
url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/access/heap/README.HOT;hb=HEAD">Heap-Only
Tuples</ulink>
<link linkend="storage-hot">Heap-Only Tuples</link>
</para>
</listitem>
</varlistentry>
Expand Down
3 changes: 2 additions & 1 deletion doc/src/sgml/btree.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,8 @@ options(<replaceable>relopts</replaceable> <type>local_relopts *</type>) returns
accumulate and adversely affect query latency and throughput. This
typically occurs with <command>UPDATE</command>-heavy workloads
where most individual updates cannot apply the
<acronym>HOT</acronym> optimization. Changing the value of only
<link linkend="storage-hot"><acronym>HOT</acronym> optimization.</link>
Changing the value of only
one column covered by one index during an <command>UPDATE</command>
<emphasis>always</emphasis> necessitates a new set of index tuples
&mdash; one for <emphasis>each and every</emphasis> index on the
Expand Down
2 changes: 1 addition & 1 deletion doc/src/sgml/catalogs.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -4326,7 +4326,7 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
<para>
If true, queries must not use the index until the <structfield>xmin</structfield>
of this <structname>pg_index</structname> row is below their <symbol>TransactionXmin</symbol>
event horizon, because the table may contain broken HOT chains with
event horizon, because the table may contain broken <link linkend="storage-hot">HOT chains</link> with
incompatible rows that they can see
</para></entry>
</row>
Expand Down
Loading
Loading