]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Behavioral improvement: empty
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 9 Sep 2011 20:03:23 +0000 (16:03 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 9 Sep 2011 20:03:23 +0000 (16:03 -0400)
    conjunctions such as and_() and or_() will be
    flattened in the context of an enclosing conjunction,
    i.e. and_(x, or_()) will produce 'X' and not 'X AND
    ()'. [ticket:2257].

CHANGES
lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/expression.py
test/sql/test_compiler.py

diff --git a/CHANGES b/CHANGES
index 644c152c4e4dbc8222f16ffd7edd3ea46570604f..8e0398d89a6d33a253031db187d02c011a080449 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -40,6 +40,12 @@ CHANGES
     Does not apply to 0.6.9.
 
 -sql
+  - Behavioral improvement: empty
+    conjunctions such as and_() and or_() will be
+    flattened in the context of an enclosing conjunction,
+    i.e. and_(x, or_()) will produce 'X' and not 'X AND
+    ()'. [ticket:2257].
+
   - Fixed bug regarding calculation of "from" list 
     for a select() element.  The "from" calc is now
     delayed, so that if the construct uses a Column
index 829adebac0f3f2fd98b11055d2a3f4afa0ef28cf..2741a853f2ba1ccc3e2fa659379af30eb104ae84 100644 (file)
@@ -445,7 +445,7 @@ class SQLCompiler(engine.Compiled):
                     s for s in 
                     (c._compiler_dispatch(self, **kwargs) 
                     for c in clauselist.clauses)
-                    if s is not None)
+                    if s)
 
     def visit_case(self, clause, **kwargs):
         x = "CASE "
index 0823137248037f890e10d6e036167d51690ec649..9e920c34f7512c5efd0af7782297f03606293932 100644 (file)
@@ -2902,6 +2902,12 @@ class BooleanClauseList(ClauseList, ColumnElement):
     def _select_iterable(self):
         return (self, )
 
+    def self_group(self, against=None):
+        if not self.clauses:
+            return self
+        else:
+            return super(BooleanClauseList, self).self_group(against=against)
+
 class _Tuple(ClauseList, ColumnElement):
 
     def __init__(self, *clauses, **kw):
index 5c6d163a5effe55ced31b9764a8e4e42ec476a33..17a3a6018b47e5519678935435fd9698411b07ca 100644 (file)
@@ -702,6 +702,27 @@ class SelectTest(fixtures.TestBase, AssertsCompiledSQL):
             checkparams = {'othername_1': 'asdf', 'othername_2':'foo', 'otherid_1': 9, 'myid_1': 12}
         )
 
+    def test_nested_conjunctions_short_circuit(self):
+        """test that empty or_(), and_() conjunctions are collapsed by
+        an enclosing conjunction."""
+
+        t = table('t', column('x'))
+
+        self.assert_compile(
+            select([t]).where(and_(t.c.x==5, 
+                or_(and_(or_(t.c.x==7))))),
+            "SELECT t.x FROM t WHERE t.x = :x_1 AND t.x = :x_2"
+        )
+        self.assert_compile(
+            select([t]).where(and_(or_(t.c.x==12, 
+                and_(or_(t.c.x==8))))),
+            "SELECT t.x FROM t WHERE t.x = :x_1 OR t.x = :x_2"
+        )
+        self.assert_compile(
+            select([t]).where(and_(or_(or_(t.c.x==12), 
+                and_(or_(), or_(and_(t.c.x==8)), and_())))),
+            "SELECT t.x FROM t WHERE t.x = :x_1 OR t.x = :x_2"
+        )
 
     def test_distinct(self):
         self.assert_compile(