Skip to content

Conversation

@grantfitzsimmons
Copy link
Member

@grantfitzsimmons grantfitzsimmons commented Oct 3, 2025

Fixes part of #6446

Screenshots and examples below are based on a local copy of the sbmnhiz database used for developing an export workflow for their institution.

In this example, the main query filter is on the EnvironmentalProtectionStatus in the Determination table. In this case, we want to return all Collection Object records where EnvironmentalProtectionStatus does NOT contain the word 'endangered'. In the current release (v7.11.2.1), the not operator causes Specify to ignore blank/null values as well, which is not intuitive and does not match the preferable behavior used in Specify 6.

872b7b05f8404999fa5bd90b8d5690900a850ad623672b7e0648f57f5ac35a54 copy

image

Left: issue-6446 (this PR), Right: v7.11.2.1
image

image

The query built in Specify 6 is as follows:

select
  count(*) as col_0_0_
from
  collectionobject collection0_
  left outer join determination determinat1_ on collection0_.CollectionObjectID = determinat1_.CollectionObjectID
  left outer join taxon taxon2_ on determinat1_.TaxonID = taxon2_.TaxonID
  left outer join taxon taxon3_ on determinat1_.PreferredTaxonID = taxon3_.TaxonID
  left outer join collectingevent collecting4_ on collection0_.CollectingEventID = collecting4_.CollectingEventID
  left outer join locality locality5_ on collecting4_.LocalityID = locality5_.LocalityID
  left outer join geography geography6_ on locality5_.GeographyID = geography6_.GeographyID
  left outer join localitydetail localityde7_ on locality5_.LocalityID = localityde7_.LocalityID
where
  (
    determinat1_.IsCurrent = 1
    or determinat1_.IsCurrent is null
  )
  and (
    taxon2_.EnvironmentalProtectionStatus not like '%endangered%'
    or taxon2_.EnvironmentalProtectionStatus is null
  )
  and taxon3_.Text2 = 'Published name'
  and collection0_.CollectionMemberID = 4

Critically, this PR aims to match the behavior or {field}.{table} is null akin to Specify 6.

Checklist

  • Self-review the PR after opening it to make sure the changes look good and
    self-explanatory (or properly documented)
  • Add relevant issue to release milestone
  • Add pr to documentation list
  • Add automated tests
  • Add a reverse migration if a migration is present in the PR

Testing instructions

  • Create a query with a field using the "NOT" operator with "In", "Contains", or "Equals" on a field that has empty/NULL data (e.g., NOT Equals "some value").
  • Execute the query and check that empty/NULL records are included in results and count.
  • Test on v7.11.2.1 to confirm empty/NULL records were excluded before the fix.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR updates the query filtering behavior to include NULL/empty values when using the "NOT" operator, aligning Specify 7 with the historical Specify 6 behavior and user expectations. When applying negated filters, the system now explicitly includes records where the filtered field is NULL or empty.

Key Changes

  • Added null_safe_not() helper function to handle negated predicates with NULL value inclusion
  • Modified query filter application logic to use the new helper when negate is True
  • Preserved existing behavior for non-negated filters

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@grantfitzsimmons grantfitzsimmons requested a review from a team October 8, 2025 01:00
@grantfitzsimmons grantfitzsimmons marked this pull request as ready for review October 8, 2025 01:00
Copy link
Collaborator

@emenslin emenslin left a comment

Choose a reason for hiding this comment

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

  • Create a query with a field using the "NOT" operator with "In", "Contains", or "Equals" on a field that has empty/NULL data (e.g., NOT Equals "some value").
  • Execute the query and check that empty/NULL records are included in results and count.
  • Test on v7.11.2.1 to confirm empty/NULL records were excluded before the fix.

Looks good!
Screenshot 2025-10-08 121940

@emenslin emenslin requested a review from a team October 8, 2025 17:21
Copy link

@Iwantexpresso Iwantexpresso left a comment

Choose a reason for hiding this comment

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

  • Create a query with a field using the "NOT" operator with "In", "Contains", or "Equals" on a field that has empty/NULL data (e.g., NOT Equals "some value").

  • Execute the query and check that empty/NULL records are included in results and count.

  • Test on v7.11.2.1 to confirm empty/NULL records were excluded before the fix.

No issues found! The Le left image is the current pr and the right image is the test on v7.11.2.1
Screenshot 2025-10-20 at 2 07 43 PM

Query used
image

It looks good to me!

@grantfitzsimmons grantfitzsimmons requested a review from a team October 20, 2025 19:14
Triggered by 8454454 on branch refs/heads/issue-6446
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 📋Back Log

Development

Successfully merging this pull request may close these issues.

Discrepancy between the counts of query results in 6 and 7

4 participants