Summary
pg-topo currently treats PostgreSQL range type creation as an unsupported statement class. This leaves downstream objects that use the range type with an unresolved type:* dependency, even though packages/pg-topo/docs/architecture.md lists types/domains/collations/sequences under implemented coverage.
This is a separate issue class from #281. #281 is about expression dependencies inside ALTER TABLE subcommands; this one is about missing statement classification/extraction for the CreateRangeStmt AST root.
Minimal repro
Input statements, intentionally shuffled:
create type app.int_range as range (subtype = int4);
create table app.bookings(
id int primary key,
span app.int_range not null
);
create schema app;
Actual result on current main
Current main: 9f01826b00b64e7f9628844ecb6f69a07f53c1f8
pg-topo ordered the table before the range type and classified the range statement as UNKNOWN:
{
"ordered": [
{
"class": "CREATE_SCHEMA",
"sql": "create schema app;"
},
{
"class": "CREATE_TABLE",
"sql": "create table app.bookings(id int primary key, span app.int_range not null);"
},
{
"class": "UNKNOWN",
"sql": "create type app.int_range as range (subtype = int4);"
}
],
"diagnostics": [
{
"code": "UNRESOLVED_DEPENDENCY",
"message": "No producer found for 'type:app:int_range:'."
},
{
"code": "UNKNOWN_STATEMENT_CLASS",
"message": "Unsupported statement AST root 'CreateRangeStmt'."
}
]
}
Runtime validation then reports the table's range type as missing:
RUNTIME_ASSUMED_EXTERNAL_DEPENDENCY: type "app.int_range" does not exist
sqlstate: 42704
missingObjectKey: type:app:int_range:
Expected result
The range type should be recognized as a supported type producer and ordered before objects that use it:
CREATE_SCHEMA
CREATE_TYPE -- create type app.int_range as range (...)
CREATE_TABLE -- span app.int_range
No UNKNOWN_STATEMENT_CLASS or UNRESOLVED_DEPENDENCY diagnostic should be emitted for the range type in this repro.
Root cause
classifyStatement does not map the parser's CreateRangeStmt AST root. extractDependenciesForStatement therefore never reaches a range-type extractor, so CREATE TYPE ... AS RANGE does not provide the type:app:int_range object that the table column requires.
Relevant code paths:
packages/pg-topo/src/classify/classify-statement.ts: CLASS_BY_AST_NODE handles CompositeTypeStmt and CreateEnumStmt as CREATE_TYPE, but not CreateRangeStmt.
packages/pg-topo/src/extract/extract-dependencies.ts: the CREATE_TYPE branch handles enum/composite-like providers through existing AST roots, but has no CreateRangeStmt extraction path.
Suggested fix direction
- Classify
CreateRangeStmt as CREATE_TYPE.
- Add extraction for
CreateRangeStmt so it provides the created range type stable ref, e.g. type:app:int_range.
- Add dependencies for:
- the containing schema;
- user-defined subtype types, when present;
- range support functions/options such as
canonical and subtype_diff, if they are schema-qualified or otherwise resolvable from the AST.
- Add focused pg-topo tests covering:
- simple
CREATE TYPE ... AS RANGE (subtype = int4) before a table column that uses it;
- a range type with support functions, if the AST exposes those options cleanly.
Local validation
I reproduced this twice with the focused local probe below. Both runs produced the same UNKNOWN_STATEMENT_CLASS / UNRESOLVED_DEPENDENCY diagnostics.
./node_modules/.bin/bun run --cwd packages/pg-topo scripts/run-tests.ts \
--test-name-pattern "CREATE TYPE AS RANGE" \
test/deep-probe.test.ts
Summary
pg-topocurrently treats PostgreSQL range type creation as an unsupported statement class. This leaves downstream objects that use the range type with an unresolvedtype:*dependency, even thoughpackages/pg-topo/docs/architecture.mdliststypes/domains/collations/sequencesunder implemented coverage.This is a separate issue class from #281. #281 is about expression dependencies inside
ALTER TABLEsubcommands; this one is about missing statement classification/extraction for theCreateRangeStmtAST root.Minimal repro
Input statements, intentionally shuffled:
Actual result on current main
Current
main:9f01826b00b64e7f9628844ecb6f69a07f53c1f8pg-topoordered the table before the range type and classified the range statement asUNKNOWN:{ "ordered": [ { "class": "CREATE_SCHEMA", "sql": "create schema app;" }, { "class": "CREATE_TABLE", "sql": "create table app.bookings(id int primary key, span app.int_range not null);" }, { "class": "UNKNOWN", "sql": "create type app.int_range as range (subtype = int4);" } ], "diagnostics": [ { "code": "UNRESOLVED_DEPENDENCY", "message": "No producer found for 'type:app:int_range:'." }, { "code": "UNKNOWN_STATEMENT_CLASS", "message": "Unsupported statement AST root 'CreateRangeStmt'." } ] }Runtime validation then reports the table's range type as missing:
Expected result
The range type should be recognized as a supported type producer and ordered before objects that use it:
No
UNKNOWN_STATEMENT_CLASSorUNRESOLVED_DEPENDENCYdiagnostic should be emitted for the range type in this repro.Root cause
classifyStatementdoes not map the parser'sCreateRangeStmtAST root.extractDependenciesForStatementtherefore never reaches a range-type extractor, soCREATE TYPE ... AS RANGEdoes not provide thetype:app:int_rangeobject that the table column requires.Relevant code paths:
packages/pg-topo/src/classify/classify-statement.ts:CLASS_BY_AST_NODEhandlesCompositeTypeStmtandCreateEnumStmtasCREATE_TYPE, but notCreateRangeStmt.packages/pg-topo/src/extract/extract-dependencies.ts: theCREATE_TYPEbranch handles enum/composite-like providers through existing AST roots, but has noCreateRangeStmtextraction path.Suggested fix direction
CreateRangeStmtasCREATE_TYPE.CreateRangeStmtso it provides the created range type stable ref, e.g.type:app:int_range.canonicalandsubtype_diff, if they are schema-qualified or otherwise resolvable from the AST.CREATE TYPE ... AS RANGE (subtype = int4)before a table column that uses it;Local validation
I reproduced this twice with the focused local probe below. Both runs produced the same
UNKNOWN_STATEMENT_CLASS/UNRESOLVED_DEPENDENCYdiagnostics../node_modules/.bin/bun run --cwd packages/pg-topo scripts/run-tests.ts \ --test-name-pattern "CREATE TYPE AS RANGE" \ test/deep-probe.test.ts