to polymorphic mappers that are using a straight "outerjoin"
clause
- sql
+ - fixed grouping of compound selects to give correct results. will break
+ on sqlite in some cases, but those cases were producing incorrect
+ results anyway, sqlite doesn't support grouped compound selects
+ [ticket:623]
- fixed precedence of operators so that parenthesis are correctly applied
[ticket:620]
- calling <column>.in_() (i.e. with no arguments) will return
return self.elem._hide_froms()
def _get_from_objects(self):
return self.elem._get_from_objects()
+ def __getattr__(self, attr):
+ return getattr(self.elem, attr)
class _Label(ColumnElement):
"""represent a label, as typically applied to any column-level element
self.is_scalar = False
self.is_subquery = False
- self.selects = selects
+ # unions group from left to right, so don't group first select
+ self.selects = [n and select.self_group(self) or select for n,select in enumerate(selects)]
# some DBs do not like ORDER BY in the inner queries of a UNION, etc.
for s in selects:
self.__hide_froms.add(f)
def self_group(self, against=None):
+ if isinstance(against, CompoundSelect):
+ return self
return _Grouping(self)
def append_whereclause(self, whereclause):
assert e.execute().fetchall() == [('aaa', 'aaa'), ('aaa', 'ccc'), ('bbb', 'aaa'), ('bbb', 'bbb'), ('ccc', 'bbb'), ('ccc', 'ccc')]
assert e.alias('bar').select().execute().fetchall() == [('aaa', 'aaa'), ('aaa', 'ccc'), ('bbb', 'aaa'), ('bbb', 'bbb'), ('ccc', 'bbb'), ('ccc', 'ccc')]
+ @testbase.unsupported('sqlite', 'mysql', 'oracle')
+ def test_except_style3(self):
+ # aaa, bbb, ccc - (aaa, bbb, ccc - (ccc)) = ccc
+ e = except_(
+ select([t1.c.col3]), # aaa, bbb, ccc
+ except_(
+ select([t2.c.col3]), # aaa, bbb, ccc
+ select([t3.c.col3], t3.c.col3 == 'ccc'), #ccc
+ )
+ )
+ self.assertEquals(e.execute().fetchall(), [('ccc',)])
+
+ @testbase.unsupported('sqlite', 'mysql', 'oracle')
+ def test_union_union_all(self):
+ e = union_all(
+ select([t1.c.col3]),
+ union(
+ select([t1.c.col3]),
+ select([t1.c.col3]),
+ )
+ )
+ self.assertEquals(e.execute().fetchall(), [('aaa',),('bbb',),('ccc',),('aaa',),('bbb',),('ccc',)])
+
@testbase.unsupported('mysql')
def test_composite(self):
u = intersect(
WHERE mytable.name = :mytable_name GROUP BY mytable.myid, mytable.name UNION SELECT mytable.myid, mytable.name, mytable.description \
FROM mytable WHERE mytable.name = :mytable_name_1"
)
+
+ def test_compound_select_grouping(self):
+ self.runtest(
+ union_all(
+ select([table1.c.myid]),
+ union(
+ select([table2.c.otherid]),
+ select([table3.c.userid]),
+ )
+ )
+ ,
+ "SELECT mytable.myid FROM mytable UNION ALL (SELECT myothertable.otherid FROM myothertable UNION \
+SELECT thirdtable.userid FROM thirdtable)"
+ )
+ # This doesn't need grouping, so don't group to not give sqlite unnecessarily hard time
+ self.runtest(
+ union(
+ except_(
+ select([table2.c.otherid]),
+ select([table3.c.userid]),
+ ),
+ select([table1.c.myid])
+ )
+ ,
+ "SELECT myothertable.otherid FROM myothertable EXCEPT SELECT thirdtable.userid FROM thirdtable \
+UNION SELECT mytable.myid FROM mytable"
+ )
def testouterjoin(self):
# test an outer join. the oracle module should take the ON clause of the join and