Use pg_current_xact_id() instead of deprecated txid_current()

First seen: 2026-02-08 09:14:37+00:00 · Messages: 13 · Participants: 4

Latest Update

2026-06-04 · claude-opus-4-6

Incremental Update: v6 Patch and Ready for Committer Status

This round contains no new technical substance. The only changes are:

  1. OID renumbering (v6): Shinya Kato moved the catalog OIDs for the new xid8 operators into the 8000–9999 range, which is the conventional range for in-development patches per bki.sgml. This is a cosmetic/procedural fix — committers renumber OIDs at commit time regardless.

  2. Status change: Teletele confirmed v6 is identical to v5 aside from the OID renumbering and marked the patch Ready for Committer.

No new technical arguments, no design changes, no new correctness issues, and no position shifts. The patch now awaits committer pickup.

History (2 prior analyses)
2026-06-01 · claude-opus-4-6

Monthly Summary: Replace txid_current() with pg_current_xact_id() — May 2026

Overview

This thread addresses replacing deprecated txid_current() calls in PostgreSQL's own test suite with the modern pg_current_xact_id(). What began as a simple cleanup exposed a deeper architectural gap: the xid8 return type of the new function lacks arithmetic operators, making direct migration impossible without ugly cast workarounds.

Key Developments

The Core Problem

Several test cases perform arithmetic on transaction IDs (e.g., txid_current() + 1 to fabricate future XIDs for visibility testing). Since pg_current_xact_id() returns xid8 rather than bigint, and xid8 has no arithmetic operators, a naive replacement forces expressions like pg_current_xact_id()::text::bigint + 1 — which Tom Lane rejected as "not an improvement."

v2 Approach: Define xid8 Arithmetic Operators

The accepted direction (shaped by Tom Lane's feedback) is a two-patch set:

Patch 0001 adds four operators:

Expression Return Type Semantics
xid8 + int8 → xid8 xid8 Advance XID by N
int8 + xid8 → xid8 xid8 Commutative addition
xid8 - int8 → xid8 xid8 Retreat XID by N
xid8 - xid8 → int8 int8 Distance between two XIDs

This avoids introducing unsigned integer types (which would cause ambiguous operator resolution) and is safe because no implicit casts exist between xid8 and numeric types.

Patch 0002 performs the actual test migration, now clean and readable: pg_current_xact_id() + 1.

May Activity

The month saw no substantive technical discussion. Shinya Kato posted a rebase (2026-05-25) to keep the patches applying cleanly against HEAD. No committer review of v2, no new feedback, and no position changes occurred.

Status

The patches are rebased and awaiting review. Key open questions remain:

  • C implementation quality (overflow handling, wraparound semantics)
  • Catalog entries for new operators
  • Whether additional operators (comparison, etc.) should be bundled
  • Regression test coverage for the operators themselves

Tom Lane's feedback shaped the v2 direction but he has not explicitly endorsed the implementation.


2026-06-01 · claude-opus-4-6

Substantive Progress: First External Code Review and v5 Patch

The thread received its first detailed code review from a new participant (Teletele), focusing on the C implementation of the xid8 arithmetic operators in v4-0001. This produced concrete improvements in v5.

Key Technical Issues Raised and Resolved

1. Overflow detection idiom (xid8pl/xid8mi)

The reviewer identified that the hand-rolled overflow detection in xid8pl (mixed-sign addition with manual sign-aware comparison) was correct but non-idiomatic. PostgreSQL already provides pg_add_u64_overflow / pg_sub_u64_overflow / pg_abs_s64 in common/int.h. Using these helpers:

  • Aligns with standard PG overflow-check patterns used elsewhere in the tree
  • Correctly handles INT64_MIN as a delta (since pg_abs_s64 returns 2^63 without invoking undefined behavior)
  • Makes the correctness more immediately apparent to reviewers

2. Undefined behavior in xid8_mi_xid8 at INT64_MIN boundary

The most significant correctness issue: when val2 - val1 == 2^63 (e.g., '0'::xid8 - '9223372036854775808'::xid8), the original code performed:

  • (int64)(val2 - val1) — implementation-defined since 2^63 doesn't fit in int64
  • -(INT64_MIN) — signed integer overflow, which is UB in C

The fix explicitly checks for the boundary case and returns PG_INT64_MIN directly, avoiding both the UB and the implementation-defined cast while producing the same observable result on two's-complement targets.

3. Missing negative-boundary test coverage

Tests were added for:

  • '0'::xid8 - '9223372036854775808'::xid8 (INT64_MIN boundary for xid8-xid8)
  • '0'::xid8 - '9223372036854775809'::xid8 (overflow error case)
  • '0'::xid8 + 9223372036854775807::bigint (INT64_MAX delta)
  • '0'::xid8 - (-9223372036854775807 - 1)::bigint (INT64_MIN delta)
  • '9223372036854775807'::xid8 - (-9223372036854775807 - 1)::bigint

4. Documentation added

v5-0001 now includes documentation in doc/src/sgml/datatype.sgml for the four new operators, modeled on the existing pg_lsn arithmetic operator documentation. This addresses a gap where user-visible operators were being added without corresponding docs.

Deferred: BRIN opclass for xid8

The reviewer noted that xid8 (being strictly monotonic and never wrapping) is a natural fit for BRIN minmax indexes, but both parties agreed this should be a separate thread to avoid scope creep.