schemainspect: constraints.sql only skips pg_temp_1, so another session's temp table crashes load_all_relations
Nobody has claimed this yet.
Assessment
- Difficulty
- 1/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- postgresql, typescript
- Domain
- databases
Research direction
Start with queries/pg/sql/constraints.sql at line 147 and compare its temp-schema filtering with queries/pg/sql/relations.sql and the indexes CTE. Reproduce with a temp table containing a constraint in one session, then run Migration.create from another; done means inspection completes without loading unrelated temporary-table constraints.
Written by the indexing model from the issue text.
Description
Summary
Migration.create (and any get_inspector call) throws
TypeError: Cannot read properties of undefined (reading 'constraints')
at PostgreSQL.load_all_relations (@pgkit/schemainspect/0.6.1/dist/pg/obj.js:1321)
at async PostgreSQL.load_all_async (.../pg/obj.js:961)
at async Function.create (.../pg/obj.js:944)
at async get_inspector (.../get.js:20)
at async Function.create (@pgkit/migra/0.6.1/dist/migra.js:22)
whenever any other backend on the server holds a temp table that has a
constraint (a PRIMARY KEY, UNIQUE or CHECK). It is not about the database
being inspected — one unrelated idle session is enough to make every inspection
of that server fail.
Root cause
load_all_relations does:
for (const each of Object.values(this.constraints)) {
const t = each.quoted_full_table_name;
this.relations[t].constraints[each.quoted_full_name] = each; // <-- this.relations[t] is undefined
}
The two queries that populate those maps disagree about temp schemas:
-
queries/pg/sql/relations.sqlexcludes them by pattern —
n.nspname not like 'pg_temp_%'(lines 23, 65, 107 onmain). -
queries/pg/sql/constraints.sqlexcludes only the literalpg_temp_1—
line 147 onmain:-- SKIP_INTERNAL and nspname not in ('pg_internal', 'pg_catalog', 'information_schema', 'pg_toast', 'pg_temp_1', 'pg_toast_temp_1')
pg_temp_1 is only ever the first backend's temp namespace. Any other session
gets pg_temp_2, pg_temp_75, pg_temp_156, … — all of which pass that filter.
So constraints on other sessions' temp tables are loaded, their tables are not,
and the lookup dereferences undefined.
The same file is already inconsistent with itself: the indexes CTE at line 69
does use the pattern form (schemaname not like 'pg_temp_%').
Reproduction
-- session A, and leave it open
CREATE TEMP TABLE t (id int PRIMARY KEY);
SELECT pg_sleep(600);
// session B
import { createClient } from '@pgkit/client'
import { Migration } from '@pgkit/migra'
const c = createClient(process.env.URL!)
await Migration.create(c, c, { schema: 'public' }) // throws
Terminate session A and the exact same call succeeds.
Verified against PostgreSQL 17 (Supabase), @pgkit/schemainspect 0.6.1 /
@pgkit/migra 0.6.1.
Suggested fix
Make constraints.sql line 147 use the same pattern form the other queries use:
-- SKIP_INTERNAL and nspname not in ('pg_internal', 'pg_catalog', 'information_schema', 'pg_toast')
-- SKIP_INTERNAL and nspname not like 'pg_temp_%' and nspname not like 'pg_toast_temp_%'
It may also be worth making load_all_relations tolerant of a missing relation
rather than throwing, since any future filter skew produces the same
hard-to-diagnose crash.
Why this is worth fixing even though it's a niche skew
This is the engine behind supabase db diff --use-migra. On a production
database it is normal for pooled backends to hold session-lifetime temp tables,
so the crash is permanent rather than intermittent — and the Supabase CLI
currently reports it as No schema changes found (filed separately), which
makes it read as a clean diff.
- Dominant language
- TypeScript
- Stars
- 289
- Forks
- 35
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from mmkal/pgkit
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 58/100
-
Difficulty 3/5 1-2 days Newbie friendliness 48/100
-
Difficulty 3/5 1-2 days Newbie friendliness 35/100
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100