diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-16 13:25:46 -0400 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-08-16 13:25:46 -0400 |
commit | fd4ac5b3171dacf2efba31c520c546e2422fba36 (patch) | |
tree | e7a98eba0ec6eca12c679294a6cae52994702da9 | |
parent | a180239d8eda8c20ea39f4f5190abf51deba8b05 (diff) | |
download | sqlalchemy-fd4ac5b3171dacf2efba31c520c546e2422fba36.tar.gz |
- we're going to attempt to get the type/operator system to eat its own dogfood and
use the type-based comparator in all cases. will attempt to remove the _adapt_expression()
method entirely as this represents an incomplete and redundant system (though it might
be a lot faster)
-rw-r--r-- | lib/sqlalchemy/sql/expression.py | 52 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/util.py | 2 | ||||
-rw-r--r-- | lib/sqlalchemy/types.py | 9 | ||||
-rw-r--r-- | test/lib/profiles.txt | 19 |
4 files changed, 41 insertions, 41 deletions
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 613705c38..a0715a975 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -2099,6 +2099,8 @@ class _DefaultColumnComparator(object): if isinstance(other, (SelectBase, Alias)): other = other.as_scalar() return other + elif isinstance(other, sqltypes.TypeEngine.Comparator): + return other.expr elif not isinstance(other, ClauseElement): return expr._bind_param(operator, other) elif isinstance(other, (SelectBase, Alias)): @@ -2152,24 +2154,24 @@ class ColumnElement(ClauseElement, ColumnOperators): __visit_name__ = 'column' primary_key = False foreign_keys = [] - type = None quote = None _label = None _key_label = None _alt_names = () @util.memoized_property + def type(self): + return sqltypes.NULLTYPE + + @util.memoized_property def comparator(self): - if self.type is None: - return None - elif self.type.comparator_factory is not None: - return self.type.comparator_factory(self) - else: - return None + return self.type.comparator_factory(self) + + #def _assert_comparator(self): + # assert self.comparator.expr is self def __getattr__(self, key): - if self.comparator is None: - raise AttributeError(key) + #self._assert_comparator() try: return getattr(self.comparator, key) except AttributeError: @@ -2180,26 +2182,13 @@ class ColumnElement(ClauseElement, ColumnOperators): key) ) - @property - def expression(self): - """Return a column expression. - - Part of the inspection interface; returns self. - - """ - return self - def operate(self, op, *other, **kwargs): - if self.comparator: - return op(self.comparator, *other, **kwargs) - else: - return _DEFAULT_COMPARATOR.operate(self, op, *other, **kwargs) + #self._assert_comparator() + return op(self.comparator, *other, **kwargs) def reverse_operate(self, op, other, **kwargs): - if self.comparator: - return op(other, self.comparator, **kwargs) - else: - return _DEFAULT_COMPARATOR.reverse_operate(self, op, other, **kwargs) + #self._assert_comparator() + return op(other, self.comparator, **kwargs) def _bind_param(self, operator, obj): return BindParameter(None, obj, @@ -2207,6 +2196,15 @@ class ColumnElement(ClauseElement, ColumnOperators): _compared_to_type=self.type, unique=True) @property + def expression(self): + """Return a column expression. + + Part of the inspection interface; returns self. + + """ + return self + + @property def _select_iterable(self): return (self, ) @@ -4007,7 +4005,7 @@ class Grouping(ColumnElement): def __init__(self, element): self.element = element - self.type = getattr(element, 'type', None) + self.type = getattr(element, 'type', sqltypes.NULLTYPE) @property def _label(self): diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 6bfaf4b8c..35761def1 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -420,6 +420,7 @@ class Annotated(object): element.c self.__dict__ = element.__dict__.copy() + self.__dict__.pop('comparator', None) self.__element = element self._annotations = values @@ -431,6 +432,7 @@ class Annotated(object): def _with_annotations(self, values): clone = self.__class__.__new__(self.__class__) clone.__dict__ = self.__dict__.copy() + clone.__dict__.pop('comparator', None) clone._annotations = values return clone diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index 6c9041630..40cf2f331 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -47,9 +47,13 @@ class TypeEngine(AbstractType): type level. See :attr:`.TypeEngine.comparator_factory`. """ + def __init__(self, expr): self.expr = expr + def __reduce__(self): + return _reconstitute_comparator, (self.expr, ) + def operate(self, op, *other, **kwargs): return _DEFAULT_COMPARATOR.operate(self.expr, op, *other, **kwargs) @@ -57,7 +61,7 @@ class TypeEngine(AbstractType): return _DEFAULT_COMPARATOR.reverse_operate(self.expr, op, other, **kwargs) - comparator_factory = None + comparator_factory = Comparator """A :class:`.TypeEngine.Comparator` class which will apply to operations performed by owning :class:`.ColumnElement` objects. @@ -406,6 +410,9 @@ class TypeEngine(AbstractType): def __repr__(self): return util.generic_repr(self) +def _reconstitute_comparator(expression): + return expression.comparator + class UserDefinedType(TypeEngine): """Base for user defined types. diff --git a/test/lib/profiles.txt b/test/lib/profiles.txt index 5572a8ebc..edbee75e9 100644 --- a/test/lib/profiles.txt +++ b/test/lib/profiles.txt @@ -1,15 +1,15 @@ # /Users/classic/dev/sqla_comparators/./test/lib/profiles.txt # This file is written out on a per-environment basis. -# For each test in aaa_profiling, the corresponding function and +# For each test in aaa_profiling, the corresponding function and # environment is located within this file. If it doesn't exist, # the test is skipped. -# If a callcount does exist, it is compared to what we received. +# If a callcount does exist, it is compared to what we received. # assertions are raised if the counts do not match. -# -# To add a new callcount test, apply the function_call_count -# decorator and re-run the tests using the --write-profiles option - +# +# To add a new callcount test, apply the function_call_count +# decorator and re-run the tests using the --write-profiles option - # this file will be rewritten including the new count. -# +# # TEST: test.aaa_profiling.test_compiler.CompileTest.test_insert @@ -195,13 +195,6 @@ test.aaa_profiling.test_resultset.ExecutionTest.test_minimal_engine_execute 3.2_ # TEST: test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile -test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.6_sqlite_pysqlite_nocextensions 12 -test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_mysql_mysqldb_cextensions 12 -test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_mysql_mysqldb_nocextensions 12 -test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_postgresql_psycopg2_cextensions 12 -test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_postgresql_psycopg2_nocextensions 12 -test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_sqlite_pysqlite_cextensions 12 -test.aaa_profiling.test_resultset.ResultSetTest.test_contains_doesnt_compile 2.7_sqlite_pysqlite_nocextensions 12 # TEST: test.aaa_profiling.test_resultset.ResultSetTest.test_string |