feat(plugin-mssql): browse SQL Server alias, table and CLR types - #2856
Conversation
…e the routine list Claude-Session: https://claude.ai/code/session_016PSQC4EGqkpq32cWdPVMBJ
… rebuilt type Claude-Session: https://claude.ai/code/session_016PSQC4EGqkpq32cWdPVMBJ
Review round: 7 findings, all real, all fixedA second model (Codex) reviewed the branch. Every finding held up when measured against SQL Server 2022, so all seven are fixed in One broke the test suite. Six were wrong DDL, each verified against a fixture built to exercise it:
Memory-optimized table types now keep Index keys are read as structured rows instead of a Round-trip proofThe rebuilt statement was executed and the resulting type compared against the original in the catalog: Before this round the same type would have come back with a bare column type, a clustered key, an ascending index and no CHECK.
|
Signed-off-by: Ngô Quốc Đạt <datlechin@gmail.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
Stacked on #2855, which fixes the session that made SQL Server's Procedures and Functions lists empty. This adds the third thing the same user asked for: Types.
Until now
fetchUserDefinedTypeshad exactly one implementation, PostgreSQL's, andsupportsUserDefinedTypeBrowsewas true for PostgreSQL and PGlite alone. SQL Server has three shapes of user-defined type and browsed none of them.What SQL Server has, and why the existing kinds did not fit
CREATE TYPE x FROM nvarchar(320) NOT NULLdomainCREATE TYPE x AS TABLE (...)compositeCREATE TYPE x EXTERNAL NAME asm.ClassThe shapes of the first two do line up, but the words do not: a SQL Server reader has never met a domain or a composite, and labelling their types with PostgreSQL's vocabulary would be wrong on screen rather than merely imprecise.
PluginUserDefinedTypeKindgainsaliasType,tableTypeandclrType.That enum is not
@frozenandPluginObjectMappingalready carries@unknown default, which is the growth path CLAUDE.md prescribes for a vocabulary like this (the same onePluginCapabilityuses). So the change is additive:currentPluginKitVersion30 to 31 and the 40 pluginInfo.plists,minimumCompatiblePluginKitVersionleft at 19, norelease-all-plugins.sh.An earlier draft replaced the enum with a string-backed struct beside a retained legacy enum, on the argument that a closed enum forces a kit bump per engine. The review pass pushed back with the CLAUDE.md rule above and was right: the parallel vocabulary was more machinery for no benefit the
@unknown defaultpath does not already give.Reading a definition
A SQL Server type has no
sys.sql_modulesrow of any kind, so unlike a procedure there is no stored text to read back. Every statement is synthesized:ANSI_NULL_DFLT_ONand a reader cannot tell which applied.PK__TT_IdLis__3214EC07...) and is deliberately dropped.Both synthesized shapes were executed against SQL Server 2022 and accepted before the Swift was written, so the builder is a transcription of statements known to parse.
The
max_lengthtraps are handled and measured: it is in bytes, sonvarchar(320)reports 640 and is halved, and -1 means MAX.Two defects the review caught before they shipped
A table type would have been offered as a column type.
UserDefinedTypeSuggestions.entrieshad no kind filter, so once the driver returned table types the column picker would list them and SQL Server would reject every resultingALTER TABLE. A table type is a table-valued parameter and nothing else. It is filtered out, and the driver gives it nocolumnTypeSpellingat all so nothing downstream can offer it either.The adapter never backfilled a type's schema.
fetchRoutinesadopts the resolved schema onto every routine;fetchUserDefinedTypesdid not, so a driver that left it nil produced types with a bare qualified name. Unreachable while PostgreSQL was the only implementation, and reachable the moment a second one landed. Fixed once in the adapter rather than worked around per driver.Presentation
One flat Types section beside Procedures, Functions and Triggers, with the kind in the row's detail. No nested tree: SSMS buries a table type four levels deep under Programmability, which breaks the HIG's two-level sidebar guidance, and TablePro's flat sections are already the better shape. TablePlus has no Types section for any engine, so there was nothing to match.
All three kinds open the existing read-only source tab. An earlier draft had table types open a Structure grid of their columns; the review pass showed that meant a new
TableTypecase on a closed enum plus editing machinery (StructureChangeManageremitsALTER TABLE, which is invalid for a type) for a read-only view, so they use the tab every other type kind already uses, carrying the synthesized statement.Verification
verify.sh build: PASSverify.sh test MSSQLTypeQueryTests MSSQLTypeDefinitionTests MSSQLObjectQueryTests: PASS, 25 of 25xcodebuild -scheme MSSQLDriver: BUILD SUCCEEDED, 0 errors. Run directly because MSSQL is registry-only, so PR CI never compiles it, and theAllPluginsaggregate cannot run on this machine: it fails in the vendoredoracle-niowithunknown attribute 'usableFromInlinenonisolated'from a@TaskLocalmacro expansion, which is a toolchain bug seen on unrelated branches and is not touched by this change.docs/scripts/check-writing-style.shandcheck-docs-against-source.py: PASS. The second earned its keep: the kit bump silently falsified three version claims inplugin-development.mdxandplugin-registry.mdx, which are fixed here.swiftlint --stricton all 9 changed Swift files: clean.Measured through the real driver
The plugin's own sources were compiled with
swiftcagainst the builtTableProPluginKit.frameworkand run against SQL Server 2022, so this isMSSQLPluginDriveritself and not the query strings:That matches the fixture's original
CREATE TYPEstatement, including the collation onNoteand its absence onSku, whose collation equals the database's.No UI automation: the Types section needs a live SQL Server, which
TableProUITestshas no deterministic access to.https://claude.ai/code/session_016PSQC4EGqkpq32cWdPVMBJ