summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-02-07 00:56:05 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2010-02-07 00:56:05 +0000
commit1c73149d5dd477ae882890e155e87f5dd9e4853f (patch)
tree1433f2fa80a06b2619f6aea5f12f0018572861a6
parent54df3ee2ab1052533f49e596d902d597eb140c52 (diff)
downloadsqlalchemy-1c73149d5dd477ae882890e155e87f5dd9e4853f.tar.gz
- FunctionElement subclasses are now directly executable the
same way any func.foo() construct is, with automatic SELECT being applied when passed to execute(). - The "type" and "bind" keyword arguments of a func.foo() construct are now local to "func." constructs and are not part of the FunctionElement base class, allowing a "type" to be handled in a custom constructor or class-level variable.
-rw-r--r--CHANGES12
-rw-r--r--lib/sqlalchemy/engine/base.py2
-rw-r--r--lib/sqlalchemy/sql/expression.py7
-rw-r--r--test/sql/test_functions.py15
4 files changed, 29 insertions, 7 deletions
diff --git a/CHANGES b/CHANGES
index e3f22b1ab..d88a6bfdc 100644
--- a/CHANGES
+++ b/CHANGES
@@ -20,7 +20,17 @@ CHANGES
- sql
- Added math negation operator support, -x.
-
+
+ - FunctionElement subclasses are now directly executable the
+ same way any func.foo() construct is, with automatic
+ SELECT being applied when passed to execute().
+
+ - The "type" and "bind" keyword arguments of a func.foo()
+ construct are now local to "func." constructs and are
+ not part of the FunctionElement base class, allowing
+ a "type" to be handled in a custom constructor or
+ class-level variable.
+
- mssql
- Re-established initial support for pymssql.
diff --git a/lib/sqlalchemy/engine/base.py b/lib/sqlalchemy/engine/base.py
index 6a4fa5d08..98d06a792 100644
--- a/lib/sqlalchemy/engine/base.py
+++ b/lib/sqlalchemy/engine/base.py
@@ -1194,7 +1194,7 @@ class Connection(Connectable):
# poor man's multimethod/generic function thingy
executors = {
- expression.Function: _execute_function,
+ expression.FunctionElement: _execute_function,
expression.ClauseElement: _execute_clauseelement,
Compiled: _execute_compiled,
schema.SchemaItem: _execute_default,
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 89137d2ce..878b0d826 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -2481,15 +2481,13 @@ class _Case(ColumnElement):
class FunctionElement(ColumnElement, FromClause):
"""Base for SQL function-oriented constructs."""
-
+
def __init__(self, *clauses, **kwargs):
- self._bind = kwargs.get('bind', None)
args = [_literal_as_binds(c, self.name) for c in clauses]
self.clause_expr = ClauseList(
operator=operators.comma_op,
group_contents=True, *args).\
self_group()
- self.type = sqltypes.to_instance(kwargs.get('type_', None))
@property
def columns(self):
@@ -2535,6 +2533,9 @@ class Function(FunctionElement):
def __init__(self, name, *clauses, **kw):
self.packagenames = kw.pop('packagenames', None) or []
self.name = name
+ self._bind = kw.get('bind', None)
+ self.type = sqltypes.to_instance(kw.get('type_', None))
+
FunctionElement.__init__(self, *clauses, **kw)
def _bind_param(self, obj):
diff --git a/test/sql/test_functions.py b/test/sql/test_functions.py
index 7a0f12cac..e6bcd2680 100644
--- a/test/sql/test_functions.py
+++ b/test/sql/test_functions.py
@@ -196,15 +196,26 @@ class ExecuteTest(TestBase):
assert isinstance(x.execute().scalar(), datetime.date)
def test_conn_execute(self):
+ from sqlalchemy.sql.expression import FunctionElement
+ from sqlalchemy.ext.compiler import compiles
+
+ class myfunc(FunctionElement):
+ type = DATE()
+
+ @compiles(myfunc)
+ def compile(elem, compiler, **kw):
+ return compiler.process(func.current_date())
+
conn = testing.db.connect()
try:
x = conn.execute(func.current_date()).scalar()
y = conn.execute(func.current_date().select()).scalar()
z = conn.scalar(func.current_date())
+ q = conn.scalar(myfunc())
finally:
conn.close()
- assert (x == y == z) is True
-
+ assert (x == y == z == q) is True
+
@engines.close_first
def test_update(self):
"""