Repository navigation
feat: support multiple allowed schemas per configuration - #4
Open
jdainsworthsnb wants to merge 5 commits into
Open
jdainsworthsnb wants to merge 5 commits into
jdainsworthsnb wants to merge 5 commits into
Conversation
Covers allowedSchemas list with legacy allowedSchema fallback, case-insensitive IsSchemaAllowed over the list, and the SchemaScope helper for parsing schema.table references and building IN filters. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011p298cqnP5d4SztyCTk46C
Adds an allowedSchemas list to DatabaseConfig. The legacy allowedSchema string is kept as a one-item alias; the first entry is the default for unqualified table names. New Services/SchemaScope.cs owns parsing of "table" / "schema.table" references, allow-list enforcement, parameterised IN filters for catalog queries, and resolution of bare names across schemas (ambiguous names are rejected with the candidate list). Exploration tools (GetSchemaInfo, GetTableInfo, DiscoverData, AnalyzeTableRelationships, ProfileDataQuality, performance stats) now span every allowed schema and report a schema field per row. Write tools and the query builder accept schema.table and default to the primary schema. Known limitation (pre-existing): dependency-tree walking stays within the starting table's schema; cross-schema FK chains are not followed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011p298cqnP5d4SztyCTk46C
SQL Server treats ROWCOUNT as a keyword, so `p.rows AS RowCount` fails with "Incorrect syntax near the keyword 'RowCount'" in DiscoverData and GetDatabasePerformanceStats. Pre-existing upstream bug surfaced during live testing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011p298cqnP5d4SztyCTk46C
STRING_SPLIT requires database compatibility level 130+, and the discovery tools failed with "Invalid object name 'STRING_SPLIT'" on an older-compat database. SchemaScope.BuildInFilter now builds the table name predicates the same way the schema filter is built. Pre-existing upstream bug surfaced during live testing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011p298cqnP5d4SztyCTk46C
…Info GetTableSchema kept the column DataReader open (method-scoped using var) while issuing the foreign-key query on the same connection, failing with "There is already an open DataReader associated with this Connection". Pre-existing upstream bug surfaced during live testing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011p298cqnP5d4SztyCTk46C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for exploring multiple schemas from a single project configuration, plus three bug fixes that surfaced while testing the change against a real SQL Server 2022 database.
Multi-schema configuration
{ "allowedSchemas": ["dbo", "sales"] }allowedSchemasis a list. The legacy single-stringallowedSchemastill works and is treated as a one-item list; if both are present the list wins.tableorschema.table. A bare name that exists in more than one allowed schema is rejected with a message listing the candidates, so the model never silently picks the wrong table.GetSchemaInfo,GetTableInfo,DiscoverData,AnalyzeTableRelationships,ProfileDataQuality,GetDatabasePerformanceStats) span every allowed schema and carry aschemafield per row.Access to schema 'x' is not allowed. Allowed schemas: dbo, sales.All of this lives in a new
Services/SchemaScope.cs: parsing of table references, allow-list enforcement, parameterisedIN (...)filter construction for catalog queries, and bare-name resolution across schemas.Bug fixes (pre-existing, found during live testing)
p.rows AS RowCountfails becauseROWCOUNTis a reserved word in SQL Server. Bracketed inDiscoverDataandGetDatabasePerformanceStats.STRING_SPLITrequires database compatibility level 130+, soDiscoverDataandAnalyzeTableRelationshipsfailed on older-compat databases. Replaced with parameterisedINlists built by the same helper.GetSchemaInfowith a table name kept the columnDataReaderopen while issuing the foreign-key query on the same connection, failing with "There is already an open DataReader associated with this Connection".Tests
Adds an xunit project (
McpMsSqlServer.Tests, wired into the solution) covering config deserialization and fallback, case-insensitive allow-list checks, table-reference parsing, and filter construction. 25 tests, all passing. Commits are in TDD order (failing tests first).Verified live against a SQL Server 2022 database with two allowed schemas of 442 and 417 tables: cross-schema listing and discovery, the ambiguity error for a table present in both schemas, qualified lookup, and the disallowed-schema error.
Known limitation
Dependency-tree walking in
AnalyzeTableRelationshipsstays within the starting table's schema (unchanged from upstream); cross-schema FK chains are not followed.🤖 Generated with Claude Code
https://claude.ai/code/session_011p298cqnP5d4SztyCTk46C