I too was rather surprised by this behavior. I have since changed my
code to use exclude(related__field__isnull = False) instead of
filter(related__field__isnull = True) to avoid this issue.

I'm all for an API, but I'm not sure which would be best. Maybe
filter(related__field__isnull_nopromote = True) ? This isn't
particularly elegant though. I'd prefer filter(related__field__isnull
= True, no_promote = True) but that would forbid users from using
no_promote as a field name.

Another backward-compatible way would be to add a no_promote() method
to the queryset:
Model.objects.no_promote().filter(related__field__isnull = True)



On 6 January 2011 22:13, Byron Ruth <bjr...@gmail.com> wrote:
> I am speaking of this particular if statement:
> http://code.djangoproject.com/browser/django/tags/releases/1.2.4/django/db/models/sql/query.py#L1051
>
> There are a few implications of this assumption. One being, that if
> the user is actually trying to get the "real" rows that exist with a
> column that has a NULL value, they will get those in addition to all
> the rows generated that are empty as a result of the LEFT OUTER JOIN.
>
> Given the example:
>
>    SELECT * FROM table1 INNER JOIN table2 ON (table2.table1_id =
> table1.id) WHERE table2.foo IS NULL
>
> With the INNER JOIN, if table2 is empty, no rows will return. Any
> table2 rows that match 'foo IS NULL' will return if and only if it
> references a row in table1 (obviously if table1_id is not nullable,
> this will always be true).
>
>    SELECT * FROM table1 LEFT OUTER JOIN table2 ON (table2.table1_id =
> table1.id) WHERE table2.foo IS NULL
>
> With the LEFT OUTER JOIN, if table2 is empty, all of the rows from
> table1 will return! In addition, any rows in table2 that match 'foo IS
> NULL' will return as well as the ones that don't have rows that exist
> in the table!
>
> This seems like very strange behavior to have by default. I suggest
> there be a way to prevent the joins from being promoted to LEFT OUTER
> JOIN when the specifying a QuerySet condition using NULL values.
>
> Obviously the fact that people have been relying on this behavior for
> 2+ years either proves to be the correct assumption or not many have
> come across these scenarios. I propose exposing a small API that
> allows for keeping INNER JOINs and not promoting simply because of a
> NULL value.
>
> Any thoughts or feedback on this argument?
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To post to this group, send email to django-develop...@googlegroups.com.
> To unsubscribe from this group, send email to 
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/django-developers?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-develop...@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to