From 0400f7246b6dec89f6ee42cd5162734624d70c59 Mon Sep 17 00:00:00 2001 From: Erik Darling <2136037+erikdarlingdata@users.noreply.github.com> Date: Tue, 21 Apr 2026 11:02:56 -0400 Subject: [PATCH] Skip live query plans on Azure SQL DB (#857) sys.dm_exec_query_statistics_xml requires VIEW SERVER PERFORMANCE STATE on Azure SQL Database regardless of scope, so DB-scoped logins (e.g. D365FO) still hit error 300 even after the #temp pre-filter landed in #869. The OUTER APPLY evaluates the DMF for every session in #req and fails on the permission check before returning rows. Force supportsLiveQueryPlan=false for SqlEngineEdition=5 in both the collector and the Live Snapshot button paths. Boxed SQL Server and Azure MI (edition 8) still get live plans as before. Co-Authored-By: Claude Opus 4.7 (1M context) --- Lite/Controls/ServerTab.xaml.cs | 4 +++- .../RemoteCollectorService.QuerySnapshots.cs | 13 ++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Lite/Controls/ServerTab.xaml.cs b/Lite/Controls/ServerTab.xaml.cs index e08ac21..1d7ab41 100644 --- a/Lite/Controls/ServerTab.xaml.cs +++ b/Lite/Controls/ServerTab.xaml.cs @@ -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); await using var connection = new SqlConnection(builder.ConnectionString); await connection.OpenAsync(); diff --git a/Lite/Services/RemoteCollectorService.QuerySnapshots.cs b/Lite/Services/RemoteCollectorService.QuerySnapshots.cs index 5148af4..c18523c 100644 --- a/Lite/Services/RemoteCollectorService.QuerySnapshots.cs +++ b/Lite/Services/RemoteCollectorService.QuerySnapshots.cs @@ -217,11 +217,18 @@ internal static string BuildQuerySnapshotsQuery(bool supportsLiveQueryPlan, bool /// private async Task 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); var query = BuildQuerySnapshotsQuery(supportsLiveQueryPlan, isAzureSqlDatabase);