﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
32398	Excluding on annotations doesn't apply null handling.	Gordon Wrigley	Simon Charette	"I would generally expect `my_timestamp__year` to behave the same as `.annotate(my_timestamp_year=ExtractYear(""my_timestamp""))` however I have noticed that when using exclude the former will account for null's but the later won't.

{{{
print(M.objects.exclude(closed_at__year=t.year).values(""closed_at__year"").query)

SELECT 
    EXTRACT('year' FROM ""r_m"".""closed_at"" AT TIME ZONE 'Europe/London') 
FROM ""r_m"" 
WHERE NOT (
    ""r_m"".""closed_at"" BETWEEN 2021-01-01 00:00:00+00:00 AND 2021-12-31 23:59:59.999999+00:00 
    AND ""r_m"".""closed_at"" IS NOT NULL
)
}}}

{{{
print(M.objects.annotate(year=ExtractYear(""closed_at"")).exclude(year=t.year).values(""year"").query)

SELECT 
     EXTRACT('year' FROM ""r_m"".""closed_at"" AT TIME ZONE 'Europe/London') AS ""year"" 
FROM ""r_m"" 
WHERE NOT (
    ""r_m"".""closed_at"" BETWEEN 2021-01-01 00:00:00+00:00 AND 2021-12-31 23:59:59.999999+00:00
)
}}}

Annotated aggregates like min and max also don't account for nulls which leads me to suspect this is a problem with annotations.

I also tried wrapping the ExtractYear in an ExpressionWrapper with `output_field=IntegerField(null=True)` which didn't change anything.
"	Bug	assigned	Database layer (models, ORM)	3.1	Normal			Jacob Walls Simon Charette	Accepted	1	0	0	1	0	0
