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.