Skip to content
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

fix: Make sort stable and handle nil comparison #1094

Merged
merged 6 commits into from
Feb 15, 2023

Conversation

shahzadlone
Copy link
Member

@shahzadlone shahzadlone commented Feb 14, 2023

Relevant issue(s)

Resolves #1071
Resolves #921
Blocks: #818, #1070

Description

  • This change uses stable sort and ensures the Less interface implementation only returns true if the comparison is less, otherwise returns false (this is not the full story as for when we do DESC the less to us then is the check of if it's greater than instead of less than). Note: Ensures the ordering of the input array is preserved, so the output is always stable.
  • This change works on both GoLang v1.18.5 and v1.19.5.
  • This also resolves some nil panics we were having before (one subtask of Resolve panics caused by deeper nested orderby #833, which is issue interface conversion orderby panic #921).
    1. Fixes the test: TestOneToManyToOneDeepOrderBySubTypeOfBothDescAndAsc
    2. Fixes the test: TestOneToManyToOneWithSumOfDeepOrderBySubTypeAndDeepOrderBySubtypeAscDirections
  • Ensures our sort handles nil sorting properly for ASC and DESC:
DESC = [10, 9, 8, ... nil, nil]
ASC  = [nil, nil, 1, 2, 3, ... ]

- This does have a side effect which is if you sort in DESC the non-sortables / defaults are sorted to the beginning.
Example: LIST = 1{"x:1"}, 2{"x:2"}, *{"x:5"}, 3{"x:3"}, 2{"x:4"}
- ASC_SORTED_LIST = 1{"x:1"}, 2{"x:2"}, 2{"x:4"}, 3{"x:3"}, *{"x:5"}
- DESC_SORTED_LIST = *{"x:5"}, 3{"x:3"}, 2{"x:2"}, 2{"x:4"}, 1{"x:1"} (unsure if we want this behaviour).

More information in the issue.

Tasks

  • I made sure the code is well commented, particularly hard-to-understand areas.
  • I made sure the repository-held documentation is changed accordingly.
  • I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in tools/configs/chglog/config.yml).
  • I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ...

How has this been tested?

CI + make test

Specify the platform(s) on which this was tested:

  • WSL2 (Manjaro)

@shahzadlone shahzadlone added bug Something isn't working area/testing Related to any test or testing suite area/planner Related to the planner system labels Feb 14, 2023
@shahzadlone shahzadlone added this to the DefraDB v0.5 milestone Feb 14, 2023
@shahzadlone shahzadlone requested a review from a team February 14, 2023 08:00
@shahzadlone shahzadlone self-assigned this Feb 14, 2023
@shahzadlone shahzadlone added the action/no-benchmark Skips the action that runs the benchmark. label Feb 14, 2023
@sourcenetwork sourcenetwork deleted a comment from source-devs Feb 14, 2023
@fredcarle
Copy link
Collaborator

DESC_SORTED_LIST = *{"x:5"}, 3{"x:3"}, 2{"x:2"}, 2{"x:4"}, 1{"x:1"} (unsure if we want this behaviour).

I think that that is "normal" behaviour. Or maybe "expected" behaviour. I'm thinking about when I look things up on Kijiji or AutoTrader or other sites like that, if I sort prices from High to Low I get the highest price first. But if I sort prices from low to high I get the ones with no prices first and then the lowest prices.

BTW the I have a solution for the detect change failure. Will open the PR for it soon.

Copy link
Collaborator

@fredcarle fredcarle left a comment

Choose a reason for hiding this comment

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

LGTM and the resulting behaviour is as I would expect. You can wait for other people's input if you want though.

@orpheuslummis
Copy link
Contributor

DESC_SORTED_LIST = *{"x:5"}, 3{"x:3"}, 2{"x:2"}, 2{"x:4"}, 1{"x:1"} (unsure if we want this behaviour).

I think that that is "normal" behaviour. Or maybe "expected" behaviour. I'm thinking about when I look things up on Kijiji or AutoTrader or other sites like that, if I sort prices from High to Low I get the highest price first. But if I sort prices from low to high I get the ones with no prices first and then the lowest prices.

BTW the I have a solution for the detect change failure. Will open the PR for it soon.

either way we have the behavior, I suggest we should document clearly the behavior

@shahzadlone
Copy link
Member Author

DESC_SORTED_LIST = *{"x:5"}, 3{"x:3"}, 2{"x:2"}, 2{"x:4"}, 1{"x:1"} (unsure if we want this behaviour).

I think that that is "normal" behaviour. Or maybe "expected" behaviour. I'm thinking about when I look things up on Kijiji or AutoTrader or other sites like that, if I sort prices from High to Low I get the highest price first. But if I sort prices from low to high I get the ones with no prices first and then the lowest prices.
BTW the I have a solution for the detect change failure. Will open the PR for it soon.

either way we have the behavior, I suggest we should document clearly the behavior

Agreed, any suggestions where you want that documentation to live?

@AndrewSisley
Copy link
Contributor

AndrewSisley commented Feb 14, 2023

This does have a side effect which is if you sort in DESC the non-sortables / defaults are sorted to the beginning

This seems really odd to me - it essentially means that nil/default is the highest value, not the lowest (as per Fred's comment). You can see this in the (modified) TestOneToManyToOneWithSumOfDeepOrderBySubTypeAndDeepOrderBySubtypeDescDirec

I think it is backwards to most/(all?) sorts I have come across. Nil is usually considered to be lower/less-than than any non-nil value when sorting?

With the current/proposed setup we have the below output:

a := [
    nil,
    nil,
    10,
    9,
    8,
    ...
]

Copy link
Contributor

@AndrewSisley AndrewSisley left a comment

Choose a reason for hiding this comment

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

I think the sort order is odd, and possibly misunderstood by Fred. Please dont merge until clarified/resolved. Code looks good

@fredcarle
Copy link
Collaborator

I think the sort order is odd, and possibly misunderstood by Fred

You're right. I thought about it wrong.

For DESC we should have

a := [
  10,
  9,
  8,
  ...
  nil,
  nil,
]

And for ASC we would have

a := [
  nil,
  nil,
  1,
  2,
  3,
  ...
]

Copy link
Collaborator

@fredcarle fredcarle left a comment

Choose a reason for hiding this comment

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

Removing my approval. Sorry I had something in mind that I though was equivalent to what you had in the PR description but it was actually different. Let's revisit the order.

@shahzadlone shahzadlone force-pushed the lone/fix/unstable-sort-ordering-for-cids branch 2 times, most recently from 52dd021 to 1a59d71 Compare February 15, 2023 07:00
@shahzadlone shahzadlone changed the title fix: Make sort stable and ensure less is valid fix: Make sort stable and handle nil comparison Feb 15, 2023
@shahzadlone
Copy link
Member Author

shahzadlone commented Feb 15, 2023

@AndrewSisley Thanks for the confirmation I caught this last night as well, this fix has been pushed by handling nil comparisons properly, I remember this (somewhat indirectly) is why 2 of our tests also panic before.

@fredcarle Ready for re-review with the sort handling nil like we expect.

PR Description has been updated.

@codecov
Copy link

codecov bot commented Feb 15, 2023

Codecov Report

Merging #1094 (ca33aa2) into develop (efb61cd) will decrease coverage by 0.02%.
The diff coverage is 83.33%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #1094      +/-   ##
===========================================
- Coverage    67.35%   67.33%   -0.02%     
===========================================
  Files          181      181              
  Lines        16730    16744      +14     
===========================================
+ Hits         11268    11275       +7     
- Misses        4513     4518       +5     
- Partials       949      951       +2     
Impacted Files Coverage Δ
db/base/compare.go 65.21% <60.00%> (-4.28%) ⬇️
planner/values.go 82.19% <95.00%> (-0.42%) ⬇️
planner/order.go 83.15% <0.00%> (-3.16%) ⬇️
net/server.go 60.84% <0.00%> (+0.97%) ⬆️

@shahzadlone shahzadlone force-pushed the lone/fix/unstable-sort-ordering-for-cids branch from 1a59d71 to fd35ebc Compare February 15, 2023 07:19
Copy link
Contributor

@AndrewSisley AndrewSisley left a comment

Choose a reason for hiding this comment

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

LGTM - cheers for sorting this out

}

testUtils.AssertPanicAndSkipChangeDetection(t, func() { executeTestCase(t, test) })
Copy link
Contributor

Choose a reason for hiding this comment

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

sweet :) Nice fix

"yearOpened": uint64(1999),
},
},
{
Copy link
Contributor

Choose a reason for hiding this comment

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

praise: Cheers for sorting this out - is horrible that we let this test into develop though, should have been flagged in review

Copy link
Collaborator

@fredcarle fredcarle left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks for changing the behaviour and sorry again for my confusion.

@shahzadlone shahzadlone force-pushed the lone/fix/unstable-sort-ordering-for-cids branch from fd35ebc to ca33aa2 Compare February 15, 2023 19:41
@shahzadlone shahzadlone merged commit 9a0fe20 into develop Feb 15, 2023
@shahzadlone shahzadlone deleted the lone/fix/unstable-sort-ordering-for-cids branch February 15, 2023 20:02
shahzadlone added a commit that referenced this pull request Apr 13, 2023
- Resolves #1071

- Resolves #921

- This change uses stable sort and ensures the `Less` interface implementation only returns true if the comparison is less, otherwise returns false (this is not the full story as for when we do `DESC` the less to us then is the check of if it's greater than instead of less than). Note: Ensures the ordering of the input array is preserved, so the output is always stable.

- This change works on both GoLang v1.18.5 and v1.19.5.

- This also resolves some nil panics we were having before (one subtask of #833, which is issue #921).
	1) Fixes the test: `TestOneToManyToOneDeepOrderBySubTypeOfBothDescAndAsc`
	2) Fixes the test: `TestOneToManyToOneWithSumOfDeepOrderBySubTypeAndDeepOrderBySubtypeAscDirections`

- Ensures our sort handles `nil` sorting properly for `ASC` and `DESC`:
```
DESC = [10, 9, 8, ... nil, nil]
ASC  = [nil, nil, 1, 2, 3, ... ]
```
shahzadlone added a commit to shahzadlone/defradb that referenced this pull request Feb 23, 2024
- Resolves sourcenetwork#1071

- Resolves sourcenetwork#921

- This change uses stable sort and ensures the `Less` interface implementation only returns true if the comparison is less, otherwise returns false (this is not the full story as for when we do `DESC` the less to us then is the check of if it's greater than instead of less than). Note: Ensures the ordering of the input array is preserved, so the output is always stable.

- This change works on both GoLang v1.18.5 and v1.19.5.

- This also resolves some nil panics we were having before (one subtask of sourcenetwork#833, which is issue sourcenetwork#921).
	1) Fixes the test: `TestOneToManyToOneDeepOrderBySubTypeOfBothDescAndAsc`
	2) Fixes the test: `TestOneToManyToOneWithSumOfDeepOrderBySubTypeAndDeepOrderBySubtypeAscDirections`

- Ensures our sort handles `nil` sorting properly for `ASC` and `DESC`:
```
DESC = [10, 9, 8, ... nil, nil]
ASC  = [nil, nil, 1, 2, 3, ... ]
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
action/no-benchmark Skips the action that runs the benchmark. area/planner Related to the planner system area/testing Related to any test or testing suite bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Using GoLang v1.19 cid ordering is changed due to unstable sort interface conversion orderby panic
4 participants