summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/expression.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/sql/expression.py')
-rw-r--r--lib/sqlalchemy/sql/expression.py47
1 files changed, 38 insertions, 9 deletions
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index cc97227a7..39a2ae3eb 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -392,7 +392,7 @@ def not_(clause):
result.
"""
- return operators.inv(clause)
+ return operators.inv(_literal_as_binds(clause))
def distinct(expr):
"""Return a ``DISTINCT`` clause."""
@@ -416,24 +416,45 @@ def case(whens, value=None, else_=None):
"""Produce a ``CASE`` statement.
whens
- A sequence of pairs or a dict to be translated into "when / then" clauses.
+ A sequence of pairs, or alternatively a dict,
+ to be translated into "WHEN / THEN" clauses.
value
- Optional for simple case statements.
+ Optional for simple case statements, produces
+ a column expression as in "CASE <expr> WHEN ..."
else\_
- Optional as well, for case defaults.
+ Optional as well, for case defaults produces
+ the "ELSE" portion of the "CASE" statement.
+
+ The expressions used for THEN and ELSE,
+ when specified as strings, will be interpreted
+ as bound values. To specify textual SQL expressions
+ for these, use the text(<string>) construct.
+
+ The expressions used for the WHEN criterion
+ may only be literal strings when "value" is
+ present, i.e. CASE table.somecol WHEN "x" THEN "y".
+ Otherwise, literal strings are not accepted
+ in this position, and either the text(<string>)
+ or literal(<string>) constructs must be used to
+ interpret raw string values.
+
"""
-
try:
whens = util.dictlike_iteritems(whens)
except TypeError:
pass
-
- whenlist = [ClauseList('WHEN', c, 'THEN', r, operator=None)
+
+ 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 not else_ is None:
- whenlist.append(ClauseList('ELSE', else_, operator=None))
+ if else_ is not None:
+ whenlist.append(ClauseList('ELSE', _literal_as_binds(else_), operator=None))
if whenlist:
type = list(whenlist[-1])[-1].type
else:
@@ -842,6 +863,14 @@ def _literal_as_binds(element, name=None, type_=None):
else:
return element
+def _no_literals(element):
+ if isinstance(element, Operators):
+ return element.expression_element()
+ elif _is_literal(element):
+ raise exceptions.ArgumentError("Ambiguous literal: %r. Use the 'text()' function to indicate a SQL expression literal, or 'literal()' to indicate a bound value." % element)
+ else:
+ return element
+
def _corresponding_column_or_error(fromclause, column, require_embedded=False):
c = fromclause.corresponding_column(column, require_embedded=require_embedded)
if not c: