Commits

Mike Bayer  committed 5bd2fe7

merged r4829 of rel_0_4, [ticket:1058]

  • Participants
  • Parent commits a2540fc

Comments (0)

Files changed (4)

 
 0.4.7
 =====
+- orm
+    - The contains() operator when used with many-to-many
+      will alias() the secondary (association) table so
+      that multiple contains() calls will not conflict
+      with each other [ticket:1058]
+      
+- mysql
+    - Added 'CALL' to the list of SQL keywords which return
+      result rows.
+
 - oracle
     - Oracle get_default_schema_name() "normalizes" the name
       before returning, meaning it returns a lower-case name

File lib/sqlalchemy/orm/properties.py

     def _optimized_compare(self, value, value_is_parent=False):
         if value is not None:
             value = attributes.instance_state(value)
-        return self._get_strategy(strategies.LazyLoader).lazy_clause(value, reverse_direction=not value_is_parent)
+        return self._get_strategy(strategies.LazyLoader).lazy_clause(value, reverse_direction=not value_is_parent, alias_secondary=True)
 
     def __str__(self):
         return str(self.parent.class_.__name__) + "." + self.key

File lib/sqlalchemy/orm/strategies.py

         self.is_class_level = True
         self._register_attribute(self.parent.class_, callable_=self.class_level_loader)
 
-    def lazy_clause(self, state, reverse_direction=False):
+    def lazy_clause(self, state, reverse_direction=False, alias_secondary=False):
         if state is None:
             return self._lazy_none_clause(reverse_direction)
             
                 # also its a deferred value; so that when used by Query, the committed value is used
                 # after an autoflush occurs
                 bindparam.value = lambda: mapper._get_committed_state_attr_by_column(state, bind_to_col[bindparam.key])
+
+        if self.parent_property.secondary and alias_secondary:
+            criterion = sql_util.ClauseAdapter(self.parent_property.secondary.alias()).traverse(criterion)
+
         return visitors.cloned_traverse(criterion, {}, {'bindparam':visit_bindparam})
     
     def _lazy_none_clause(self, reverse_direction=False):

File test/orm/query.py

 
         assert [Order(id=4), Order(id=5)] == sess.query(Order).filter(~Order.items.contains(item)).all()
 
+        item2 = sess.query(Item).get(5)
+        assert [Order(id=3)] == sess.query(Order).filter(Order.items.contains(item)).filter(Order.items.contains(item2)).all()
+        
+
     def test_comparison(self):
         """test scalar comparison to an object instance"""
 
         # m2m
         self.assertEquals(sess.query(Item).filter(Item.keywords==None).all(), [Item(id=4), Item(id=5)])
         self.assertEquals(sess.query(Item).filter(Item.keywords!=None).all(), [Item(id=1),Item(id=2), Item(id=3)])
-        
+    
     def test_filter_by(self):
         sess = create_session()
         user = sess.query(User).get(8)