]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- FunctionElement subclasses are now directly executable the
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 7 Feb 2010 00:56:05 +0000 (00:56 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 7 Feb 2010 00:56:05 +0000 (00:56 +0000)
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.

CHANGES
lib/sqlalchemy/engine/base.py
lib/sqlalchemy/sql/expression.py
test/sql/test_functions.py

diff --git a/CHANGES b/CHANGES
index e3f22b1ab2f26b635460d2e2b1cda344a843d80f..d88a6bfdc8a8bcd824430ffee5e4e7b35fb6a830 100644 (file)
--- 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.
   
index 6a4fa5d08ed724d1c4e77e9aca505708a70285f9..98d06a792fece203c62e08dd2596d6525564ecf7 100644 (file)
@@ -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,
index 89137d2ce0f82de9d928f803a810ebd057ea7130..878b0d82653a44b475b4caf7779a36fa74c083f7 100644 (file)
@@ -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):
index 7a0f12cac30a83d61749211be2245d98aa5e5fef..e6bcd2680dcb85a437cfbcb93f337838039d3729 100644 (file)
@@ -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):
         """