summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/expression.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2009-01-28 01:28:20 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2009-01-28 01:28:20 +0000
commit397ba5d73d8486a2092cacfaaa743d92731ce67c (patch)
treec8703adb47ed04f345374242a25055c2749f04e4 /lib/sqlalchemy/sql/expression.py
parent7e7aa8f7c28628c4b5de7428c33ed63552e8f5b9 (diff)
downloadsqlalchemy-397ba5d73d8486a2092cacfaaa743d92731ce67c.tar.gz
- _CalculatedClause is gone
- Function rolls the various standalone execution functionality of CC into itself, accesses its internal state more directly - collate just uses _BinaryExpression, don't know why it didn't do this already - added new _Case construct, compiles directly - the world is a happier place
Diffstat (limited to 'lib/sqlalchemy/sql/expression.py')
-rw-r--r--lib/sqlalchemy/sql/expression.py159
1 files changed, 74 insertions, 85 deletions
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index cacf7e7b9..f4002fe13 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -462,26 +462,8 @@ def case(whens, value=None, else_=None):
})
"""
- try:
- whens = util.dictlike_iteritems(whens)
- except TypeError:
- pass
-
- if value:
- crit_filter = _literal_as_binds
- else:
- crit_filter = _no_literals
-
- whenlist = [ClauseList('WHEN', crit_filter(c), 'THEN', _literal_as_binds(r), operator=None)
- for (c,r) in whens]
- if else_ is not None:
- whenlist.append(ClauseList('ELSE', _literal_as_binds(else_), operator=None))
- if whenlist:
- type = list(whenlist[-1])[-1].type
- else:
- type = None
- cc = _CalculatedClause(None, 'CASE', value, type_=type, operator=None, group_contents=False, *whenlist + ['END'])
- return cc
+
+ return _Case(whens, value=value, else_=else_)
def cast(clause, totype, **kwargs):
"""Return a ``CAST`` function.
@@ -509,9 +491,10 @@ def collate(expression, collation):
"""Return the clause ``expression COLLATE collation``."""
expr = _literal_as_binds(expression)
- return _CalculatedClause(
- expr, expr, _literal_as_text(collation),
- operator=operators.collate, group=False)
+ return _BinaryExpression(
+ expr,
+ _literal_as_text(collation),
+ operators.collate, type_=expr.type)
def exists(*args, **kwargs):
"""Return an ``EXISTS`` clause as applied to a :class:`~sqlalchemy.sql.expression.Select` object.
@@ -1516,9 +1499,7 @@ class _CompareMixin(ColumnOperators):
def collate(self, collation):
"""Produce a COLLATE clause, i.e. ``<column> COLLATE utf8_bin``"""
- return _CalculatedClause(
- None, self, _literal_as_text(collation),
- operator=operators.collate, group=False)
+ return collate(self, collation)
def op(self, operator):
"""produce a generic operator function.
@@ -1540,6 +1521,7 @@ class _CompareMixin(ColumnOperators):
return lambda other: self.__operate(operator, other)
def _bind_param(self, obj):
+ # ONE COmpareMixin
return _BindParamClause(None, obj, type_=self.type, unique=True)
def _check_literal(self, other):
@@ -2198,73 +2180,55 @@ class BooleanClauseList(ClauseList, ColumnElement):
return (self, )
-class _CalculatedClause(ColumnElement):
- """Describe a calculated SQL expression that has a type, like ``CASE``.
-
- Extends ``ColumnElement`` to provide column-level comparison
- operators.
+class _Case(ColumnElement):
+ __visit_name__ = 'case'
- """
-
- __visit_name__ = 'calculatedclause'
+ def __init__(self, whens, value=None, else_=None):
+ try:
+ whens = util.dictlike_iteritems(whens)
+ except TypeError:
+ pass
- def __init__(self, name, *clauses, **kwargs):
- self.name = name
- self.type = sqltypes.to_instance(kwargs.get('type_', None))
- self._bind = kwargs.get('bind', None)
- self.group = kwargs.pop('group', True)
- clauses = ClauseList(
- operator=kwargs.get('operator', None),
- group_contents=kwargs.get('group_contents', True),
- *clauses)
- if self.group:
- self.clause_expr = clauses.self_group()
+ if value:
+ whenlist = [(_literal_as_binds(c).self_group(), _literal_as_binds(r)) for (c, r) in whens]
else:
- self.clause_expr = clauses
-
- @property
- def key(self):
- return self.name or '_calc_'
+ whenlist = [(_no_literals(c).self_group(), _literal_as_binds(r)) for (c, r) in whens]
+
+ if whenlist:
+ type_ = list(whenlist[-1])[-1].type
+ else:
+ type_ = None
+
+ self.value = value
+ self.type = type_
+ self.whens = whenlist
+ if else_ is not None:
+ self.else_ = _literal_as_binds(else_)
+ else:
+ self.else_ = None
def _copy_internals(self, clone=_clone):
- self.clause_expr = clone(self.clause_expr)
-
- @property
- def clauses(self):
- if isinstance(self.clause_expr, _Grouping):
- return self.clause_expr.element
- else:
- return self.clause_expr
+ if self.value:
+ self.value = clone(self.value)
+ self.whens = [(clone(x), clone(y)) for x, y in self.whens]
+ if self.else_:
+ self.else_ = clone(self.else_)
def get_children(self, **kwargs):
- return self.clause_expr,
+ if self.value:
+ yield self.value
+ for x, y in self.whens:
+ yield x
+ yield y
+ if self.else_:
+ yield self.else_
@property
def _from_objects(self):
- return self.clauses._from_objects
+ return itertools.chain(*[x._from_objects for x in self.get_children()])
- def _bind_param(self, obj):
- return _BindParamClause(self.name, obj, type_=self.type, unique=True)
-
- def select(self):
- return select([self])
-
- def scalar(self):
- return select([self]).execute().scalar()
-
- def execute(self):
- return select([self]).execute()
-
- def _compare_type(self, obj):
- return self.type
-
-class Function(_CalculatedClause, FromClause):
- """Describe a SQL function.
-
- Extends ``_CalculatedClause``, turn the *clauselist* into function
- arguments, also adds a `packagenames` argument.
-
- """
+class Function(ColumnElement, FromClause):
+ """Describe a SQL function."""
__visit_name__ = 'function'
@@ -2284,12 +2248,36 @@ class Function(_CalculatedClause, FromClause):
def columns(self):
return [self]
+ @util.memoized_property
+ def clauses(self):
+ return self.clause_expr.element
+
+ @property
+ def _from_objects(self):
+ return self.clauses._from_objects
+
+ def get_children(self, **kwargs):
+ return self.clause_expr,
+
def _copy_internals(self, clone=_clone):
- _CalculatedClause._copy_internals(self, clone=clone)
+ self.clause_expr = clone(self.clause_expr)
self._reset_exported()
+ util.reset_memoized(self, 'clauses')
+
+ def _bind_param(self, obj):
+ return _BindParamClause(self.name, obj, type_=self.type, unique=True)
- def get_children(self, **kwargs):
- return _CalculatedClause.get_children(self, **kwargs)
+ def select(self):
+ return select([self])
+
+ def scalar(self):
+ return select([self]).execute().scalar()
+
+ def execute(self):
+ return select([self]).execute()
+
+ def _compare_type(self, obj):
+ return self.type
class _Cast(ColumnElement):
@@ -2848,6 +2836,7 @@ class ColumnClause(_Immutable, ColumnElement):
return []
def _bind_param(self, obj):
+ # THREE ColumnCluase
return _BindParamClause(self.name, obj, type_=self.type, unique=True)
def _make_proxy(self, selectable, name=None, attach=True):