Skip to content

Conversation

@pyramation
Copy link
Collaborator

@pyramation pyramation commented Jan 1, 2026

feat(pgsql-types): add package for narrowed PostgreSQL AST types

Summary

This PR adds a new pgsql-types package that generates narrowed TypeScript type definitions for PostgreSQL AST Node fields. Instead of using the generic Node union type (~250 types), fields are now typed with specific unions based on what actually appears in practice.

For example, DefElem.arg changes from:

// @pgsql/types
arg?: Node;

to:

// pgsql-types
arg?: { A_Const: A_Const }
    | { A_Star: A_Star }
    | { Boolean: Boolean }
    | { Float: Float }
    | { Integer: Integer }
    | { List: List }
    | { String: String }
    | { TypeName: TypeName }
    | { VariableSetStmt: VariableSetStmt };

The package includes:

  • Inference script (scripts/infer-field-metadata.ts): Parses 496 SQL fixture files (67,572 statements) to discover which node types appear in each Node-typed field
  • Type generation script (scripts/generate-types.ts): Generates 277 narrowed type aliases and interfaces
  • Generated output: field-metadata.json (metadata) and types.ts (TypeScript definitions)
  • README: Documentation with badges, experimental warning, and usage examples

Addresses: constructive-io/libpg-query-node#143

Updates since last revision

  • Fixed TypeScript compilation: Added proper enum imports from @pgsql/enums to resolve missing type errors
  • Cleaner API surface: Type aliases are now internal (not exported), so consumers only see clean interfaces like @pgsql/types - no CreateStmt_tableElts noise in autocomplete
  • Added README: Includes badges, experimental warning pointing to @pgsql/types for production, and DefElem usage example

Review & Testing Checklist for Human

  • Verify narrowed types in interfaces: Check that DefElem interface in src/types.ts shows the narrowed union inline (not referencing an exported type alias)
  • Confirm clean API surface: Run npm pack --dry-run or check the exports - only interfaces and enums should be exported, not the internal NodeName_fieldName type aliases
  • Test full build: Run cd packages/pgsql-types && npm run build to verify the complete pipeline (infer → clean → tsc → copy)
  • Review README: Verify the experimental warning and DefElem example look correct

Recommended test plan:

  1. Run cd packages/pgsql-types && npm run infer && npm run generate
  2. Verify src/types.ts compiles: npx tsc --noEmit
  3. Check that type aliases in types.ts use type (not export type)
  4. Spot-check the DefElem interface matches the README example

Notes

  • The type aliases are internal but will still appear in .d.ts output (TypeScript includes them so exported interfaces can reference them) - this is expected
  • The scripts use relative imports to ../../utils/src/runtime-schema - this works but is fragile
  • 1,536 statements failed to parse (2.2%) - these are likely invalid/partial SQL in fixtures, which is expected
  • The narrowed types are based on fixtures, so rare-but-valid node types may be missing

Link to Devin run: https://app.devin.ai/sessions/db627c3d06d741d7b2ece147ce39f0d3
Requested by: Dan Lynch ([email protected]) / @pyramation

This package generates narrowed TypeScript type definitions for PostgreSQL
AST Node fields by parsing SQL fixtures and inferring which specific node
types actually appear in each Node-typed field.

Features:
- Inference script that parses all SQL fixtures from kitchen-sink and postgres directories
- Generates field-metadata.json with inferred type information
- Generates narrowed TypeScript types with wrapped unions like { Integer: Integer } | { Float: Float }
- Type aliases for each Node-typed field to avoid bloating interfaces

Example: DefElem.arg is now typed as DefElem_arg which is a union of
{ A_Const: A_Const } | { Boolean: Boolean } | { Float: Float } | { Integer: Integer } | ...
instead of the generic Node type.

Addresses: constructive-io/libpg-query-node#143
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@pyramation pyramation merged commit 3b1ac1f into main Jan 1, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants