@yawlabs/postgres-mcp 0.6.10 → 0.6.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,54 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ## [0.6.10] - 2026-05-16
11
-
12
- ### Infrastructure
13
- - Republishes the 0.6.7-0.6.9 coverage additions, which never reached
14
- npm. The `pg_top_queries orderBy=calls` numeric-vs-lexical ordering
15
- test was removed after three round-trips trying to make it
16
- environment-independent. pg_stat_statements on PG17/18 fingerprints
17
- `SELECT 1 AS x_a` and `SELECT 2 AS x_b` to the same query id (column
18
- aliases drop out of the jumble even though they're preserved in the
19
- displayed text), so two markers with different aliases collapse to
20
- one entry and the ordering assertion has nothing to compare. Local
21
- WSL clusters differentiate; CI doesn't. The alias-shadowing trap at
22
- `stats.ts:60-67` remains documented at the call site and the other
23
- six coverage additions are unaffected.
24
-
25
- ## [0.6.9] - 2026-05-16 [UNPUBLISHED]
26
-
27
- Tagged but never published to npm -- the pg_top_queries ordering test
28
- still failed in CI even after switching marker queries from cursor-
29
- wrapped handler calls to raw `runInternal`. Root cause was column-alias
30
- jumbling in pg_stat_statements; the test was removed in 0.6.10.
10
+ ## [0.6.12] - 2026-05-16
31
11
 
32
- ## [0.6.8] - 2026-05-16 [UNPUBLISHED]
33
-
34
- Tagged but never published to npm -- the v0.6.8 attempt at the
35
- pg_top_queries test still depended on `pg_stat_statements.track_utility`
36
- being on, which the CI image's defaults don't guarantee. Shipped in 0.6.9.
37
-
38
- ## [0.6.7] - 2026-05-16 [UNPUBLISHED]
12
+ ### Fixed
13
+ - `pg_inspect_locks` now resolves `relation` for the common case of row-level
14
+ contention. Previously, `SELECT FOR UPDATE` + `UPDATE` row-level waits
15
+ queued on a `transactionid` lock with `pg_locks.relation = NULL`, so the
16
+ handler returned `relation: null` and gave the agent no hint as to which
17
+ table was contested. A fallback subquery now resolves the contested table
18
+ from the blocker's held write-intent relation locks (RowShareLock,
19
+ RowExclusiveLock, etc.), filtering out plain SELECT's AccessShareLock so
20
+ unrelated tables the blocker only read from don't show up. Closes #5.
39
21
 
40
- Tagged but never published to npm -- the initial coverage additions
41
- included an ordering test for pg_top_queries that failed in CI on a
42
- test-stability issue (not a code issue). The other six coverage
43
- additions shipped in 0.6.10.
22
+ ## [0.6.11] - 2026-05-16
44
23
 
24
+ ### Infrastructure
25
+ - Tightened the `pg_inspect_locks` real-contention test: replaced the
26
+ 500ms hardcoded sleep with a 5s polling loop on `pg_blocking_pids()`
27
+ (avoids flakes on slow CI hosts and wasted time on fast ones), and
28
+ moved the `waiterPromise` await into the `finally` block so an
29
+ assertion failure mid-test still drains the queued waiter query
30
+ rather than leaving a floating promise.
45
31
 
32
+ ## [0.6.10] - 2026-05-16
46
33
 
47
34
  ### Infrastructure
48
- - Closed seven coverage gaps surfaced by a coverage audit. No behavior
35
+ - Closed six coverage gaps surfaced by a coverage audit. No behavior
49
36
  changes; each test pins a branch the existing suite exercised on only
50
37
  one side, or a structural property a regression could silently violate:
51
38
  - `pg_inspect_locks` real ACCESS EXCLUSIVE contention with two side
52
39
  clients. Covers the LATERAL `unnest(pg_blocking_pids(...))` and the
53
40
  per-(blocked, blocker) row shape the v0.6.6 description claims.
54
- - `pg_top_queries` `orderBy: 'calls'` numeric (not lexical) ordering.
55
- A 12-call query must rank above a 2-call query -- pins the
56
- alias-shadowing fix where unqualified `calls` would resolve to the
57
- text output alias and sort lexically (`"2" > "12"`).
58
41
  - `pg_table_bloat` `minDeadRatio` threshold filter, as a relative
59
42
  property (filtered rows are at or above the threshold; baseline rows
60
43
  below the threshold are absent from filtered). Order-independent.
package/dist/index.js CHANGED
@@ -36391,7 +36391,35 @@ var adminTools = [
36391
36391
  FROM pg_catalog.pg_class c
36392
36392
  JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
36393
36393
  WHERE c.oid = bl.relation)
36394
- ELSE NULL
36394
+ ELSE (
36395
+ -- transactionid / virtualxid waits have bl.relation = NULL
36396
+ -- because the wait is on the blocker's xid, not on a relation.
36397
+ -- The contested table is usually identifiable from the
36398
+ -- blocker's held write-intent locks: SELECT FOR UPDATE takes
36399
+ -- RowShareLock, UPDATE/INSERT/DELETE take RowExclusiveLock,
36400
+ -- migrations take stronger modes. Filter out the AccessShare
36401
+ -- locks (plain SELECT) the blocker also holds on every table
36402
+ -- they read from -- those aren't the contention source. If
36403
+ -- the blocker has touched multiple write-intent tables in
36404
+ -- their transaction, this is a best-effort hint, not a
36405
+ -- definitive answer; the blocked/blocking queries above let
36406
+ -- the caller disambiguate.
36407
+ SELECT n.nspname || '.' || c.relname
36408
+ FROM pg_catalog.pg_locks blocker_locks
36409
+ JOIN pg_catalog.pg_class c ON c.oid = blocker_locks.relation
36410
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
36411
+ WHERE blocker_locks.pid = blocking.pid
36412
+ AND blocker_locks.locktype = 'relation'
36413
+ AND blocker_locks.granted
36414
+ AND blocker_locks.mode IN (
36415
+ 'RowShareLock', 'RowExclusiveLock', 'ShareLock',
36416
+ 'ShareRowExclusiveLock', 'ShareUpdateExclusiveLock',
36417
+ 'ExclusiveLock', 'AccessExclusiveLock'
36418
+ )
36419
+ AND n.nspname NOT IN ('pg_catalog', 'information_schema')
36420
+ ORDER BY n.nspname, c.relname
36421
+ LIMIT 1
36422
+ )
36395
36423
  END AS relation,
36396
36424
  bl.locktype AS lock_type
36397
36425
  FROM pg_catalog.pg_locks bl
@@ -37550,7 +37578,7 @@ function compareVersions(a, b) {
37550
37578
  }
37551
37579
 
37552
37580
  // src/index.ts
37553
- var version2 = true ? "0.6.10" : (await null).createRequire(import.meta.url)("../package.json").version;
37581
+ var version2 = true ? "0.6.12" : (await null).createRequire(import.meta.url)("../package.json").version;
37554
37582
  var subcommand = process.argv[2];
37555
37583
  if (subcommand === "version" || subcommand === "--version") {
37556
37584
  console.log(version2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yawlabs/postgres-mcp",
3
- "version": "0.6.10",
3
+ "version": "0.6.12",
4
4
  "mcpName": "io.github.YawLabs/postgres-mcp",
5
5
  "description": "PostgreSQL MCP server - query, schema introspection, explain, and health checks for AI assistants",
6
6
  "license": "MIT",