Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Lite/Controls/ServerTab.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5365,7 +5365,9 @@ private async void LiveSnapshot_Click(object sender, RoutedEventArgs e)
ConnectTimeout = 15
};

var query = RemoteCollectorService.BuildQuerySnapshotsQuery(supportsLiveQueryPlan: true, isAzureSqlDatabase: _isAzureSqlDatabase);
// Live query plans require VIEW SERVER PERFORMANCE STATE on Azure SQL DB,
// which DB-scoped logins don't have — skip them there. See #857.
var query = RemoteCollectorService.BuildQuerySnapshotsQuery(supportsLiveQueryPlan: !_isAzureSqlDatabase, isAzureSqlDatabase: _isAzureSqlDatabase);
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Gating logic now lives in two places — here and RemoteCollectorService.QuerySnapshots.cs:231. They agree today (!isAzureSqlDatabase), but the collector also factors version/edition (>= 13 || == 0 || == 8) while this caller only checks Azure. If the collector's predicate gets tighter later (e.g. excludes some other engine edition), this site won't follow. Consider exposing a single RemoteCollectorService.SupportsLiveQueryPlan(serverStatus) helper so both sites share the rule.


Generated by Claude Code


await using var connection = new SqlConnection(builder.ConnectionString);
await connection.OpenAsync();
Expand Down
13 changes: 10 additions & 3 deletions Lite/Services/RemoteCollectorService.QuerySnapshots.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,18 @@ internal static string BuildQuerySnapshotsQuery(bool supportsLiveQueryPlan, bool
/// </summary>
private async Task<int> CollectQuerySnapshotsAsync(ServerConnection server, CancellationToken cancellationToken)
{
// dm_exec_query_statistics_xml requires SQL Server 2016 SP1+ (version 13)
/*
* sys.dm_exec_query_statistics_xml requires SQL Server 2016 SP1+ (version 13)
* on boxed, and VIEW SERVER PERFORMANCE STATE on Azure SQL Database regardless
* of tier. DB-scoped logins (e.g. D365FO) don't have the server-level grant
* and the DMF raises error 300 even when only called for current-DB sessions,
* so we disable live query plans on Azure SQL DB entirely. See #857.
*/
var serverStatus = _serverManager.GetConnectionStatus(server.Id);
var supportsLiveQueryPlan = serverStatus.SqlMajorVersion >= 13 || serverStatus.SqlMajorVersion == 0
|| serverStatus.SqlEngineEdition == 5 || serverStatus.SqlEngineEdition == 8;
var isAzureSqlDatabase = serverStatus.SqlEngineEdition == 5;
var supportsLiveQueryPlan = !isAzureSqlDatabase
&& (serverStatus.SqlMajorVersion >= 13 || serverStatus.SqlMajorVersion == 0
|| serverStatus.SqlEngineEdition == 8);
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Behaviour change worth calling out: previously SqlEngineEdition == 5 (Azure SQL DB) explicitly enabled live plans (the old expression OR'd EngineEdition == 5). After this change Azure SQL DB is unconditionally excluded — including service-tier/login combos where VIEW SERVER PERFORMANCE STATE is held (some elastic admin / server-admin logins can grant it). That's almost certainly the right tradeoff given #857, but it removes the capability for the small set of Azure SQL DB users who weren't broken before. The PR description's deferred test on D365FO is the right gate.


Generated by Claude Code


var query = BuildQuerySnapshotsQuery(supportsLiveQueryPlan, isAzureSqlDatabase);

Expand Down
Loading