fix(csharp): expand SEA catalog wildcards in GetSchemas client-side (PECO-3035) [SEA]#472
Open
eric-wang-1990 wants to merge 4 commits into
Open
fix(csharp): expand SEA catalog wildcards in GetSchemas client-side (PECO-3035) [SEA]#472eric-wang-1990 wants to merge 4 commits into
eric-wang-1990 wants to merge 4 commits into
Conversation
…PECO-3035) [SEA]
JDBC metadata APIs (getSchemas(catalog, schemaPattern)) accept SQL LIKE-style
patterns in the catalog argument (%, _, \_), and Thrift honors those patterns
server-side. The SEA path wrapped the catalog in backticks as a literal
identifier, so SHOW SCHEMAS IN `%` returned empty rather than expanding to
all catalogs.
This change adds client-side wildcard expansion in StatementExecutionConnection:
- null or pure '%' / '*' -> SHOW SCHEMAS IN ALL CATALOGS
- pattern with unescaped %/_ -> SHOW CATALOGS LIKE '<pat>' then per-catalog
SHOW SCHEMAS IN `<cat>` aggregated together
- literal name -> unchanged (single SHOW SCHEMAS IN `<catalog>`)
Both the IGetObjectsDataProvider.GetSchemasAsync path (used by GetObjects)
and StatementExecutionStatement.GetSchemasAsync (direct GetSchemas metadata
command) now share a single ListSchemasAsync helper. Wildcard detection
honors backslash escapes (\_ stays literal).
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a SEA-specific gap in JDBC/Thrift-compatible metadata behavior by expanding SQL LIKE-style wildcards in the catalog argument for GetSchemas/GetObjects(depth=DbSchemas) on the client side (PECO-3035), bringing SEA results in line with Thrift.
Changes:
- Added wildcard detection helpers (
ContainsUnescapedWildcard,IsMatchAnything) to recognize unescaped%/_(with backslash escapes). - Implemented
StatementExecutionConnection.ListSchemasAsyncto resolve catalog wildcards client-side (fast-path toIN ALL CATALOGS, otherwiseSHOW CATALOGS LIKE ...+ per-catalogSHOW SCHEMAS). - Refactored SEA
GetSchemascall sites to share the new logic and added an E2E regression test validating%matches thenullbaseline.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| csharp/src/StatementExecution/MetadataCommands/MetadataCommandBase.cs | Adds wildcard-detection helpers for JDBC-like patterns with backslash escaping. |
| csharp/src/StatementExecution/StatementExecutionConnection.cs | Introduces ListSchemasAsync + ExecuteShowSchemasAsync and routes GetSchemasAsync through it. |
| csharp/src/StatementExecution/StatementExecutionStatement.cs | Refactors GetSchemasAsync to delegate to connection.ListSchemasAsync. |
| csharp/test/E2E/StatementExecution/SeaMetadataE2ETests.cs | Adds E2E regression coverage for catalogPattern="%" in GetObjects(depth=DbSchemas). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ecoding Addresses Copilot review comments on PR #472: - Add Theory-driven unit tests for MetadataCommandBase.ContainsUnescapedWildcard (21 cases) and IsMatchAnything (7 cases). Covers the backslash-escape edge cases that drive client-side wildcard expansion in ListSchemasAsync. - Decode SHOW CATALOGS results via TryGetColumn<StringArray>(batch, "catalog") instead of positional batch.Column(0), matching the convention in GetCatalogsAsync / GetTablesAsync / etc. Apply the same to ExecuteShowSchemasAsync for the SHOW SCHEMAS result columns (databaseName, catalog). - Drop the "in deterministic order" claim from the ListSchemasAsync XML doc — the implementation preserves backend order without sorting. Co-authored-by: Isaac
eric-wang-1990
commented
May 29, 2026
Replaces the per-catalog fan-out (SHOW CATALOGS LIKE 'pat' + N x SHOW SCHEMAS IN `cat`) with a single SHOW SCHEMAS IN ALL CATALOGS + client-side filtering by the catalog column. The previous design issued 1+N round-trips and ran N separate queries on the backend; the new one is always 1 round-trip when the catalog pattern is wildcarded. The literal-catalog path is preserved (single SHOW SCHEMAS IN `cat`) so users who pass a specific catalog name don't pay the cost of fetching every catalog's schemas just to throw most of them away. Adds MetadataCommandBase.JdbcLikeToRegex to compile a JDBC LIKE pattern (% / _ / \% / \_ / \\) into an anchored .NET Regex, mirroring the same escape semantics as ContainsUnescapedWildcard. Covered by 23 new [Theory] cases in ShowCommandTests. Co-authored-by: Isaac
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.
What's Changed
JDBC metadata APIs (e.g.
getSchemas(catalog, schemaPattern)) accept SQL LIKE-style patterns in the catalog argument (%,_,\_), and the Thrift driver honors those patterns server-side. The SEA path wrapped the catalog in backticks as a literal identifier, so:catalog="%"Thrift returns all 7 catalogs; SEA looked up a catalog literally named%, found nothing, returned empty.catalog="comp%"Thrift prefix-matches; SEA returned empty.catalog="my_table"(unescaped_) Thrift wildcards match; SEA returned empty.This PR adds client-side wildcard expansion in
StatementExecutionConnection.ListSchemasAsync:nullor pure%/*SHOW SCHEMAS IN ALL CATALOGS(one round-trip)%or_(e.g.comp%)SHOW CATALOGS LIKE '<pat>'to enumerate matches, then per-catalogSHOW SCHEMAS IN \`` aggregated togetherSHOW SCHEMAS IN \``)Wildcard detection lives in
MetadataCommandBaseand honors backslash escapes (so\_and\%stay literal, matching JDBCescape clausesemantics).Both call sites now share the helper:
IGetObjectsDataProvider.GetSchemasAsyncused byconnection.GetObjects(...)StatementExecutionStatement.GetSchemasAsyncused by the directGetSchemasmetadata commandWhy
PECO-3035 (D7 in the SEA rollout). Catalog wildcard handling was the only SEA-specific gap in
GetSchemas; once this lands, SEA and Thrift agree on catalog wildcard semantics forGetSchemas/GetObjects(depth=DbSchemas).GetCatalogsalready usedSHOW CATALOGS LIKEcorrectly; this PR bringsGetSchemasto parity.Red -> Green proof
E2E test
SEA_GetObjects_CatalogPercentWildcard_ReturnsSchemasFromAllCatalogsincsharp/test/E2E/StatementExecution/SeaMetadataE2ETests.csissuesGetObjects(depth=DbSchemas, catalogPattern="%")against the livepecotestingwarehouse and asserts the schema count matches thecatalogPattern=nullbaseline.Before fix:
After fix:
Full class regression check (all 19
SeaMetadataE2ETests):Files touched
csharp/src/StatementExecution/MetadataCommands/MetadataCommandBase.cs(addedContainsUnescapedWildcard+IsMatchAnythinghelpers)csharp/src/StatementExecution/StatementExecutionConnection.cs(addedListSchemasAsync+ privateExecuteShowSchemasAsynchelper;IGetObjectsDataProvider.GetSchemasAsyncnow delegates)csharp/src/StatementExecution/StatementExecutionStatement.cs(refactoredGetSchemasAsyncto delegate toconnection.ListSchemasAsync)csharp/test/E2E/StatementExecution/SeaMetadataE2ETests.cs(new test + helper)Manual verification
dotnet buildsucceeds fornetstandard2.0andnet8.0pecotestingSeaMetadataE2ETestsclass passes (no regressions)ShowCommandTests,StatementExecutionMetadataObjectNotFoundTests)pre-commit run --all-files(skipped locally: pre-commit environment couldn't install setuptools; will run in CI)PECO-3035