Skip to content

Fix SearchParameter pagination bug - move TOP to outer query#5362

Merged
jestradaMS merged 1 commit intomainfrom
users/jestrada/fix-searchparam-pagination-bug
Jan 30, 2026
Merged

Fix SearchParameter pagination bug - move TOP to outer query#5362
jestradaMS merged 1 commit intomainfrom
users/jestrada/fix-searchparam-pagination-bug

Conversation

@jestradaMS
Copy link
Contributor

@jestradaMS jestradaMS commented Jan 30, 2026

Summary

Fixes a pagination bug introduced in commit 6dd540c that caused custom SearchParameters to become "unsupported" after pod restarts.

Problem

The subquery wrapper introduced in #5297 placed TOP inside the inner SELECT without ORDER BY:

-- BEFORE (buggy)
SELECT * FROM (
  SELECT DISTINCT TOP (@p0) r.ResourceTypeId, ...
  FROM dbo.Resource r
  WHERE ResourceTypeId = 123 AND IsHistory = 0
  -- No ORDER BY here!
) AS t ORDER BY t.ResourceTypeId ASC, t.ResourceSurrogateId ASC

This caused SQL Server to return arbitrary rows in clustered index order before the outer ORDER BY reordered them. When pagination continued with ResourceSurrogateId > lastValue, rows with high GUIDs but low surrogate IDs were skipped.

Solution

Move TOP to the outer SELECT so it applies after ORDER BY:

-- AFTER (fixed)
SELECT TOP (@p0) * FROM (
  SELECT DISTINCT r.ResourceTypeId, ...
  FROM dbo.Resource r
  WHERE ResourceTypeId = 123 AND IsHistory = 0
) AS t ORDER BY t.ResourceTypeId ASC, t.ResourceSurrogateId ASC

Impact

  • ~50 FHIR services affected with 7,000-12,000 errors/day since Dec 31, 2025
  • Customer example: Genome loaded 36 SearchParameters on Jan 21, only 24 on Jan 24 after pod restart
  • Affects any account with custom SearchParameters where pagination order differs from clustered index order

Testing

  • Verified locally that generated SQL now has TOP on outer query
  • Confirmed correct pagination behavior with continuation tokens

Related

AB#182301

The subquery wrapper introduced in commit 6dd540c placed TOP inside the
inner SELECT without ORDER BY, causing SQL Server to return arbitrary rows
in clustered index order before the outer ORDER BY reordered them.

This caused pagination to skip resources when continuation tokens filtered
by ResourceSurrogateId > lastValue, as rows with high GUIDs but low
surrogate IDs were excluded from the initial TOP N selection.

Fix: Move TOP to the outer SELECT so it applies after ORDER BY, ensuring
correct row selection for pagination.

Fixes ICM 2601260050003542
@jestradaMS jestradaMS requested a review from a team as a code owner January 30, 2026 20:18
@jestradaMS jestradaMS added this to the FY26\Q3\2Wk\2Wk16 milestone Jan 30, 2026
@jestradaMS jestradaMS added Bug-Reliability Reliability related bugs. Azure API for FHIR Label denotes that the issue or PR is relevant to the Azure API for FHIR Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs Schema Version unchanged No-PaaS-breaking-change labels Jan 30, 2026
// When there are no SearchParamTableExpressions, we need TOP on the outer SELECT (after ORDER BY)
// to ensure pagination works correctly. Previously TOP was in the inner subquery without ORDER BY,
// causing SQL Server to return arbitrary rows before the outer ORDER BY reordered them.
// Fix for pagination bug introduced in commit 6dd540c7d.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I don't think we need references to specific commits in the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I blame co-pilot for that, haha

@jestradaMS jestradaMS added the No-ADR ADR not needed label Jan 30, 2026
@jestradaMS jestradaMS merged commit 5608a06 into main Jan 30, 2026
61 of 69 checks passed
@jestradaMS jestradaMS deleted the users/jestrada/fix-searchparam-pagination-bug branch January 30, 2026 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Azure API for FHIR Label denotes that the issue or PR is relevant to the Azure API for FHIR Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs Bug-Reliability Reliability related bugs. No-ADR ADR not needed No-PaaS-breaking-change Schema Version unchanged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants