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 Correctly implement backwards compatible null comparisons #10935

Merged

Conversation

GuySartorelli
Copy link
Member

@GuySartorelli GuySartorelli commented Aug 30, 2023

#10925 introduced a change to the way ArrayList filtering works. It had a naive cast of null values to empty strings, but that wasn't sufficient for all null comparisons.

This resulted in breaking this unit test, because subsites was using ArrayList to filter null against 0, which used to work but didn't work after the above linked PR.

After making these changes, these failing tests are also passing locally so it looks like it was causing those as well.

Issue

Copy link
Member Author

Choose a reason for hiding this comment

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

These were all the null comparisons I could think of, as far as things that should match. If you think of any others, please ask me to add them.

Comment on lines +711 to +725
$hasNullFilter = false;

foreach ($filters as $filterKey => $filterValue) {
// Convert null to an empty string for backwards compatability, since nulls are treated specially
// Check if we have any null filter values for backwards compatability, since nulls are treated specially
// in the ExactMatchFilter
$searchFilter = $this->createSearchFilter($filterKey, $filterValue ?? '');
if (is_array($filterValue)) {
foreach ($filterValue as $value) {
if ($value === null) {
$hasNullFilter = true;
}
}
} elseif ($filterValue === null) {
$hasNullFilter = true;
}
$searchFilter = $this->createSearchFilter($filterKey, $filterValue);
Copy link
Member Author

Choose a reason for hiding this comment

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

Don't cast the null value to empty string anymore since 0 == '' evaluates false. Instead, just take note of if we have any null values for later.

Comment on lines 734 to 755
$hasMatch = $searchFilter->matches($this->extractValue($item, $searchFilter->getFullName()) ?? '');
$extractedValue = $this->extractValue($item, $searchFilter->getFullName());
$hasMatch = $searchFilter->matches($extractedValue);

// If we didn't get a match, check if we need to do a legacy null
// comparison for backwards compatibility
if (!$hasMatch
&& ($searchFilter instanceof ExactMatchFilter)
&& ($hasNullFilter || $extractedValue === null)
) {
$hasMatch = $this->performLegacyNullMatch($extractedValue, $filterValue);
if (in_array('not', $searchFilter->getModifiers())) {
$hasMatch = !$hasMatch;
}
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Instead of just casting null to empty string, we now first let the search filter do its thing. Only if it doesn't get a match, do we then check if we need to do a legacy null comparison.

Copy link
Member Author

@GuySartorelli GuySartorelli Aug 30, 2023

Choose a reason for hiding this comment

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

Changed this to doing the null check first (if necessary), due to some edge cases. But if the object value isn't null and we don't get a match, we still pass it through to the search filter afterward.

@GuySartorelli
Copy link
Member Author

GuySartorelli commented Aug 30, 2023

Oops I need to add tests to make sure this works as expecte dwith the not modifier. Changed to draft pending that since I'm not able to do it right now.
Edit: Done

@GuySartorelli GuySartorelli marked this pull request as ready for review August 30, 2023 21:14
@emteknetnz emteknetnz merged commit 374771d into silverstripe:5 Aug 31, 2023
15 checks passed
@emteknetnz emteknetnz deleted the pulls/5/fix-broken-tests branch August 31, 2023 00:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants