#14609: __or__ method of queries does not return a correctly combined query.
-------------------------------------+-------------------------------------
               Reporter:  melinath   |        Owner:  nobody
                 Status:  new        |    Milestone:
              Component:  Database   |      Version:  1.2
  layer (models, ORM)                |     Keywords:
             Resolution:             |    Has patch:  0
           Triage Stage:  Accepted   |  Needs tests:  0
    Needs documentation:  0          |
Patch needs improvement:  0          |
-------------------------------------+-------------------------------------

Comment (by hvdklauw):

 Ran into this problem two, tried to work around it with Q objects; still
 didn't work

 {{{
 class EntityManager(models.Manager):

     def between(self, entity1, entity2):
         """
             Returns a queryset that shows entities between the two given
 entities
         """

         result =
 
self.get_query_set().filter(related_to__to_entity=entity1).filter(related_from__from_entity=entity2)
 | \
 
self.get_query_set().filter(related_to__to_entity=entity2).filter(related_from__from_entity=entity1)
 | \
 
self.get_query_set().filter(related_from__from_entity=entity1).filter(related_from__from_entity=entity2)
 | \
 
self.get_query_set().filter(related_to__to_entity=entity1).filter(related_to__to_entity=entity2)
         return result

     def between2(self, entity1, entity2):
         from django.db.models import Q
         result = self.get_query_set().filter(
                     (
                         Q(
                             related_to__to_entity=entity1
                         ) & Q(
                             related_from__from_entity=entity2
                         )
                     ) |
                     (
                         Q(
                             related_to__to_entity=entity2
                         ) & Q(
                             related_from__from_entity=entity1
                         )
                     ) |
                     (
                         Q(
                             related_from__from_entity=entity1
                         ) & Q(
                              related_from__from_entity=entity1
                         )
                     ) |
                     (
                         Q(
                             related_to__to_entity=entity1
                         ) & Q(
                             related_to__to_entity=entity2
                         )
                     )
                 )
         return result

 class Entity(models.Model):
     """
         Entity
     """
     name = models.CharField(_('naam'), max_length=250)

     objects = EntityManager()

 class Relation(models.Model):
     """
         Relation
     """
     from_entity = models.ForeignKey(Entity, related_name='related_to',
 verbose_name=_('van entiteit'))
     to_entity = models.ForeignKey(Entity, related_name='related_from',
 verbose_name=_('naar entiteit'))
 }}}

 Resulting query for between is:

 {{{

 SELECT "entities_entity"."id", "entities_entity"."name",
 "entities_entity"."entity_type_id"
 FROM "entities_entity"
 INNER JOIN "entities_relation" ON ("entities_entity"."id" =
 "entities_relation"."from_entity_id")
 INNER JOIN "entities_relation" T4 ON ("entities_entity"."id" =
 T4."to_entity_id")
 LEFT OUTER JOIN "entities_relation" T6 ON ("entities_entity"."id" =
 T6."to_entity_id")
 LEFT OUTER JOIN "entities_relation" T7 ON ("entities_entity"."id" =
 T7."from_entity_id")
 WHERE (("entities_relation"."to_entity_id" = 1  AND T4."from_entity_id" =
 3 )
         OR ("entities_relation"."to_entity_id" = 3  AND
 T4."from_entity_id" = 1 )
         OR (T4."from_entity_id" = 1  AND T6."from_entity_id" = 3 )
         OR ("entities_relation"."to_entity_id" = 1  AND T7."to_entity_id"
 = 3 ))
 }}}
 The problem are the two INNER JOINS I get the expected result when they
 are also LEFT (OUTER) JOINS


 The Q solution gives me this query:

 {{{
 SELECT "entities_entity"."id", "entities_entity"."name",
 "entities_entity"."entity_type_id"
 FROM "entities_entity"
 LEFT OUTER JOIN "entities_relation" ON ("entities_entity"."id" =
 "entities_relation"."from_entity_id")
 LEFT OUTER JOIN "entities_relation" T4 ON ("entities_entity"."id" =
 T4."to_entity_id")
 WHERE (("entities_relation"."to_entity_id" = 1  AND T4."from_entity_id" =
 3 )
         OR ("entities_relation"."to_entity_id" = 3  AND
 T4."from_entity_id" = 1 )
         OR (T4."from_entity_id" = 1  AND T4."from_entity_id" = 1 )
         OR ("entities_relation"."to_entity_id" = 1  AND
 "entities_relation"."to_entity_id" = 3 ))
 }}}
 Which gives me too many results

-- 
Ticket URL: <http://code.djangoproject.com/ticket/14609#comment:2>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

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

Reply via email to