]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
merged r4829 of rel_0_4, [ticket:1058]
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 1 Jun 2008 14:15:41 +0000 (14:15 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 1 Jun 2008 14:15:41 +0000 (14:15 +0000)
CHANGES
lib/sqlalchemy/orm/properties.py
lib/sqlalchemy/orm/strategies.py
test/orm/query.py

diff --git a/CHANGES b/CHANGES
index ff6a0c07d7203af2bda130e255263db0f9c9a175..841a6227556cc8904adf9b3b018c7c1c43530b05 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -72,6 +72,16 @@ user_defined_state
 
 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
index 98f19131ba7fe000fa4b4fc9b6294c271c4561ef..c7300f21605c0d77e8a2d06bc5f8b6e5aa806617 100644 (file)
@@ -426,7 +426,7 @@ class PropertyLoader(StrategizedProperty):
     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
index 76cf4de18b66edc19caf689b2e07f4105efe9755..d40937a18ceb34972bd1e855fde06b09c79e8461 100644 (file)
@@ -294,7 +294,7 @@ class LazyLoader(AbstractRelationLoader):
         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)
             
@@ -310,6 +310,10 @@ class LazyLoader(AbstractRelationLoader):
                 # 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):
index 48e7d5b940d7d6435e9f5752e3c31f4cf8f11923..f8164191878e0880667635c99cd11f1a8e7089ee 100644 (file)
@@ -450,6 +450,10 @@ class FilterTest(QueryTest):
 
         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"""
 
@@ -471,7 +475,7 @@ class FilterTest(QueryTest):
         # 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)