Fix skiptoken paging issue when combined with $orderby involving nullable property - #859
Merged
xuzhg merged 1 commit intoMar 27, 2023
Conversation
gathogojr
force-pushed
the
fix/1943-skiptoken-paging-issue-when-combined-with-orderby
branch
from
March 14, 2023 11:39
f0e3f67 to
05eb664
Compare
nullable property
gathogojr
force-pushed
the
fix/1943-skiptoken-paging-issue-when-combined-with-orderby
branch
from
March 15, 2023 05:05
05eb664 to
e30be1f
Compare
gathogojr
requested review from
ElizabethOkerio,
KenitoInc,
corranrogue9,
habbes,
lisicase,
mikepizzo and
xuzhg
March 15, 2023 05:20
xuzhg
approved these changes
Mar 20, 2023
gathogojr
deleted the
fix/1943-skiptoken-paging-issue-when-combined-with-orderby
branch
March 27, 2023 08:23
This was referenced Apr 4, 2023
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request fixes OData/WebApi#1943, fixes OData/WebApi#2041, and fixes OData/WebApi#2561
Description
Consider a simple scenario involving a data sample comprising of
Idkey field and a non-unique nullable fieldCreditLimit:From the controller action, we could configure a page size of 2:
When the data sample is ordered by
CreditLimitfield ($orderby=CreditLimit), and then internally byId(for uniqueness and predictability - stable ordering), the ordered data sample would look at follows:If we query for the
S1Customersentity set and order byCreditLimit, we get the following response:Response:
{ "@odata.context": "http://localhost:5000/odata/$metadata#S1Customers", "value": [ { "Id": 1, "CreditLimit": null }, { "Id": 3, "CreditLimit": null } ], "@odata.nextLink": "http://localhost:5000/odata/S1Customers?$orderby=CreditLimit&$skiptoken=CreditLimit-null,Id-3" }While the response is correct (including the next-link), if we attempt to use the returned next link to fetch the next batch of records, the following error message is returned:
What is happening here is that we’re mishandling the null value and attempting to apply a greater-than operator between the nullable
CreditLimitfield and theODataNullValue.This pull request fixes this issue by ensuring that a valid
Whereexpression is composed as follows:CreditLimit-null,Id-3in ascending order scenario -$orderby=CreditLimit, we compose theWhereexpression as:(CreditLimit ne null OR (CreditLimit eq null AND Id gt 3))CreditLimit-2,Id-2in ascending order scenario -$orderby=CreditLimit, we compose theWhereexpression as:(CreditLimit gt 2 OR (CreditLimit eq 2 AND Id gt 2))CreditLimit-null,Id-3in descending order scenario -$orderby=CreditLimit desc, we compose theWhereexpression as:(CreditLimit eq null AND Id gt 3)CreditLimit-35,Id-6in descending order scenario -$orderby=CreditLimit desc, we compose theWhereexpression as:(CreditLimit lt 35 OR (CreditLimit eq 35 AND Id gt 6))Consider also a more advanced scenario involving a data sample comprising of
Idkey field, a non-nullable fieldGrade, and a non-unique nullable fieldCreditLimit:From the controller action, we would configure a page size of 4 as follows:
When the data sample is ordered by
Gradeand then byCreditLimitfield ($orderby=Grade,CreditLimit), and then internally byId(for uniqueness and predictability - stable ordering), the ordered data sample would look at follows:If we query for the
S2Customersentity set and orderbyGradeand then byCreditLimit, we get the following response:Response
{ "@odata.context": "http://localhost:5000/odata/$metadata#S2Customers", "value": [ { "Id": 1, "Grade": "A", "CreditLimit": null }, { "Id": 3, "Grade": "A", "CreditLimit": 10.00 }, { "Id": 5, "Grade": "A", "CreditLimit": 30.00 }, { "Id": 2, "Grade": "B", "CreditLimit": null } ], "@odata.nextLink": "http://localhost:5000/odata/S2Customers?$orderby=Grade%2CCreditLimit&$skiptoken=Grade-%27B%27,CreditLimit-null,Id-2" }Again, the response is correct (including the next-link), but if we attempt to use the returned next link to fetch the next batch of records, the following error message is returned:
Again, this is due to mishandling of the null value.
In this pull request we ensure that a valid
Whereexpression is composed as follows:Grade-B,CreditLimit-null,Id-2in ascending order scenario -$orderby=Grade,CreditLimit, we compose theWhereexpression as:Grade gt B OR (Grade eq B AND (CreditLimit ne null OR (CreditLimit eq null AND Id gt 2)))Grade-F,CreditLimit-30,Id-12in ascending order scenario -$orderby=Grade,CreditLimit, we compose theWhereexpression as:Grade gt F OR (Grade eq F AND (CreditLimit gt 30 OR (CreditLimit eq 30 AND Id gt 12)))CreditLimit-null,Grade-C,Id-6in ascending order scenario -$orderby=CreditLimit,Grade, we compose theWhereexpression as:CreditLimit ne null OR (CreditLimit eq null AND (Grade gt C OR (Grade eq C AND Id gt 6)))CreditLimit-30,Grade-A,Id-5in ascending order scenario -$orderby=CreditLimit,Grade, we compose theWhereexpression as:CreditLimit gt 30 OR (CreditLimit eq 30 AND (Grade gt A OR (Grade eq A AND Id gt 5)))