Skip to content

feat: add Microsoft Fabric Warehouse / Azure SQL support via Service Principal#838

Open
Germain-D wants to merge 5 commits into
k1LoW:mainfrom
Germain-D:main
Open

feat: add Microsoft Fabric Warehouse / Azure SQL support via Service Principal#838
Germain-D wants to merge 5 commits into
k1LoW:mainfrom
Germain-D:main

Conversation

@Germain-D

Copy link
Copy Markdown
  • New azuresql:// datasource — connects to Microsoft Fabric Warehouse and Azure SQL using Azure AD
    Service Principal auth (fedauth=ActiveDirectoryServicePrincipal). Delegates schema analysis to the
    existing mssql driver.

    • Replace FOR XML PATH with STRING_AGG — FOR XML PATH is unsupported in Synapse SQL / Microsoft Fabric
      Warehouse. STRING_AGG is supported on Azure SQL, Fabric Warehouse, and SQL Server 2017+.

    Breaking Change

    SQL Server 2016 and earlier no longer supported (no STRING_AGG).

    Files changed

    • datasource/azuresql.go — new datasource + STRING_AGG fix
    • datasource/azuresql_test.go — tests for both
    • datasource/datasource.go — register new datasource
    • drivers/mssql/mssql.go — remove FOR XML PATH
    • go.mod / go.sum — new Azure SDK dependency

Germain-D added 2 commits June 4, 2026 11:34
  Enables connecting to Microsoft Fabric Warehouse via azuresql://
  using fedauth=ActiveDirectoryServicePrincipal. Bypasses dburl
  and delegates analysis to the existing mssql driver.
  FOR XML PATH is unsupported in Synapse SQL / Microsoft Fabric Warehouse.
  STRING_AGG achieves the same concatenation and is supported across
  Azure SQL, Fabric Warehouse, and SQL Server 2017+.

  BREAKING CHANGE: SQL Server 2016 and earlier no longer supported.
@Germain-D Germain-D changed the title Add Microsoft Fabric Warehouse / Azure SQL support via Service Principal feat: add Microsoft Fabric Warehouse / Azure SQL support via Service Principal Jun 6, 2026
@k1LoW

k1LoW commented Jun 17, 2026

Copy link
Copy Markdown
Owner

@Germain-D GREAT!! Thank you!!!

I'm unable to maintain a persistent test environment for Microsoft Fabric Warehouse/Azure SQL.

If I put Microsoft Fabric Warehouse/Azure SQL support in tbls, is it ok to make it "experimental support"?

Also, is it possible to commit the following files?

  1. a sample DDL similar to other data sources ( in testdata/ )
  2. a sample document generated by tbls doc for the database created in 1 ( in sample/ )
  3. Datasource section in README.md

Comment thread datasource/azuresql.go Outdated
Comment on lines +26 to +28
// buildAzureSQLConnStr converts azuresql:// URL to a key=value connection string
// because go-mssqldb/azuread only URL-parses sqlserver:// scheme, not azuresql://.
func buildAzureSQLConnStr(urlstr string) (string, error) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider rewriting the scheme instead of hand-building a key=value connection string

go-mssqldb/azuread registers the azuresql driver, but its DSN parser (msdsn.Parse) only URL-parses the sqlserver:// scheme. Instead of assembling an ADO key=value string by hand, we can keep the URL form and just swap the scheme azuresql://sqlserver://, then pass it to sql.Open("azuresql", ...).

I checked azuread/configuration.go: for ActiveDirectoryServicePrincipal it reads params["user id"] (split into tenant/client) and params["password"], and msdsn merges + percent-decodes URL query params (msdsn/conn_str.go), so the existing DSN shape keeps working unchanged.

Besides removing both buildAzureSQLConnStr and parseAzureSQLDatabaseName, this fixes a latent issue: the current fmt.Sprintf builds the ADO form with no escaping, and msdsn's default (non-odbc:) parser splits on ; with no brace quoting. So a password containing ; would break parsing or inject extra options (e.g. TrustServerCertificate=true). The URL form avoids that, since query values are percent-decoded rather than ;-split.

Rough sketch:

func AnalyzeAzureSQL(urlstr string) (_ *schema.Schema, err error) {
	defer func() { err = errors.WithStack(err) }()

	u, err := url.Parse(urlstr)
	if err != nil {
		return nil, err
	}
	q := u.Query()
	dbName := q.Get("database")
	if dbName == "" {
		return nil, fmt.Errorf("no database name in azuresql connection string")
	}
	if q.Get("fedauth") == "" {
		q.Set("fedauth", "ActiveDirectoryServicePrincipal")
	}
	q.Set("encrypt", "true") // preserve current Encrypt=true posture
	u.RawQuery = q.Encode()
	u.Scheme = "sqlserver" // azuread driver only URL-parses sqlserver://

	db, err := sql.Open("azuresql", u.String())
	// ... Ping + mssqlDriver.New(db).Analyze(s)
}

WDYT?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a great idea! I tried implementing it with Claude. Let me know what you think

Germain-D and others added 3 commits June 22, 2026 19:06
connstr manually
Avoids hand-built ADO key=value connection string. go-mssqldb/azuread's
msdsn parser only URL-parses sqlserver://, so we swap the scheme and let
msdsn handle query param parsing/percent-decoding directly. Fixes a
latent issue where a password containing ';' could break parsing or
inject extra ADO options (e.g. TrustServerCertificate=true).
  Adds the three artifacts requested for experimental Azure SQL
  /Microsoft Fabric Warehouse support:
  - testdata/ddl/azuresql.sql: sample schema (5 tables + 1 view, FKs,
    sp_addextendedproperty comments, no TRIGGER/PROC for Fabric
    Warehouse compatibility)
  - testdata/test_tbls_azuresql.yml: tbls config for the sample
  - sample/azuresql/: docs generated by `tbls doc` (md, svg,
    schema.json)
  - README.md: azuresql:// datasource entry (Experimental), with Azure
    AD Service Principal DSN examples and param reference
  - Makefile: azuresql targets in db/doc/testdoc + separate
    doc_azuresql/test_azuresql for real Azure credentials
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants