diff options
author | Jason Kirtland <jek@discorporate.us> | 2009-03-30 20:41:48 +0000 |
---|---|---|
committer | Jason Kirtland <jek@discorporate.us> | 2009-03-30 20:41:48 +0000 |
commit | aca84bebb091a51ceeb911249c366e17b954826a (patch) | |
tree | 87a0424805905c9fdae0ab6930144c91b9a78ff6 /lib/sqlalchemy/sql | |
parent | 1ad157a0a1823706ffb43ee7d235c38ae16f46ff (diff) | |
download | sqlalchemy-aca84bebb091a51ceeb911249c366e17b954826a.tar.gz |
extract() is now dialect-sensitive and supports SQLite and others.
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r-- | lib/sqlalchemy/sql/compiler.py | 22 | ||||
-rw-r--r-- | lib/sqlalchemy/sql/expression.py | 24 |
2 files changed, 44 insertions, 2 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 3a982f23c..5042959b2 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -108,6 +108,23 @@ FUNCTIONS = { functions.user: 'USER' } +EXTRACT_MAP = { + 'month': 'month', + 'day': 'day', + 'year': 'year', + 'second': 'second', + 'hour': 'hour', + 'doy': 'doy', + 'minute': 'minute', + 'quarter': 'quarter', + 'dow': 'dow', + 'week': 'week', + 'epoch': 'epoch', + 'milliseconds': 'milliseconds', + 'microseconds': 'microseconds', + 'timezone_hour': 'timezone_hour', + 'timezone_minute': 'timezone_minute' +} class _CompileLabel(visitors.Visitable): """lightweight label object which acts as an expression._Label.""" @@ -133,6 +150,7 @@ class DefaultCompiler(engine.Compiled): operators = OPERATORS functions = FUNCTIONS + extract_map = EXTRACT_MAP # if we are insert/update/delete. # set to true when we visit an INSERT, UPDATE or DELETE @@ -346,6 +364,10 @@ class DefaultCompiler(engine.Compiled): def visit_cast(self, cast, **kwargs): return "CAST(%s AS %s)" % (self.process(cast.clause), self.process(cast.typeclause)) + def visit_extract(self, extract, **kwargs): + field = self.extract_map.get(extract.field, extract.field) + return "EXTRACT(%s FROM %s)" % (field, self.process(extract.expr)) + def visit_function(self, func, result_map=None, **kwargs): if result_map is not None: result_map[func.name.lower()] = (func.name, None, func.type) diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py index 5a0d5b043..56f358db8 100644 --- a/lib/sqlalchemy/sql/expression.py +++ b/lib/sqlalchemy/sql/expression.py @@ -484,8 +484,7 @@ def cast(clause, totype, **kwargs): def extract(field, expr): """Return the clause ``extract(field FROM expr)``.""" - expr = _BinaryExpression(text(field), expr, operators.from_) - return func.extract(expr) + return _Extract(field, expr) def collate(expression, collation): """Return the clause ``expression COLLATE collation``.""" @@ -2313,6 +2312,27 @@ class _Cast(ColumnElement): return self.clause._from_objects +class _Extract(ColumnElement): + + __visit_name__ = 'extract' + + def __init__(self, field, expr, **kwargs): + self.type = sqltypes.Integer() + self.field = field + self.expr = _literal_as_binds(expr, None) + + def _copy_internals(self, clone=_clone): + self.field = clone(self.field) + self.expr = clone(self.expr) + + def get_children(self, **kwargs): + return self.field, self.expr + + @property + def _from_objects(self): + return self.expr._from_objects + + class _UnaryExpression(ColumnElement): __visit_name__ = 'unary' |