From 3ccf17f8ace09370c7fd1bdee1185a79ccd5ba7e Mon Sep 17 00:00:00 2001 From: Rajendra kadam Date: Fri, 22 May 2026 21:49:23 +0530 Subject: [PATCH] Remove nano_view_queue from unscoped MDM commands list query (#45674) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops `nano_view_queue` from the Apple branch of the unscoped commands list and joins the underlying `nano_*` tables directly. The view's definition bakes in `ORDER BY q.priority DESC, q.created_at`, which MySQL re-materializes on every query — the outer `LIMIT` can't push past it, so each unscoped list call pays the full sort cost over the post-join row set regardless of page size. This is the same join shape the host-scoped path already uses (see `listMDMCommandsByHostIdentifier`), so I followed that pattern. Column output is identical to what the view was producing, which is why no test updates were needed — all the existing `TestListMDMCommands*` cases pass without modification. Scope of this PR is just the hot caller. The view itself isn't touched. The issue notes other call sites (`vpp.go`, `apple_mdm.go`) still go through it, and that dropping the `ORDER BY` from the view's definition would be the durable fix. Both feel like separate PRs — the audit work for other call sites is non-trivial, and modifying the view risks silently breaking any consumer that relied on its implicit ordering. Happy to follow up on either. Refs #44509. # Checklist for submitter - [x] Input is properly validated (no new user input paths; same parameterized query shape) - Tests: existing `TestListMDMCommands*` coverage exercises this path and passes unchanged. No new tests added — see rationale above. - Changes file: not applicable, internal query refactor with no user-visible behavior change. ## Summary by CodeRabbit ## Bug Fixes * Updated Mobile Device Management command status reporting to ensure accurate status and timestamp information. [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/fleetdm/fleet/pull/45674?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) Co-authored-by: Jordan Montgomery --- server/datastore/mysql/mdm.go | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/server/datastore/mysql/mdm.go b/server/datastore/mysql/mdm.go index 6321d6fb39..147d9d65f8 100644 --- a/server/datastore/mysql/mdm.go +++ b/server/datastore/mysql/mdm.go @@ -61,24 +61,29 @@ END AS platform // These subqueries are only used for the all-hosts listing; host-scoped // requests go through listMDMCommandsByHostIdentifier instead. func getMDMCommandsSubqueries() (appleStmt, windowsStmt string) { + // Apple branch joins the underlying nano_* tables directly instead of + // going through the nano_view_queue VIEW. The view bakes + // "ORDER BY q.priority DESC, q.created_at" into its definition, which + // MySQL re-materializes on every query — defeating the outer LIMIT and + // forcing a full join + sort regardless of page size. The host-scoped + // path (see listMDMCommandsByHostIdentifier) already bypasses the view + // for the same reason. appleStmt = ` SELECT - nvq.id as host_uuid, - nvq.command_uuid, - COALESCE(NULLIF(nvq.status, ''), 'Pending') as status, - COALESCE(nvq.result_updated_at, nvq.created_at) as updated_at, - nvq.request_type as request_type, + q.id AS host_uuid, + c.command_uuid, + COALESCE(NULLIF(r.status, ''), 'Pending') AS status, + COALESCE(r.updated_at, q.created_at) AS updated_at, + c.request_type, h.hostname, h.team_id, - nvq.name -FROM - nano_view_queue nvq -INNER JOIN - hosts h -ON - nvq.id = h.uuid -WHERE - nvq.active = 1 + c.name +FROM nano_enrollment_queue q + INNER JOIN nano_commands c ON q.command_uuid = c.command_uuid + INNER JOIN hosts h ON h.uuid = q.id + LEFT JOIN nano_command_results r + ON r.command_uuid = q.command_uuid AND r.id = q.id +WHERE q.active = 1 ` // The Windows sub-statement is itself a UNION ALL of two branches: one