-
Notifications
You must be signed in to change notification settings - Fork 518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update SqlQueryGenerator to support client-side paging #3536
base: main
Are you sure you want to change the base?
Conversation
@microsoft-github-policy-service agree |
/azp run |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good on first pass, still running some tests on the behavior. If we include this it will need to default to off as it otherwise would be a breaking change.
Something I need to still test is how this handles updates compared with the old CTs.
@@ -118,7 +119,18 @@ public SearchOptions Create(string resourceType, IReadOnlyList<Tuple<string, str | |||
string.Format(Core.Resources.MultipleQueryParametersNotAllowed, KnownQueryParameterNames.ContinuationToken)); | |||
} | |||
|
|||
continuationToken = ContinuationTokenConverter.Decode(query.Item2); | |||
// check is continuation token is a numerical format which means it must use an offset | |||
if (int.TryParse(query.Item2, out _)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is being done both here and in the continuation token converter. Making a note to see if it is needed in both locations.
...lth.Fhir.SqlServer/Features/Search/Expressions/Visitors/QueryGenerators/SqlQueryGenerator.cs
Outdated
Show resolved
Hide resolved
@@ -95,7 +108,8 @@ public override Expression VisitSqlRoot(SqlRootExpression expression, SqlSearchO | |||
// for resources that have a value for the _sort parameter. So we will generate | |||
// the appropriate Sort expression below. | |||
} | |||
else if (continuationToken != null && continuationToken.SortValue == null) | |||
else if ((continuationToken != null && continuationToken.SortValue == null) || | |||
(continuationToken == null && context.Sort[0].sortOrder == SortOrder.Ascending)) | |||
{ | |||
// We have a ct for resourceid but not for the sort value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you update the comment to fit the new logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this change
@@ -773,7 +792,7 @@ void AppendOrderBy() | |||
|
|||
StringBuilder.Append("SELECT DISTINCT "); | |||
|
|||
if (includeExpression.Reversed) | |||
if (includeExpression.Reversed && context.UseIndexedPaging) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this case only needed when using indexed paging? This is used to prevent too many results from being returned from a revinclude.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reverted this change. This was an old change i did when I was messing around.
A difference I found in behavior between the two CTs:
This could cause issues for services with heavy usage as the user could get "more" results then they are expecting, or get duplicates if they aren't looking for this issue. |
@almostchristian do you have performance numbers comparing runtimes of your change to our default method? |
Thanks for testing, I think this is an expected behavior with this indexed based paging. Indexed based list is suitable for UIs that have page indexes instead of an infinite scroll. Our UIs uses the traditional table with page numbers, and indexed based paging allows us to generate the links without having to walk through the entire list which would be required in the current ct. |
I don't have the comparison of the performance of the generated sql, but I was able to measure the e2e performance below. Test setup: From a fresh db, create patient with same data 1000 times, then search by patient.identifier. I get the first page and second page, with _count of 2.
|
Description
Updates
SqlQueryGenerator
to support client-side paging by generating queries that are paged using OFFSET. If the configuration SupportsIndexedPaging is set to false, the old query generation will be used. If the ct parameter is numeric, indexed paging will be used regardless of the SupportsIndexedPaging configuration.Related issues
Addresses #2454.
Testing
Added tests in ChainingSearchTests
FHIR Team Checklist
Semver Change (docs)
Patch|Skip|Feature|Breaking (reason)