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
def _get_from_objects(self, **modifiers):
return self.elem._get_from_objects(**modifiers)
-
+
+ def __getattr__(self, attr):
+ return getattr(self.elem, attr)
+
class _Label(ColumnElement):
"""represent a label, as typically applied to any column-level element
using the ``AS`` sql keyword.
self.selects = []
# some DBs do not like ORDER BY in the inner queries of a UNION, etc.
- for s in selects:
+ for n, s in enumerate(selects):
if len(s._order_by_clause):
s = s.order_by(None)
- self.selects.append(s)
+ # unions group from left to right, so don't group first select
+ if n:
+ self.selects.append(s.self_group(self))
+ else:
+ self.selects.append(s)
self._col_map = {}
return column._make_proxy(self)
def self_group(self, against=None):
+ if isinstance(against, CompoundSelect):
+ return self
return _Grouping(self)
def _locate_oid_column(self):
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