summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/compiler.py15
-rw-r--r--lib/sqlalchemy/sql/expression.py21
2 files changed, 27 insertions, 9 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 2fed1d666..be3375def 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -134,6 +134,15 @@ EXTRACT_MAP = {
'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."""
@@ -158,6 +167,8 @@ class SQLCompiler(engine.Compiled):
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
@@ -414,7 +425,9 @@ class SQLCompiler(engine.Compiled):
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))
)
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 0b65cfa34..9bc127291 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -528,7 +528,7 @@ def union(*selects, **kwargs):
: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.
@@ -547,7 +547,7 @@ def union_all(*selects, **kwargs):
: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.
@@ -563,7 +563,7 @@ def except_(*selects, **kwargs):
: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.
@@ -579,7 +579,7 @@ def except_all(*selects, **kwargs):
: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.
@@ -595,7 +595,7 @@ def intersect(*selects, **kwargs):
: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.
@@ -611,7 +611,7 @@ def intersect_all(*selects, **kwargs):
: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.
@@ -904,8 +904,6 @@ def _cloned_intersection(a, b):
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 \
@@ -3459,6 +3457,13 @@ class CompoundSelect(_SelectBaseMixin, FromClause):
__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