From 85d335b01bf64a27e99cee915205afd99e7191b5 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 11 Feb 2010 19:33:06 +0000 Subject: - The type/expression system now does a more complete job of determining the return type from an expression as well as the adaptation of the Python operator into a SQL operator, based on the full left/right/operator of the given expression. In particular the date/time/interval system created for Postgresql EXTRACT in [ticket:1647] has now been generalized into the type system. The previous behavior which often occured of an expression "column + literal" forcing the type of "literal" to be the same as that of "column" will now usually not occur - the type of "literal" is first derived from the Python type of the literal, assuming standard native Python types + date types, before falling back to that of the known type on the other side of the expression. Also part of [ticket:1683]. --- lib/sqlalchemy/sql/util.py | 86 ---------------------------------------------- 1 file changed, 86 deletions(-) (limited to 'lib/sqlalchemy/sql/util.py') diff --git a/lib/sqlalchemy/sql/util.py b/lib/sqlalchemy/sql/util.py index 821b3a3d1..43673eaec 100644 --- a/lib/sqlalchemy/sql/util.py +++ b/lib/sqlalchemy/sql/util.py @@ -46,92 +46,6 @@ def find_join_source(clauses, join_to): else: return None, None -_date_affinities = None -def determine_date_affinity(expr): - """Given an expression, determine if it returns 'interval', 'date', or 'datetime'. - - the PG dialect uses this to generate the extract() function. - - It's less than ideal since it basically needs to duplicate PG's - date arithmetic rules. - - Rules are based on http://www.postgresql.org/docs/current/static/functions-datetime.html. - - Returns None if operators other than + or - are detected as well as types - outside of those above. - - """ - - global _date_affinities - if _date_affinities is None: - Date, DateTime, Integer, \ - Numeric, Interval, Time = \ - sqltypes.Date, sqltypes.DateTime,\ - sqltypes.Integer, sqltypes.Numeric,\ - sqltypes.Interval, sqltypes.Time - - _date_affinities = { - operators.add:{ - (Date, Integer):Date, - (Date, Interval):DateTime, - (Date, Time):DateTime, - (Interval, Interval):Interval, - (DateTime, Interval):DateTime, - (Interval, Time):Time, - }, - operators.sub:{ - (Date, Integer):Date, - (Date, Interval):DateTime, - (Time, Time):Interval, - (Time, Interval):Time, - (DateTime, Interval):DateTime, - (Interval, Interval):Interval, - (DateTime, DateTime):Interval, - }, - operators.mul:{ - (Integer, Interval):Interval, - (Interval, Numeric):Interval, - }, - operators.div: { - (Interval, Numeric):Interval - } - } - - if isinstance(expr, expression._BinaryExpression): - if expr.operator not in _date_affinities: - return None - - left_affin, right_affin = \ - determine_date_affinity(expr.left), \ - determine_date_affinity(expr.right) - - if left_affin is None or right_affin is None: - return None - - if operators.is_commutative(expr.operator): - key = tuple(sorted([left_affin, right_affin], key=lambda cls:cls.__name__)) - else: - key = (left_affin, right_affin) - - lookup = _date_affinities[expr.operator] - return lookup.get(key, None) - - # work around the fact that expressions put the wrong type - # on generated bind params when its "datetime + timedelta" - # and similar - if isinstance(expr, expression._BindParamClause): - type_ = sqltypes.type_map.get(type(expr.value), sqltypes.NullType)() - else: - type_ = expr.type - - affinities = set([sqltypes.Date, sqltypes.DateTime, - sqltypes.Interval, sqltypes.Time, sqltypes.Integer]) - - if type_ is not None and type_._type_affinity in affinities: - return type_._type_affinity - else: - return None - def find_tables(clause, check_columns=False, -- cgit v1.2.1