]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed recursion overflow which could occur when operating
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 25 Sep 2010 22:38:01 +0000 (18:38 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 25 Sep 2010 22:38:01 +0000 (18:38 -0400)
with two expressions both of type "NullType", but
not the singleton NULLTYPE instance. [ticket:1907]

CHANGES
lib/sqlalchemy/types.py
test/sql/test_types.py

diff --git a/CHANGES b/CHANGES
index d71497795725a3c7bcc535b2cb94415dd4719dd1..58d95ec5416cf69512f70a9f883754a9856a65a6 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -128,6 +128,10 @@ CHANGES
      which contains a Column that is not yet named.
      [ticket:1862]
 
+   - Fixed recursion overflow which could occur when operating
+     with two expressions both of type "NullType", but
+     not the singleton NULLTYPE instance. [ticket:1907]
+     
 - declarative
    - @classproperty (soon/now @mapperproperty) takes effect for 
      __mapper_args__, __table_args__, __tablename__ on 
index af7ef22e69180494d948a2dce190f172ba7e0904..46e5901a31397ada0437b09dd0addcaf3982694b 100644 (file)
@@ -639,7 +639,7 @@ class NullType(TypeEngine):
     __visit_name__ = 'null'
 
     def _adapt_expression(self, op, othertype):
-        if othertype is NULLTYPE or not operators.is_commutative(op):
+        if isinstance(othertype, NullType) or not operators.is_commutative(op):
             return op, self
         else:
             return othertype._adapt_expression(op, self)
index af460628ea3d3fa5b12cb744ad7e2336e87d7a5f..d7caae6003c5a76e1de9069a1fefcee5c5bc77d0 100644 (file)
@@ -738,10 +738,10 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         meta.create_all()
 
         test_table.insert().execute({
-                                        'id':1, 
-                                        'data':'somedata', 
-                                        'atimestamp':datetime.date(2007, 10, 15), 
-                                        'avalue':25, 'bvalue':'foo'})
+                                'id':1, 
+                                'data':'somedata', 
+                                'atimestamp':datetime.date(2007, 10, 15), 
+                                'avalue':25, 'bvalue':'foo'})
 
     @classmethod
     def teardown_class(cls):
@@ -752,7 +752,8 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
         eq_(
             test_table.select().execute().fetchall(),
-            [(1, 'somedata', datetime.date(2007, 10, 15), 25, "BIND_INfooBIND_OUT")]
+            [(1, 'somedata', datetime.date(2007, 10, 15), 25,
+             'BIND_INfooBIND_OUT')]
         )
 
     def test_bind_adapt(self):
@@ -762,9 +763,9 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
 
         eq_(
             testing.db.execute(
-                            select([test_table.c.id, test_table.c.data, test_table.c.atimestamp])
-                            .where(expr), 
-                            {"thedate":datetime.date(2007, 10, 15)}).fetchall(),
+                    select([test_table.c.id, test_table.c.data, test_table.c.atimestamp])
+                    .where(expr), 
+                    {"thedate":datetime.date(2007, 10, 15)}).fetchall(),
             [(1, 'somedata', datetime.date(2007, 10, 15))]
         )
 
@@ -772,21 +773,25 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
         eq_(expr.right.type._type_affinity, MyCustomType)
 
         eq_(
-            testing.db.execute(test_table.select().where(expr), {"somevalue":25}).fetchall(),
-            [(1, 'somedata', datetime.date(2007, 10, 15), 25, 'BIND_INfooBIND_OUT')]
+            testing.db.execute(test_table.select().where(expr),
+             {'somevalue': 25}).fetchall(),
+            [(1, 'somedata', datetime.date(2007, 10, 15), 25,
+             'BIND_INfooBIND_OUT')]
         )
 
         expr = test_table.c.bvalue == bindparam("somevalue")
         eq_(expr.right.type._type_affinity, String)
         
         eq_(
-            testing.db.execute(test_table.select().where(expr), {"somevalue":"foo"}).fetchall(),
-            [(1, 'somedata', datetime.date(2007, 10, 15), 25, 'BIND_INfooBIND_OUT')]
+            testing.db.execute(test_table.select().where(expr), 
+                {"somevalue":"foo"}).fetchall(),
+            [(1, 'somedata', 
+                datetime.date(2007, 10, 15), 25, 'BIND_INfooBIND_OUT')]
         )
     
     def test_literal_adapt(self):
-        # literals get typed based on the types dictionary, unless compatible
-        # with the left side type
+        # literals get typed based on the types dictionary, unless
+        # compatible with the left side type
 
         expr = column('foo', String) == 5
         eq_(expr.right.type._type_affinity, Integer)
@@ -933,7 +938,13 @@ class ExpressionTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
                        )
                 assert isinstance(expr.type, types.Numeric)
 
+    def test_null_comparison(self):
+        eq_(
+            str(column('a', types.NullType()) + column('b', types.NullType())), 
+            "a + b"
+        )
         
+
         
     def test_expression_typing(self):
         expr = column('bar', Integer) - 3