which is more or less equivalent on that platform.
[ticket:1712]
is emitted asking that the user seriously consider
the usage of this difficult mode of operation.
[ticket:1670]
-
+
+ - The except_() method now renders as MINUS on Oracle,
+ which is more or less equivalent on that platform.
+ [ticket:1712]
+
- sqlite
- Added "native_datetime=True" flag to create_engine().
This will cause the DATE and TIMESTAMP types to skip
statements to work under non-ANSI configured Oracle databases, if
the use_ansi flag is False.
"""
-
+
+ compound_keywords = util.update_copy(
+ compiler.SQLCompiler.compound_keywords,
+ {
+ expression.CompoundSelect.EXCEPT : 'MINUS'
+ }
+ )
+
def __init__(self, *args, **kwargs):
super(OracleCompiler, self).__init__(*args, **kwargs)
self.__wheres = {}
class SQLiteCompiler(compiler.SQLCompiler):
- extract_map = compiler.SQLCompiler.extract_map.copy()
- extract_map.update({
+ extract_map = util.update_copy(
+ compiler.SQLCompiler.extract_map,
+ {
'month': '%m',
'day': '%d',
'year': '%Y',
'timezone_minute': 'timezone_minute'
}
+COMPOUND_KEYWORDS = {
+ sql.CompoundSelect.UNION : 'UNION',
+ sql.CompoundSelect.UNION_ALL : 'UNION ALL',
+ sql.CompoundSelect.EXCEPT : 'EXCEPT',
+ sql.CompoundSelect.EXCEPT_ALL : 'EXCEPT ALL',
+ sql.CompoundSelect.INTERSECT : 'INTERSECT',
+ sql.CompoundSelect.INTERSECT_ALL : 'INTERSECT ALL'
+}
+
class _CompileLabel(visitors.Visitable):
"""lightweight label object which acts as an expression._Label."""
extract_map = EXTRACT_MAP
+ compound_keywords = COMPOUND_KEYWORDS
+
# class-level defaults which can be set at the instance
# level to define if this Compiled instance represents
# INSERT/UPDATE/DELETE
entry = self.stack and self.stack[-1] or {}
self.stack.append({'from':entry.get('from', None), 'iswrapper':True})
- text = (" " + cs.keyword + " ").join(
+ keyword = self.compound_keywords.get(cs.keyword)
+
+ text = (" " + keyword + " ").join(
(self.process(c, asfrom=asfrom, parens=False, compound_index=i)
for i, c in enumerate(cs.selects))
)
:func:`select`.
"""
- return _compound_select('UNION', *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.UNION, *selects, **kwargs)
def union_all(*selects, **kwargs):
"""Return a ``UNION ALL`` of multiple selectables.
:func:`select`.
"""
- return _compound_select('UNION ALL', *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.UNION_ALL, *selects, **kwargs)
def except_(*selects, **kwargs):
"""Return an ``EXCEPT`` of multiple selectables.
:func:`select`.
"""
- return _compound_select('EXCEPT', *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.EXCEPT, *selects, **kwargs)
def except_all(*selects, **kwargs):
"""Return an ``EXCEPT ALL`` of multiple selectables.
:func:`select`.
"""
- return _compound_select('EXCEPT ALL', *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.EXCEPT_ALL, *selects, **kwargs)
def intersect(*selects, **kwargs):
"""Return an ``INTERSECT`` of multiple selectables.
:func:`select`.
"""
- return _compound_select('INTERSECT', *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.INTERSECT, *selects, **kwargs)
def intersect_all(*selects, **kwargs):
"""Return an ``INTERSECT ALL`` of multiple selectables.
:func:`select`.
"""
- return _compound_select('INTERSECT ALL', *selects, **kwargs)
+ return CompoundSelect(CompoundSelect.INTERSECT_ALL, *selects, **kwargs)
def alias(selectable, alias=None):
"""Return an :class:`Alias` object.
all_overlap = set(_expand_cloned(a)).intersection(_expand_cloned(b))
return set(elem for elem in a if all_overlap.intersection(elem._cloned_set))
-def _compound_select(keyword, *selects, **kwargs):
- return CompoundSelect(keyword, *selects, **kwargs)
def _is_literal(element):
return not isinstance(element, Visitable) and \
__visit_name__ = 'compound_select'
+ UNION = util.symbol('UNION')
+ UNION_ALL = util.symbol('UNION ALL')
+ EXCEPT = util.symbol('EXCEPT')
+ EXCEPT_ALL = util.symbol('EXCEPT ALL')
+ INTERSECT = util.symbol('INTERSECT')
+ INTERSECT_ALL = util.symbol('INTERSECT ALL')
+
def __init__(self, keyword, *selects, **kwargs):
self._should_correlate = kwargs.pop('correlate', False)
self.keyword = keyword
s = select([t])
s = select([s.c.col1, s.c.col2])
- self.assert_compile(s, "SELECT col1, col2 FROM (SELECT sometable.col1 AS col1, sometable.col2 AS col2 FROM sometable)")
+ self.assert_compile(s, "SELECT col1, col2 FROM (SELECT "
+ "sometable.col1 AS col1, sometable.col2 AS col2 FROM sometable)")
def test_limit(self):
t = table('sometable', column('col1'), column('col2'))
s = select([s.c.col1, s.c.col2])
- self.assert_compile(s, "SELECT col1, col2 FROM (SELECT col1, col2 FROM (SELECT col1, col2, ROWNUM AS ora_rn FROM (SELECT sometable.col1 AS col1, sometable.col2 AS col2 FROM sometable) WHERE ROWNUM <= :ROWNUM_1) WHERE ora_rn > :ora_rn_1)")
+ self.assert_compile(s, "SELECT col1, col2 FROM (SELECT col1, col2 FROM "
+ "(SELECT col1, col2, ROWNUM AS ora_rn FROM (SELECT "
+ "sometable.col1 AS col1, sometable.col2 AS col2 FROM "
+ "sometable) WHERE ROWNUM <= :ROWNUM_1) WHERE ora_rn > :ora_rn_1)")
# testing this twice to ensure oracle doesn't modify the original statement
- self.assert_compile(s, "SELECT col1, col2 FROM (SELECT col1, col2 FROM (SELECT col1, col2, ROWNUM AS ora_rn FROM (SELECT sometable.col1 AS col1, sometable.col2 AS col2 FROM sometable) WHERE ROWNUM <= :ROWNUM_1) WHERE ora_rn > :ora_rn_1)")
+ self.assert_compile(s, "SELECT col1, col2 FROM (SELECT col1, col2 FROM "
+ "(SELECT col1, col2, ROWNUM AS ora_rn FROM (SELECT "
+ "sometable.col1 AS col1, sometable.col2 AS col2 FROM sometable) "
+ "WHERE ROWNUM <= :ROWNUM_1) WHERE ora_rn > :ora_rn_1)")
s = select([t]).limit(10).offset(20).order_by(t.c.col2)
from_obj = [ outerjoin(table1, table2, table1.c.myid == table2.c.otherid) ]
)
self.assert_compile(query,
- "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername \
-FROM mytable, myothertable WHERE \
-(mytable.name = :name_1 OR mytable.myid = :myid_1 OR \
-myothertable.othername != :othername_1 OR EXISTS (select yay from foo where boo = lar)) \
-AND mytable.myid = myothertable.otherid(+)",
+ "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, "
+ "myothertable.othername FROM mytable, myothertable WHERE "
+ "(mytable.name = :name_1 OR mytable.myid = :myid_1 OR "
+ "myothertable.othername != :othername_1 OR EXISTS (select yay from foo where boo = lar)) "
+ "AND mytable.myid = myothertable.otherid(+)",
dialect=oracle.OracleDialect(use_ansi = False))
query = table1.outerjoin(table2, table1.c.myid==table2.c.otherid).outerjoin(table3, table3.c.userid==table2.c.otherid)
- self.assert_compile(query.select(), "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM mytable LEFT OUTER JOIN myothertable ON mytable.myid = myothertable.otherid LEFT OUTER JOIN thirdtable ON thirdtable.userid = myothertable.otherid")
- self.assert_compile(query.select(), "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM mytable, myothertable, thirdtable WHERE thirdtable.userid(+) = myothertable.otherid AND mytable.myid = myothertable.otherid(+)", dialect=oracle.dialect(use_ansi=False))
+ self.assert_compile(query.select(), "SELECT mytable.myid, mytable.name, mytable.description, "
+ "myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff "
+ "FROM mytable LEFT OUTER JOIN myothertable ON mytable.myid = myothertable.otherid LEFT OUTER "
+ "JOIN thirdtable ON thirdtable.userid = myothertable.otherid")
+ self.assert_compile(query.select(), "SELECT mytable.myid, mytable.name, mytable.description, "
+ "myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM "
+ "mytable, myothertable, thirdtable WHERE thirdtable.userid(+) = myothertable.otherid AND "
+ "mytable.myid = myothertable.otherid(+)", dialect=oracle.dialect(use_ansi=False))
query = table1.join(table2, table1.c.myid==table2.c.otherid).join(table3, table3.c.userid==table2.c.otherid)
- self.assert_compile(query.select(), "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM mytable, myothertable, thirdtable WHERE thirdtable.userid = myothertable.otherid AND mytable.myid = myothertable.otherid", dialect=oracle.dialect(use_ansi=False))
+ self.assert_compile(query.select(), "SELECT mytable.myid, mytable.name, mytable.description, "
+ "myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM "
+ "mytable, myothertable, thirdtable WHERE thirdtable.userid = myothertable.otherid AND "
+ "mytable.myid = myothertable.otherid", dialect=oracle.dialect(use_ansi=False))
query = table1.join(table2, table1.c.myid==table2.c.otherid).outerjoin(table3, table3.c.userid==table2.c.otherid)
"ON addresses.address_type_id = address_types_1.id WHERE addresses.user_id = :user_id_1 ORDER BY addresses.id, "
"address_types.id")
+ def test_compound(self):
+ t1 = table('t1', column('c1'), column('c2'), column('c3'), )
+ t2 = table('t2', column('c1'), column('c2'), column('c3'), )
+ self.assert_compile(
+ union(t1.select(), t2.select()),
+ "SELECT t1.c1, t1.c2, t1.c3 FROM t1 UNION SELECT t2.c1, t2.c2, t2.c3 FROM t2"
+ )
+ self.assert_compile(
+ except_(t1.select(), t2.select()),
+ "SELECT t1.c1, t1.c2, t1.c3 FROM t1 MINUS SELECT t2.c1, t2.c2, t2.c3 FROM t2"
+ )
+
class MultiSchemaTest(TestBase, AssertsCompiledSQL):
__only_on__ = 'oracle'
eq_(found2, wanted)
@testing.crashes('firebird', 'Does not support except')
- @testing.crashes('oracle', 'FIXME: unknown, verify not fails_on')
@testing.crashes('sybase', 'FIXME: unknown, verify not fails_on')
@testing.fails_on('mysql', 'FIXME: unknown')
@testing.fails_on('sqlite', "Can't handle this style of nesting")
eq_(found, wanted)
@testing.crashes('firebird', 'Does not support except')
- @testing.crashes('oracle', 'FIXME: unknown, verify not fails_on')
@testing.crashes('sybase', 'FIXME: unknown, verify not fails_on')
@testing.fails_on('mysql', 'FIXME: unknown')
def test_except_style2(self):
eq_(found2, wanted)
@testing.crashes('firebird', 'Does not support except')
- @testing.crashes('oracle', 'FIXME: unknown, verify not fails_on')
@testing.crashes('sybase', 'FIXME: unknown, verify not fails_on')
@testing.fails_on('mysql', 'FIXME: unknown')
@testing.fails_on('sqlite', "Can't handle this style of nesting")
[('ccc',)])
@testing.crashes('firebird', 'Does not support except')
- @testing.crashes('oracle', 'FIXME: unknown, verify not fails_on')
@testing.crashes('sybase', 'FIXME: unknown, verify not fails_on')
@testing.fails_on('mysql', 'FIXME: unknown')
def test_except_style4(self):