Skip to content

M7: SQL Server introspection (describe machinery)#7

Merged
lgamorim merged 6 commits into
masterfrom
feature/M7-sqlserver-introspection
Jul 11, 2026
Merged

M7: SQL Server introspection (describe machinery)#7
lgamorim merged 6 commits into
masterfrom
feature/M7-sqlserver-introspection

Conversation

@lgamorim

Copy link
Copy Markdown
Owner

Opens Phase 3 (0.3.0-preview.1) with the pilot provider's describe machinery — the prepare-step primitive that ADR 0001 reserves the database round-trip for.

What's here

  • SqlBound.SqlServer (new package): SqlServerQueryDescriber.DescribeAsync(SqlConnection, commandText) wraps sp_describe_first_result_set and sp_describe_undeclared_parameters, returning a QueryDescription:
    • Columns: zero-based ordinal (matching DbDataReader), name (empty for unnamed expressions), reported SQL type, mapped C# type text, nullability. No-result-set statements describe as zero columns — exactly what [SqlExecute] verification expects.
    • Parameters: @name placeholders with SQL Server's suggested types, names stripped of @ to compare against C# method parameters.
  • SqlServerTypeMap: SQL type names → exactly the generator's supported getter vocabulary (int, string, decimal, global::System.Guid, byte[], …). Types outside it (datetimeoffset, time, xml, sql_variant, spatial, UDTs) fail describe with SqlBoundDescribeException rather than promising a materialization the generated code cannot perform.
  • Error surface: syntax errors, missing objects, temp tables, and ambiguous parameter usage rethrow as SqlBoundDescribeException carrying the server's message and the offending command text — one exception type for the prepare step to report per failing query.
  • docs/introspection.md: mechanism plus the inherent sp_describe_* limits found while testing.

Testing

  • 42 unit tests cover the type map exhaustively.
  • 19 integration tests run the describer against a real SQL Server 2022 via Testcontainers — full type-map round-trip through a real table, nullability, unnamed/hidden columns, parameter inference, all failure paths, cancellation. Without Docker they skip locally with an explanatory message but fail hard in CI, so CI cannot silently lose the suite.
  • TDD red→green per commit; solution-wide: 154 tests green, zero warnings, all five packages pack at 0.3.0-preview.1.

Noted for M8

SQL Server's suggested parameter types are inferences, not column lookups (Price > @minPrice against decimal(18,2) suggests decimal(38,19)), so M8 must compare mapped CLR types, not raw SQL type names.

🤖 Generated with Claude Code

lgamorim and others added 6 commits July 11, 2026 19:35
Bump PackageVersion to 0.3.0-preview.1 (Phase 3 owns 0.3.x) and add the
pilot provider project plus its unit and integration test projects, so
M7's introspection work lands in the package layout planned for it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SqlServerTypeMap converts sp_describe_* system type names to the exact
C# type text the generator's getter set supports, so the describer and
the codegen agree on one type vocabulary. Types without a supported
getter (datetimeoffset, time, xml, sql_variant, spatial) map to nothing
by design - they must fail describe loudly rather than promise a
materialization the generated code cannot perform.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SqlServerQueryDescriber wraps sp_describe_first_result_set: it returns
each visible column's name, zero-based ordinal, reported SQL type,
mapped C# type text, and nullability, and throws SqlBoundDescribeException
when a column's type has no generator-supported mapping. This is the
prepare-step primitive ADR 0001 reserves the database round-trip for.

Integration tests run against a real SQL Server via Testcontainers,
skipping locally without Docker but failing hard in CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
DescribeAsync now also wraps sp_describe_undeclared_parameters,
returning each placeholder's name (stripped of '@' to match the C#
parameter it binds to) with SQL Server's suggested type mapped through
the same type vocabulary; unsupported suggestions throw. Suggested
types are inferences from the expression context, not column lookups -
a comparison against decimal(18,2) suggests the widened decimal(38,19).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Syntax errors, missing objects, temp tables, and ambiguous parameter
usage all raise provider SqlExceptions from the sp_describe_* calls;
DescribeAsync now rethrows them as SqlBoundDescribeException carrying
the server's message and the offending command text, giving the
prepare step one exception type to report per failing query.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Record how the describer maps sp_describe_* output, which failures are
inherent SQL Server limits (temp tables, ambiguous parameters, widened
suggested types, unsupported type set), and how the Testcontainers
suite behaves with and without Docker.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lgamorim lgamorim merged commit 4a24a95 into master Jul 11, 2026
4 checks passed
@lgamorim lgamorim deleted the feature/M7-sqlserver-introspection branch July 11, 2026 20:15
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.

1 participant