Skip to content

Fixes #35101: keep CLR stored procedures in the MSSQL catalogue - #35162

Merged
ulixius9 merged 1 commit into
mainfrom
detail/bug-fix/fixes-35101-keep-clr-stored-procedures-in-the-mssq-415f9e
Oct 15, 2026
Merged

ulixius9 merged 1 commit into
mainfrom
detail/bug-fix/fixes-35101-keep-clr-stored-procedures-in-the-mssq-415f9e

Conversation

@detail-app

@detail-app detail-app Bot commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Detail bug report: View on Detail

Describe your changes:

Fixes #35101

I worked on MSSQL ingestion silently dropping CLR (assembly) stored procedures from the catalogue. MSSQL_GET_STORED_PROCEDURES sourced the procedure definition via an INNER JOIN sys.sql_modules — added in PR #16002 to fix the 4000-character truncation of INFORMATION_SCHEMA.ROUTINES.ROUTINE_DEFINITION. But sys.sql_modules has no row for CLR procedures (sys.objects.type = 'PC'; their definition lives in sys.assembly_modules), so the INNER JOIN dropped every CLR procedure before it reached Python and left the shipped EXTERNAL -> Language.External language map as dead code. The original (pre-#16002) query returned CLR procedures (with ROUTINE_BODY='EXTERNAL' and ROUTINE_DEFINITION=NULL), so this is a regression.

Type of change:

  • Bug fix

High-level design:

Changed JOIN sys.sql_modules to LEFT JOIN sys.sql_modules in MSSQL_GET_STORED_PROCEDURES (ingestion/src/metadata/ingestion/source/database/mssql/queries.py). CLR procedures now survive the join with definition = NULL. yield_stored_procedure already handles definition=None — the encrypted-procedure placeholder is only substituted for names in the per-(database, schema) encrypted cache (queried via OBJECTPROPERTY(object_id, 'IsEncrypted') = 1, which is only true for T-SQL WITH ENCRYPTION), so a CLR procedure is emitted with language=Language.External and code=None. No models.py change was needed; the pre-existing EXTERNAL arm of STORED_PROC_LANGUAGE_MAP becomes live again. T-SQL procedures are unaffected — each has exactly one sys.sql_modules row, so the LEFT JOIN returns the same single row the INNER JOIN did (no row duplication).

Tests:

Use cases covered:

  • A CLR procedure (language='EXTERNAL', definition=None) survives MSSQL_GET_STORED_PROCEDURES and is parsed/yielded by get_stored_procedures.
  • A CLR procedure maps to Language.External with code=None — the previously-dead EXTERNAL arm of STORED_PROC_LANGUAGE_MAP.
  • The encrypted-procedure placeholder is not substituted for a CLR procedure (it's only for T-SQL WITH ENCRYPTION).
  • The sys.sql_modules join stays a LEFT JOIN (regression guard against reintroducing the INNER JOIN).
  • T-SQL procedures still return their full definition; the LEFT JOIN adds no duplicate rows.
  • Cross-schema fan-out and apostrophe-in-identifier paths are unchanged.

Unit tests:
Added TestMssqlClrStoredProcedures in ingestion/tests/unit/topology/database/test_mssql.py (4 tests):

  • query-shape guard asserting every JOIN sys.sql_modules is a LEFT JOIN;
  • get_stored_procedures yields a mocked CLR row with language=='EXTERNAL' and definition is None;
  • yield_stored_procedure emits storedProcedureCode.language == Language.External and code is None;
  • a CLR proc keeps code=None even when the encrypted cache holds other proc names.
    The full test_mssql.py suite (68 tests including the 4 new) passes. ruff check + format are clean, and basedpyright reports no new errors from the change (the 3 pre-existing errors on the pristine tree are all in untouched files / missing optional deps).

Ingestion integration tests:
Ran the existing MSSQL stored-procedure integration tests against a Testcontainers MSSQL 2022 container — test_stored_procedures_fanout.py (cross-schema no-fanout) and test_stored_procedures_apostrophe.py (apostrophe-name). Both pass, confirming the LEFT JOIN fix does not regress T-SQL procedures, cross-schema scoping, or the bound-parameter path.

Manual testing performed:
End-to-end CLR verification against a Testcontainers MSSQL 2022 container — enabled CLR (sp_configure 'clr enabled', 1), compiled a tiny [SqlProcedure] .NET assembly (Mono mcs), registered it via CREATE ASSEMBLY FROM 0x… (trusting it through sp_add_trusted_assembly for clr strict security), and created a CLR stored procedure alongside a T-SQL control procedure. The fixed query returned the CLR proc with language='EXTERNAL' and definition is None, while the T-SQL proc kept its full definition; re-running the pre-fix INNER JOIN query against the same fixture confirmed it omits the CLR proc. This scratch test was not committed (it needs a compiled .NET assembly and Mono tooling), but the unit tests above lock the fix.

Backend integration tests / Playwright (UI) tests: N/A.

UI screen recording / screenshots:

N/A — no UI change.

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • My PR is linked to a GitHub issue via Fixes #<issue-number> above.
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: N/A.
  • For UI changes: N/A.
  • I have added tests (unit / integration / Playwright as applicable) and listed them above.

Automatic Fixes PRs can be configured here.

@detail-app
detail-app Bot requested a review from a team as a code owner October 10, 2026 02:19
@detail-app
detail-app Bot requested a review from akashverma0786 October 10, 2026 02:19
@github-actions

Copy link
Copy Markdown
Contributor

Hi there 👋 Thanks for your contribution!

The OpenMetadata team will review the PR shortly! Once it has been labeled as safe to test, the CI workflows
will start executing and we'll be able to make sure everything is working as expected.

Let us know if you need any help!

@detail-app detail-app Bot added the safe to test Add this label to run secure Github workflows on PRs label Oct 10, 2026
@sonarqubecloud

Copy link
Copy Markdown

@ulixius9
ulixius9 added this pull request to the merge queue Oct 15, 2026
Merged via the queue into main with commit e1c2d93 Oct 15, 2026
108 of 117 checks passed
@ulixius9
ulixius9 deleted the detail/bug-fix/fixes-35101-keep-clr-stored-procedures-in-the-mssq-415f9e branch October 15, 2026 23:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Detail Bug] MSSQL ingestion silently omits CLR stored procedures from the catalog

2 participants