summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-05-24 14:35:28 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2014-05-24 14:35:28 -0400
commitd1705a46fea6beb7a02d20b2bdc1518c214012ff (patch)
treee0f5fd316ad845ecd41aa8f4f395e00a26c65a39 /lib/sqlalchemy
parent931685bac9161056cda3337ca2515ae9add236d8 (diff)
downloadsqlalchemy-d1705a46fea6beb7a02d20b2bdc1518c214012ff.tar.gz
- Fixed bug where the :meth:`.Operators.__and__`,
:meth:`.Operators.__or__` and :meth:`.Operators.__invert__` operator overload methods could not be overridden within a custom :class:`.TypeEngine.Comparator` implementation. fixes #3012
Diffstat (limited to 'lib/sqlalchemy')
-rw-r--r--lib/sqlalchemy/sql/default_comparator.py20
-rw-r--r--lib/sqlalchemy/sql/elements.py28
2 files changed, 40 insertions, 8 deletions
diff --git a/lib/sqlalchemy/sql/default_comparator.py b/lib/sqlalchemy/sql/default_comparator.py
index 6bc7fb580..20f13f70f 100644
--- a/lib/sqlalchemy/sql/default_comparator.py
+++ b/lib/sqlalchemy/sql/default_comparator.py
@@ -13,7 +13,7 @@ from . import type_api
from .elements import BindParameter, True_, False_, BinaryExpression, \
Null, _const_expr, _clause_element_as_expr, \
ClauseList, ColumnElement, TextClause, UnaryExpression, \
- collate, _is_literal, _literal_as_text, ClauseElement
+ collate, _is_literal, _literal_as_text, ClauseElement, and_, or_
from .selectable import SelectBase, Alias, Selectable, ScalarSelect
class _DefaultColumnComparator(operators.ColumnOperators):
@@ -124,6 +124,14 @@ class _DefaultColumnComparator(operators.ColumnOperators):
return BinaryExpression(left, right, op, type_=result_type)
+ def _conjunction_operate(self, expr, op, other, **kw):
+ if op is operators.and_:
+ return and_(expr, other)
+ elif op is operators.or_:
+ return or_(expr, other)
+ else:
+ raise NotImplementedError()
+
def _scalar(self, expr, op, fn, **kw):
return fn(expr)
@@ -190,6 +198,13 @@ class _DefaultColumnComparator(operators.ColumnOperators):
raise NotImplementedError("Operator '%s' is not supported on "
"this expression" % op.__name__)
+ def _inv_impl(self, expr, op, **kw):
+ """See :meth:`.ColumnOperators.__inv__`."""
+ if hasattr(expr, 'negation_clause'):
+ return expr.negation_clause
+ else:
+ return expr._negate()
+
def _neg_impl(self, expr, op, **kw):
"""See :meth:`.ColumnOperators.__neg__`."""
return UnaryExpression(expr, operator=operators.neg)
@@ -226,6 +241,9 @@ class _DefaultColumnComparator(operators.ColumnOperators):
# a mapping of operators with the method they use, along with
# their negated operator for comparison operators
operators = {
+ "and_": (_conjunction_operate,),
+ "or_": (_conjunction_operate,),
+ "inv": (_inv_impl,),
"add": (_binary_operate,),
"mul": (_binary_operate,),
"sub": (_binary_operate,),
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py
index 13cf9aa91..ce6056418 100644
--- a/lib/sqlalchemy/sql/elements.py
+++ b/lib/sqlalchemy/sql/elements.py
@@ -505,9 +505,21 @@ class ClauseElement(Visitable):
return unicode(self.compile()).encode('ascii', 'backslashreplace')
def __and__(self, other):
+ """'and' at the ClauseElement level.
+
+ .. deprecated:: 0.9.5 - conjunctions are intended to be
+ at the :class:`.ColumnElement`. level
+
+ """
return and_(self, other)
def __or__(self, other):
+ """'or' at the ClauseElement level.
+
+ .. deprecated:: 0.9.5 - conjunctions are intended to be
+ at the :class:`.ColumnElement`. level
+
+ """
return or_(self, other)
def __invert__(self):
@@ -516,17 +528,18 @@ class ClauseElement(Visitable):
else:
return self._negate()
- def __bool__(self):
- raise TypeError("Boolean value of this clause is not defined")
-
- __nonzero__ = __bool__
-
def _negate(self):
return UnaryExpression(
self.self_group(against=operators.inv),
operator=operators.inv,
negate=None)
+ def __bool__(self):
+ raise TypeError("Boolean value of this clause is not defined")
+
+ __nonzero__ = __bool__
+
+
def __repr__(self):
friendly = getattr(self, 'description', None)
if friendly is None:
@@ -536,8 +549,7 @@ class ClauseElement(Visitable):
self.__module__, self.__class__.__name__, id(self), friendly)
-
-class ColumnElement(ClauseElement, operators.ColumnOperators):
+class ColumnElement(operators.ColumnOperators, ClauseElement):
"""Represent a column-oriented SQL expression suitable for usage in the
"columns" clause, WHERE clause etc. of a statement.
@@ -1503,6 +1515,8 @@ class TextClause(Executable, ClauseElement):
def get_children(self, **kwargs):
return list(self._bindparams.values())
+ def compare(self, other):
+ return isinstance(other, TextClause) and other.text == self.text
class Null(ColumnElement):
"""Represent the NULL keyword in a SQL statement.