Skip to content

TML-3228: register the SQL built-in attribute specs and source every interpreter call site from the namespace - #30159

Open
StevenMcClankerton wants to merge 8 commits into
mainfrom
tml-3228-sql-attributes-registered
Open

TML-3228: register the SQL built-in attribute specs and source every interpreter call site from the namespace#30159
StevenMcClankerton wants to merge 8 commits into
mainfrom
tml-3228-sql-attributes-registered

Conversation

@StevenMcClankerton

@StevenMcClankerton StevenMcClankerton commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Slice 2 of the attribute-registry project (parent TML-3226; builds on TML-3227, #30154). The SQL family now registers its whole built-in attribute surface once, and every consumer — the four interpreter files, the two unknown-attribute checks, and the language server — reads that one registration.

What changed

One namespace, one export. @internal/sql-contract-psl gains sqlAttributeSpecs (as const satisfies AttributeSpecNamespace): eight model factories (map id unique index check control discriminator base) and six field factories (map id unique noCheck relation default), exposed through a new @internal/sql-contract-psl/attribute-specs entry. The @relation spec moved from psl-relation-resolution.ts into the namespace's module so the namespace never imports from a consumer. The individual spec constants and the two @default builders are no longer exported — a spec is reachable only through the namespace.

@default is one factory over the uniform ctx. It reads the field's list-ness and the default-function registry from the ctx, and resolves an enum-typed field's member names from the symbol table (topLevel.blocks or the field's namespace scope), replacing the interpreter-side buildDefaultSpec / buildEnumDefaultSpec split. Both grammars key their positional as value, so the factory has a single return type; the enum lowering narrows on typeof value === 'string'. A memberless enum yields a grammar that rejects every argument.

Call sites source from the namespace. interpreter.ts, psl-field-resolution.ts, psl-column-resolution.ts, psl-relation-resolution.ts read sqlAttributeSpecs.<level>.<name>(…); symbolTable is threaded to the two @default lowering sites (the only factory that consumes ctx). InferAttr typing at every call site is unchanged and no cast was added or removed.

The family registers it. @internal/family-sql depends on @internal/sql-contract-psl (moved from dev to prod — family is the last layer in the SQL layer order) and declares authoring.attributeSpecs on both its pack ref and its control descriptor. The public @prisma/orm-family-sql export map gained the matching entry from the build's public-surface sync.

Unknown-attribute diagnostics derive from the registry. The hand-maintained BUILTIN_FIELD_ATTRIBUTE_NAMES set is gone; the field-level check is Object.hasOwn(sqlAttributeSpecs.field, name). The model-attribute loop checks Object.hasOwn(sqlAttributeSpecs.model, name) (or an ADR 236 contribution) before dispatching; the former fall-through diagnostic became an InternalError, since a registered name without an interpreter branch is a programming error. Messages and codes are untouched.

LSP proof in final form. The in-package language-server test enumerates a synthetic family field factory through resolveConfigInputs; the integration test enumerates the real postgres project's full model/field key sets and @relation's named arguments. Both go red if the family stops registering.

Why

The project's premise is that the editor can never fall out of step with what the interpreters accept. That only holds when the interpreter and the LSP read the same object — so the namespace is a module constant the interpreter consumes directly (total, InferAttr-typed access) and the LSP reads through assembleAttributeSpecs. Deriving the unknown-name checks from the same keys closes the last place a second list could drift.

Scope

In: the SQL family only (sql-contract-psl, family-sql, tests in language-server and test/integration). Out: Mongo (TML-3229), block-level attributes (TML-3230), any LSP production change, the registry ADR (project close-out).

Decisions taken on the registry-core open items: resolveConfigInputs stays a deep import (no new import site appeared); the ?? new Map() mutation-default fallback stays (the factory receives exactly the registry the old builder did); wrong-level registration is guarded by a test that invokes every factory and asserts spec.level / spec.name match its subkey.

Verification

pnpm --filter @internal/sql-contract-psl test (451), pnpm --filter @internal/language-server test (295), the integration test file (4), pnpm typecheck, pnpm lint:deps, pnpm fixtures:check (byte-clean), pnpm build, pnpm test:packages. Grep gate: rg "ModelSpec\b|FieldSpec\b|buildDefaultSpec|buildEnumDefaultSpec" packages/2-sql/2-authoring/contract-psl/src --glob '!sql-attribute-specs.ts' → empty. No comment lines added to .ts files.

Refs: TML-3228

🤖 Generated with Claude Code

https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA

Summary by CodeRabbit

  • New Features

    • Added a public SQL attribute-specification surface for model and field attributes.
    • Added support for enumerating built-in attributes and inspecting @relation arguments.
    • Improved validation for defaults, enum values, and unknown attributes.
    • Exposed SQL attribute specifications through SQL family and public package exports.
  • Tests

    • Added coverage for attribute registration, consumability, relation metadata, defaults, and diagnostic behavior.

SevInf and others added 7 commits August 28, 2026 15:17
…lan, trace)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA
Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
…mespace

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA
Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
…pace

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA
Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
…e it reaches the LSP

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA
Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
…L namespace

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA
Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
…ackage

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA
Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
…roject trace

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA
Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
@StevenMcClankerton
StevenMcClankerton requested a review from a team as a code owner August 28, 2026 16:03
@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 108c27f1-af9c-4263-9384-d4ee868707ff

📥 Commits

Reviewing files that changed from the base of the PR and between 750feea and 6fe720b.

📒 Files selected for processing (3)
  • packages/2-sql/2-authoring/contract-psl/src/psl-field-resolution.ts
  • packages/2-sql/2-authoring/contract-psl/test/interpreter.defaults.test.ts
  • packages/2-sql/2-authoring/contract-psl/test/interpreter.unknown-attributes.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

The SQL authoring package now exposes centralized model and field attribute specifications. Default and relation parsing use symbol-aware factories. SQL family descriptors publish the namespace, and tests cover registration, interpretation, diagnostics, and language-server consumability.

Changes

SQL attribute specification surface

Layer / File(s) Summary
Centralized SQL attribute namespace
packages/2-sql/2-authoring/contract-psl/src/sql-attribute-specs.ts
Groups SQL model and field factories under sqlAttributeSpecs. Adds symbol-aware default and relation specifications.
Interpreter and field resolution integration
packages/2-sql/2-authoring/contract-psl/src/interpreter.ts, packages/2-sql/2-authoring/contract-psl/src/psl-column-resolution.ts, packages/2-sql/2-authoring/contract-psl/src/psl-field-resolution.ts, packages/2-sql/2-authoring/contract-psl/src/psl-relation-resolution.ts
Updates attribute interpretation, validation, default lowering, relation parsing, and symbol-table propagation to use the centralized specifications.
Package exports and SQL family wiring
packages/2-sql/2-authoring/contract-psl/src/exports/attribute-specs.ts, packages/2-sql/2-authoring/contract-psl/package.json, packages/2-sql/2-authoring/contract-psl/tsdown.config.ts, packages/2-sql/9-family/package.json, packages/2-sql/9-family/src/core/control-descriptor.ts, packages/2-sql/9-family/src/exports/pack.ts, packages/9-public/@prisma/orm-family-sql/package.json
Builds and exports the attribute-spec module. Adds the namespace to SQL family authoring descriptors and public package exports.
Consumability validation
packages/2-sql/2-authoring/contract-psl/test/*, packages/1-framework/3-tooling/language-server/test/attribute-spec-consumability.test.ts, test/integration/test/authoring/attribute-specs.lsp-consumability.test.ts
Tests registered surfaces, default values, relation arguments, unknown attributes, contributed field specifications, and SQL-family integration.

Estimated code review effort: 4 (Complex) | ~45 minutes

Merge Risk: ⚪ Minimal · up to 6fe72

The PR centralizes SQL attribute specifications and updates consumers to use the shared namespace without any supplied current-head merge-blocking concern. No actionable risk remains beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant PSLInterpreter
  participant sqlAttributeSpecs
  participant sqlFamilyPack
  participant LSPConsumabilityTest
  PSLInterpreter->>sqlAttributeSpecs: resolve model and field attribute factories
  sqlFamilyPack->>sqlAttributeSpecs: publish authoring.attributeSpecs
  LSPConsumabilityTest->>sqlFamilyPack: enumerate SQL attributes
  LSPConsumabilityTest->>sqlAttributeSpecs: invoke relation and contributed field factories
Loading

Suggested reviewers: aqrln

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.90% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 29 functions across 14 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: registering SQL built-in attribute specifications and sourcing interpreter call sites from the shared namespace.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tml-3228-sql-attributes-registered

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Aug 28, 2026

Copy link
Copy Markdown

Open in StackBlitz

@prisma/orm-extension-arktype-json

npm i https://pkg.pr.new/@prisma/orm-extension-arktype-json@30159

@prisma/orm-extension-middleware-cache

npm i https://pkg.pr.new/@prisma/orm-extension-middleware-cache@30159

@prisma/orm-extension-paradedb

npm i https://pkg.pr.new/@prisma/orm-extension-paradedb@30159

@prisma/orm-extension-pgvector

npm i https://pkg.pr.new/@prisma/orm-extension-pgvector@30159

@prisma/orm-extension-postgis

npm i https://pkg.pr.new/@prisma/orm-extension-postgis@30159

@prisma/orm-extension-supabase

npm i https://pkg.pr.new/@prisma/orm-extension-supabase@30159

@prisma/orm-family-mongo

npm i https://pkg.pr.new/@prisma/orm-family-mongo@30159

@prisma/orm-family-sql

npm i https://pkg.pr.new/@prisma/orm-family-sql@30159

@prisma/orm-framework

npm i https://pkg.pr.new/@prisma/orm-framework@30159

@prisma/orm-mongo

npm i https://pkg.pr.new/@prisma/orm-mongo@30159

@prisma/orm-postgres

npm i https://pkg.pr.new/@prisma/orm-postgres@30159

@prisma/orm-sqlite

npm i https://pkg.pr.new/@prisma/orm-sqlite@30159

@prisma/orm-target-mongo

npm i https://pkg.pr.new/@prisma/orm-target-mongo@30159

@prisma/orm-target-postgres

npm i https://pkg.pr.new/@prisma/orm-target-postgres@30159

@prisma/orm-target-sqlite

npm i https://pkg.pr.new/@prisma/orm-target-sqlite@30159

@prisma/orm-toolchain

npm i https://pkg.pr.new/@prisma/orm-toolchain@30159

commit: 6fe720b

@github-actions

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
postgres / no-emit 180.28 KB (+3.09% 🔺)
postgres / emit 152.03 KB (-0.01% 🔽)
mongo / no-emit 101.09 KB (0%)
mongo / emit 90.95 KB (0%)
cf-worker / no-emit 204.72 KB (+3% 🔺)
cf-worker / emit 173.31 KB (-0.01% 🔽)

…cceptance test

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LdeyeSGNsLAJiyKfntYnaA
Signed-off-by: Steven McClankerton <tatarintsev@prisma.io>
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