summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/default_comparator.py46
-rw-r--r--lib/sqlalchemy/sql/operators.py3
-rw-r--r--lib/sqlalchemy/sql/sqltypes.py18
-rw-r--r--lib/sqlalchemy/sql/type_api.py46
4 files changed, 54 insertions, 59 deletions
diff --git a/lib/sqlalchemy/sql/default_comparator.py b/lib/sqlalchemy/sql/default_comparator.py
index d26fdc455..c898b78d6 100644
--- a/lib/sqlalchemy/sql/default_comparator.py
+++ b/lib/sqlalchemy/sql/default_comparator.py
@@ -9,8 +9,8 @@
"""
from .. import exc, util
-from . import operators
from . import type_api
+from . import operators
from .elements import BindParameter, True_, False_, BinaryExpression, \
Null, _const_expr, _clause_element_as_expr, \
ClauseList, ColumnElement, TextClause, UnaryExpression, \
@@ -18,7 +18,7 @@ from .elements import BindParameter, True_, False_, BinaryExpression, \
from .selectable import SelectBase, Alias, Selectable, ScalarSelect
-class _DefaultColumnComparator(operators.ColumnOperators):
+class _DefaultColumnComparator(object):
"""Defines comparison and math operations.
See :class:`.ColumnOperators` and :class:`.Operators` for descriptions
@@ -26,46 +26,6 @@ class _DefaultColumnComparator(operators.ColumnOperators):
"""
- @util.memoized_property
- def type(self):
- return self.expr.type
-
- def operate(self, op, *other, **kwargs):
- o = self.operators[op.__name__]
- return o[0](self, self.expr, op, *(other + o[1:]), **kwargs)
-
- def reverse_operate(self, op, other, **kwargs):
- o = self.operators[op.__name__]
- return o[0](self, self.expr, op, other,
- reverse=True, *o[1:], **kwargs)
-
- def _adapt_expression(self, op, other_comparator):
- """evaluate the return type of <self> <op> <othertype>,
- and apply any adaptations to the given operator.
-
- This method determines the type of a resulting binary expression
- given two source types and an operator. For example, two
- :class:`.Column` objects, both of the type :class:`.Integer`, will
- produce a :class:`.BinaryExpression` that also has the type
- :class:`.Integer` when compared via the addition (``+``) operator.
- However, using the addition operator with an :class:`.Integer`
- and a :class:`.Date` object will produce a :class:`.Date`, assuming
- "days delta" behavior by the database (in reality, most databases
- other than Postgresql don't accept this particular operation).
-
- The method returns a tuple of the form <operator>, <type>.
- The resulting operator and type will be those applied to the
- resulting :class:`.BinaryExpression` as the final operator and the
- right-hand side of the expression.
-
- Note that only a subset of operators make usage of
- :meth:`._adapt_expression`,
- including math operators and user-defined operators, but not
- boolean comparison or special SQL keywords like MATCH or BETWEEN.
-
- """
- return op, other_comparator.type
-
def _boolean_compare(self, expr, op, obj, negate=None, reverse=False,
_python_is_types=(util.NoneType, bool),
result_type = None,
@@ -320,3 +280,5 @@ class _DefaultColumnComparator(operators.ColumnOperators):
return expr._bind_param(operator, other)
else:
return other
+
+the_comparator = _DefaultColumnComparator()
diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py
index a328b023e..f71cba913 100644
--- a/lib/sqlalchemy/sql/operators.py
+++ b/lib/sqlalchemy/sql/operators.py
@@ -38,6 +38,7 @@ class Operators(object):
:class:`.ColumnOperators`.
"""
+ __slots__ = ()
def __and__(self, other):
"""Implement the ``&`` operator.
@@ -267,6 +268,8 @@ class ColumnOperators(Operators):
"""
+ __slots__ = ()
+
timetuple = None
"""Hack, allows datetime objects to be compared on the LHS."""
diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py
index 7bb5c5515..9b0d26601 100644
--- a/lib/sqlalchemy/sql/sqltypes.py
+++ b/lib/sqlalchemy/sql/sqltypes.py
@@ -14,7 +14,6 @@ import codecs
from .type_api import TypeEngine, TypeDecorator, to_instance
from .elements import quoted_name, type_coerce, _defer_name
-from .default_comparator import _DefaultColumnComparator
from .. import exc, util, processors
from .base import _bind_or_error, SchemaEventTarget
from . import operators
@@ -1704,19 +1703,4 @@ type_api.NULLTYPE = NULLTYPE
type_api.MATCHTYPE = MATCHTYPE
type_api._type_map = _type_map
-# this one, there's all kinds of ways to play it, but at the EOD
-# there's just a giant dependency cycle between the typing system and
-# the expression element system, as you might expect. We can use
-# importlaters or whatnot, but the typing system just necessarily has
-# to have some kind of connection like this. right now we're injecting the
-# _DefaultColumnComparator implementation into the TypeEngine.Comparator
-# interface. Alternatively TypeEngine.Comparator could have an "impl"
-# injected, though just injecting the base is simpler, error free, and more
-# performant.
-
-
-class Comparator(_DefaultColumnComparator):
- BOOLEANTYPE = BOOLEANTYPE
-
-TypeEngine.Comparator.__bases__ = (
- Comparator, ) + TypeEngine.Comparator.__bases__
+TypeEngine.Comparator.BOOLEANTYPE = BOOLEANTYPE
diff --git a/lib/sqlalchemy/sql/type_api.py b/lib/sqlalchemy/sql/type_api.py
index 03fed3878..834640928 100644
--- a/lib/sqlalchemy/sql/type_api.py
+++ b/lib/sqlalchemy/sql/type_api.py
@@ -21,6 +21,7 @@ NULLTYPE = None
STRINGTYPE = None
MATCHTYPE = None
+
class TypeEngine(Visitable):
"""The ultimate base class for all SQL datatypes.
@@ -45,9 +46,51 @@ class TypeEngine(Visitable):
"""
+ __slots__ = 'expr', 'type'
def __init__(self, expr):
self.expr = expr
+ self.type = expr.type
+
+ @util.dependencies('sqlalchemy.sql.default_comparator')
+ def operate(self, default_comparator, op, *other, **kwargs):
+ comp = default_comparator.the_comparator
+ o = comp.operators[op.__name__]
+ return o[0](comp, self.expr, op, *(other + o[1:]), **kwargs)
+
+ @util.dependencies('sqlalchemy.sql.default_comparator')
+ def reverse_operate(self, default_comparator, op, other, **kwargs):
+ comp = default_comparator.the_comparator
+ o = comp.operators[op.__name__]
+ return o[0](comp, self.expr, op, other,
+ reverse=True, *o[1:], **kwargs)
+
+ def _adapt_expression(self, op, other_comparator):
+ """evaluate the return type of <self> <op> <othertype>,
+ and apply any adaptations to the given operator.
+
+ This method determines the type of a resulting binary expression
+ given two source types and an operator. For example, two
+ :class:`.Column` objects, both of the type :class:`.Integer`, will
+ produce a :class:`.BinaryExpression` that also has the type
+ :class:`.Integer` when compared via the addition (``+``) operator.
+ However, using the addition operator with an :class:`.Integer`
+ and a :class:`.Date` object will produce a :class:`.Date`, assuming
+ "days delta" behavior by the database (in reality, most databases
+ other than Postgresql don't accept this particular operation).
+
+ The method returns a tuple of the form <operator>, <type>.
+ The resulting operator and type will be those applied to the
+ resulting :class:`.BinaryExpression` as the final operator and the
+ right-hand side of the expression.
+
+ Note that only a subset of operators make usage of
+ :meth:`._adapt_expression`,
+ including math operators and user-defined operators, but not
+ boolean comparison or special SQL keywords like MATCH or BETWEEN.
+
+ """
+ return op, other_comparator.type
def __reduce__(self):
return _reconstitute_comparator, (self.expr, )
@@ -454,6 +497,8 @@ class UserDefinedType(TypeEngine):
__visit_name__ = "user_defined"
class Comparator(TypeEngine.Comparator):
+ __slots__ = ()
+
def _adapt_expression(self, op, other_comparator):
if hasattr(self.type, 'adapt_operator'):
util.warn_deprecated(
@@ -617,6 +662,7 @@ class TypeDecorator(TypeEngine):
"""
class Comparator(TypeEngine.Comparator):
+ __slots__ = ()
def operate(self, op, *other, **kwargs):
kwargs['_python_is_types'] = self.expr.type.coerce_to_is_types