Commits

jason kirtland committed 4d5d2f2

- func.count() with no argument emits COUNT(*)

Comments (0)

Files changed (3)

       should reduce the probability of "Attribute x was 
       not replaced during compile" warnings. (this generally
       applies to SQLA hackers, like Elixir devs).
-      
+
+- sql
+    - func.count() with no arguments renders as COUNT(*),
+      equivalent to func.count(text('*')). 
+ 
 - ext
     - Class-bound attributes sent as arguments to 
       relation()'s remote_side and foreign_keys parameters 

lib/sqlalchemy/sql/functions.py

 from sqlalchemy import types as sqltypes
 from sqlalchemy.sql.expression import (
-    ClauseList, _FigureVisitName, _Function, _literal_as_binds,
+    ClauseList, _FigureVisitName, _Function, _literal_as_binds, text
     )
 from sqlalchemy.sql import operators
 
         kwargs.setdefault('type_', None)
         GenericFunction.__init__(self, args=args, **kwargs)
 
+class count(GenericFunction):
+    """The ANSI COUNT aggregate function.  With no arguments, emits COUNT *."""
+
+    __return_type__ = sqltypes.Integer
+
+    def __init__(self, expression=None, **kwargs):
+        if expression is None:
+            expression = text('*')
+        GenericFunction.__init__(self, args=(expression,), **kwargs)
+
 class current_date(AnsiFunction):
     __return_type__ = sqltypes.Date
 

test/sql/functions.py

 from sqlalchemy import types as sqltypes
 from testlib import *
 from sqlalchemy.sql.functions import GenericFunction
+from testlib.testing import eq_
 
 from sqlalchemy.databases import *
 # every dialect in databases.__all__ is expected to pass these tests.
         ]:
             self.assert_compile(func.random(), ret, dialect=dialect)
 
+    def test_generic_count(self):
+        assert isinstance(func.count().type, sqltypes.Integer)
+
+        self.assert_compile(func.count(), 'count(*)')
+        self.assert_compile(func.count(1), 'count(:param_1)')
+        c = column('abc')
+        self.assert_compile(func.count(c), 'count(abc)')
+
     def test_constructor(self):
         try:
             func.current_timestamp('somearg')