functions.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. # sql/functions.py
  2. # Copyright (C) 2005-2017 the SQLAlchemy authors and contributors
  3. # <see AUTHORS file>
  4. #
  5. # This module is part of SQLAlchemy and is released under
  6. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  7. """SQL function API, factories, and built-in functions.
  8. """
  9. from . import sqltypes, schema
  10. from .base import Executable, ColumnCollection
  11. from .elements import ClauseList, Cast, Extract, _literal_as_binds, \
  12. literal_column, _type_from_args, ColumnElement, _clone,\
  13. Over, BindParameter, FunctionFilter, Grouping, WithinGroup
  14. from .selectable import FromClause, Select, Alias
  15. from . import util as sqlutil
  16. from . import operators
  17. from .visitors import VisitableType
  18. from .. import util
  19. from . import annotation
  20. _registry = util.defaultdict(dict)
  21. def register_function(identifier, fn, package="_default"):
  22. """Associate a callable with a particular func. name.
  23. This is normally called by _GenericMeta, but is also
  24. available by itself so that a non-Function construct
  25. can be associated with the :data:`.func` accessor (i.e.
  26. CAST, EXTRACT).
  27. """
  28. reg = _registry[package]
  29. reg[identifier] = fn
  30. class FunctionElement(Executable, ColumnElement, FromClause):
  31. """Base for SQL function-oriented constructs.
  32. .. seealso::
  33. :class:`.Function` - named SQL function.
  34. :data:`.func` - namespace which produces registered or ad-hoc
  35. :class:`.Function` instances.
  36. :class:`.GenericFunction` - allows creation of registered function
  37. types.
  38. """
  39. packagenames = ()
  40. def __init__(self, *clauses, **kwargs):
  41. """Construct a :class:`.FunctionElement`.
  42. """
  43. args = [_literal_as_binds(c, self.name) for c in clauses]
  44. self.clause_expr = ClauseList(
  45. operator=operators.comma_op,
  46. group_contents=True, *args).\
  47. self_group()
  48. def _execute_on_connection(self, connection, multiparams, params):
  49. return connection._execute_function(self, multiparams, params)
  50. @property
  51. def columns(self):
  52. """The set of columns exported by this :class:`.FunctionElement`.
  53. Function objects currently have no result column names built in;
  54. this method returns a single-element column collection with
  55. an anonymously named column.
  56. An interim approach to providing named columns for a function
  57. as a FROM clause is to build a :func:`.select` with the
  58. desired columns::
  59. from sqlalchemy.sql import column
  60. stmt = select([column('x'), column('y')]).\
  61. select_from(func.myfunction())
  62. """
  63. return ColumnCollection(self.label(None))
  64. @util.memoized_property
  65. def clauses(self):
  66. """Return the underlying :class:`.ClauseList` which contains
  67. the arguments for this :class:`.FunctionElement`.
  68. """
  69. return self.clause_expr.element
  70. def over(self, partition_by=None, order_by=None, rows=None, range_=None):
  71. """Produce an OVER clause against this function.
  72. Used against aggregate or so-called "window" functions,
  73. for database backends that support window functions.
  74. The expression::
  75. func.row_number().over(order_by='x')
  76. is shorthand for::
  77. from sqlalchemy import over
  78. over(func.row_number(), order_by='x')
  79. See :func:`~.expression.over` for a full description.
  80. .. versionadded:: 0.7
  81. """
  82. return Over(
  83. self,
  84. partition_by=partition_by,
  85. order_by=order_by,
  86. rows=rows,
  87. range_=range_
  88. )
  89. def within_group(self, *order_by):
  90. """Produce a WITHIN GROUP (ORDER BY expr) clause against this function.
  91. Used against so-called "ordered set aggregate" and "hypothetical
  92. set aggregate" functions, including :class:`.percentile_cont`,
  93. :class:`.rank`, :class:`.dense_rank`, etc.
  94. See :func:`~.expression.within_group` for a full description.
  95. .. versionadded:: 1.1
  96. """
  97. return WithinGroup(self, *order_by)
  98. def filter(self, *criterion):
  99. """Produce a FILTER clause against this function.
  100. Used against aggregate and window functions,
  101. for database backends that support the "FILTER" clause.
  102. The expression::
  103. func.count(1).filter(True)
  104. is shorthand for::
  105. from sqlalchemy import funcfilter
  106. funcfilter(func.count(1), True)
  107. .. versionadded:: 1.0.0
  108. .. seealso::
  109. :class:`.FunctionFilter`
  110. :func:`.funcfilter`
  111. """
  112. if not criterion:
  113. return self
  114. return FunctionFilter(self, *criterion)
  115. @property
  116. def _from_objects(self):
  117. return self.clauses._from_objects
  118. def get_children(self, **kwargs):
  119. return self.clause_expr,
  120. def _copy_internals(self, clone=_clone, **kw):
  121. self.clause_expr = clone(self.clause_expr, **kw)
  122. self._reset_exported()
  123. FunctionElement.clauses._reset(self)
  124. def within_group_type(self, within_group):
  125. """For types that define their return type as based on the criteria
  126. within a WITHIN GROUP (ORDER BY) expression, called by the
  127. :class:`.WithinGroup` construct.
  128. Returns None by default, in which case the function's normal ``.type``
  129. is used.
  130. """
  131. return None
  132. def alias(self, name=None, flat=False):
  133. r"""Produce a :class:`.Alias` construct against this
  134. :class:`.FunctionElement`.
  135. This construct wraps the function in a named alias which
  136. is suitable for the FROM clause, in the style accepted for example
  137. by PostgreSQL.
  138. e.g.::
  139. from sqlalchemy.sql import column
  140. stmt = select([column('data_view')]).\
  141. select_from(SomeTable).\
  142. select_from(func.unnest(SomeTable.data).alias('data_view')
  143. )
  144. Would produce:
  145. .. sourcecode:: sql
  146. SELECT data_view
  147. FROM sometable, unnest(sometable.data) AS data_view
  148. .. versionadded:: 0.9.8 The :meth:`.FunctionElement.alias` method
  149. is now supported. Previously, this method's behavior was
  150. undefined and did not behave consistently across versions.
  151. """
  152. return Alias(self, name)
  153. def select(self):
  154. """Produce a :func:`~.expression.select` construct
  155. against this :class:`.FunctionElement`.
  156. This is shorthand for::
  157. s = select([function_element])
  158. """
  159. s = Select([self])
  160. if self._execution_options:
  161. s = s.execution_options(**self._execution_options)
  162. return s
  163. def scalar(self):
  164. """Execute this :class:`.FunctionElement` against an embedded
  165. 'bind' and return a scalar value.
  166. This first calls :meth:`~.FunctionElement.select` to
  167. produce a SELECT construct.
  168. Note that :class:`.FunctionElement` can be passed to
  169. the :meth:`.Connectable.scalar` method of :class:`.Connection`
  170. or :class:`.Engine`.
  171. """
  172. return self.select().execute().scalar()
  173. def execute(self):
  174. """Execute this :class:`.FunctionElement` against an embedded
  175. 'bind'.
  176. This first calls :meth:`~.FunctionElement.select` to
  177. produce a SELECT construct.
  178. Note that :class:`.FunctionElement` can be passed to
  179. the :meth:`.Connectable.execute` method of :class:`.Connection`
  180. or :class:`.Engine`.
  181. """
  182. return self.select().execute()
  183. def _bind_param(self, operator, obj, type_=None):
  184. return BindParameter(None, obj, _compared_to_operator=operator,
  185. _compared_to_type=self.type, unique=True,
  186. type_=type_)
  187. def self_group(self, against=None):
  188. # for the moment, we are parenthesizing all array-returning
  189. # expressions against getitem. This may need to be made
  190. # more portable if in the future we support other DBs
  191. # besides postgresql.
  192. if against is operators.getitem and \
  193. isinstance(self.type, sqltypes.ARRAY):
  194. return Grouping(self)
  195. else:
  196. return super(FunctionElement, self).self_group(against=against)
  197. class _FunctionGenerator(object):
  198. """Generate :class:`.Function` objects based on getattr calls."""
  199. def __init__(self, **opts):
  200. self.__names = []
  201. self.opts = opts
  202. def __getattr__(self, name):
  203. # passthru __ attributes; fixes pydoc
  204. if name.startswith('__'):
  205. try:
  206. return self.__dict__[name]
  207. except KeyError:
  208. raise AttributeError(name)
  209. elif name.endswith('_'):
  210. name = name[0:-1]
  211. f = _FunctionGenerator(**self.opts)
  212. f.__names = list(self.__names) + [name]
  213. return f
  214. def __call__(self, *c, **kwargs):
  215. o = self.opts.copy()
  216. o.update(kwargs)
  217. tokens = len(self.__names)
  218. if tokens == 2:
  219. package, fname = self.__names
  220. elif tokens == 1:
  221. package, fname = "_default", self.__names[0]
  222. else:
  223. package = None
  224. if package is not None:
  225. func = _registry[package].get(fname)
  226. if func is not None:
  227. return func(*c, **o)
  228. return Function(self.__names[-1],
  229. packagenames=self.__names[0:-1], *c, **o)
  230. func = _FunctionGenerator()
  231. """Generate SQL function expressions.
  232. :data:`.func` is a special object instance which generates SQL
  233. functions based on name-based attributes, e.g.::
  234. >>> print(func.count(1))
  235. count(:param_1)
  236. The element is a column-oriented SQL element like any other, and is
  237. used in that way::
  238. >>> print(select([func.count(table.c.id)]))
  239. SELECT count(sometable.id) FROM sometable
  240. Any name can be given to :data:`.func`. If the function name is unknown to
  241. SQLAlchemy, it will be rendered exactly as is. For common SQL functions
  242. which SQLAlchemy is aware of, the name may be interpreted as a *generic
  243. function* which will be compiled appropriately to the target database::
  244. >>> print(func.current_timestamp())
  245. CURRENT_TIMESTAMP
  246. To call functions which are present in dot-separated packages,
  247. specify them in the same manner::
  248. >>> print(func.stats.yield_curve(5, 10))
  249. stats.yield_curve(:yield_curve_1, :yield_curve_2)
  250. SQLAlchemy can be made aware of the return type of functions to enable
  251. type-specific lexical and result-based behavior. For example, to ensure
  252. that a string-based function returns a Unicode value and is similarly
  253. treated as a string in expressions, specify
  254. :class:`~sqlalchemy.types.Unicode` as the type:
  255. >>> print(func.my_string(u'hi', type_=Unicode) + ' ' +
  256. ... func.my_string(u'there', type_=Unicode))
  257. my_string(:my_string_1) || :my_string_2 || my_string(:my_string_3)
  258. The object returned by a :data:`.func` call is usually an instance of
  259. :class:`.Function`.
  260. This object meets the "column" interface, including comparison and labeling
  261. functions. The object can also be passed the :meth:`~.Connectable.execute`
  262. method of a :class:`.Connection` or :class:`.Engine`, where it will be
  263. wrapped inside of a SELECT statement first::
  264. print(connection.execute(func.current_timestamp()).scalar())
  265. In a few exception cases, the :data:`.func` accessor
  266. will redirect a name to a built-in expression such as :func:`.cast`
  267. or :func:`.extract`, as these names have well-known meaning
  268. but are not exactly the same as "functions" from a SQLAlchemy
  269. perspective.
  270. .. versionadded:: 0.8 :data:`.func` can return non-function expression
  271. constructs for common quasi-functional names like :func:`.cast`
  272. and :func:`.extract`.
  273. Functions which are interpreted as "generic" functions know how to
  274. calculate their return type automatically. For a listing of known generic
  275. functions, see :ref:`generic_functions`.
  276. .. note::
  277. The :data:`.func` construct has only limited support for calling
  278. standalone "stored procedures", especially those with special
  279. parameterization concerns.
  280. See the section :ref:`stored_procedures` for details on how to use
  281. the DBAPI-level ``callproc()`` method for fully traditional stored
  282. procedures.
  283. """
  284. modifier = _FunctionGenerator(group=False)
  285. class Function(FunctionElement):
  286. """Describe a named SQL function.
  287. See the superclass :class:`.FunctionElement` for a description
  288. of public methods.
  289. .. seealso::
  290. :data:`.func` - namespace which produces registered or ad-hoc
  291. :class:`.Function` instances.
  292. :class:`.GenericFunction` - allows creation of registered function
  293. types.
  294. """
  295. __visit_name__ = 'function'
  296. def __init__(self, name, *clauses, **kw):
  297. """Construct a :class:`.Function`.
  298. The :data:`.func` construct is normally used to construct
  299. new :class:`.Function` instances.
  300. """
  301. self.packagenames = kw.pop('packagenames', None) or []
  302. self.name = name
  303. self._bind = kw.get('bind', None)
  304. self.type = sqltypes.to_instance(kw.get('type_', None))
  305. FunctionElement.__init__(self, *clauses, **kw)
  306. def _bind_param(self, operator, obj, type_=None):
  307. return BindParameter(self.name, obj,
  308. _compared_to_operator=operator,
  309. _compared_to_type=self.type,
  310. type_=type_,
  311. unique=True)
  312. class _GenericMeta(VisitableType):
  313. def __init__(cls, clsname, bases, clsdict):
  314. if annotation.Annotated not in cls.__mro__:
  315. cls.name = name = clsdict.get('name', clsname)
  316. cls.identifier = identifier = clsdict.get('identifier', name)
  317. package = clsdict.pop('package', '_default')
  318. # legacy
  319. if '__return_type__' in clsdict:
  320. cls.type = clsdict['__return_type__']
  321. register_function(identifier, cls, package)
  322. super(_GenericMeta, cls).__init__(clsname, bases, clsdict)
  323. class GenericFunction(util.with_metaclass(_GenericMeta, Function)):
  324. """Define a 'generic' function.
  325. A generic function is a pre-established :class:`.Function`
  326. class that is instantiated automatically when called
  327. by name from the :data:`.func` attribute. Note that
  328. calling any name from :data:`.func` has the effect that
  329. a new :class:`.Function` instance is created automatically,
  330. given that name. The primary use case for defining
  331. a :class:`.GenericFunction` class is so that a function
  332. of a particular name may be given a fixed return type.
  333. It can also include custom argument parsing schemes as well
  334. as additional methods.
  335. Subclasses of :class:`.GenericFunction` are automatically
  336. registered under the name of the class. For
  337. example, a user-defined function ``as_utc()`` would
  338. be available immediately::
  339. from sqlalchemy.sql.functions import GenericFunction
  340. from sqlalchemy.types import DateTime
  341. class as_utc(GenericFunction):
  342. type = DateTime
  343. print select([func.as_utc()])
  344. User-defined generic functions can be organized into
  345. packages by specifying the "package" attribute when defining
  346. :class:`.GenericFunction`. Third party libraries
  347. containing many functions may want to use this in order
  348. to avoid name conflicts with other systems. For example,
  349. if our ``as_utc()`` function were part of a package
  350. "time"::
  351. class as_utc(GenericFunction):
  352. type = DateTime
  353. package = "time"
  354. The above function would be available from :data:`.func`
  355. using the package name ``time``::
  356. print select([func.time.as_utc()])
  357. A final option is to allow the function to be accessed
  358. from one name in :data:`.func` but to render as a different name.
  359. The ``identifier`` attribute will override the name used to
  360. access the function as loaded from :data:`.func`, but will retain
  361. the usage of ``name`` as the rendered name::
  362. class GeoBuffer(GenericFunction):
  363. type = Geometry
  364. package = "geo"
  365. name = "ST_Buffer"
  366. identifier = "buffer"
  367. The above function will render as follows::
  368. >>> print func.geo.buffer()
  369. ST_Buffer()
  370. .. versionadded:: 0.8 :class:`.GenericFunction` now supports
  371. automatic registration of new functions as well as package
  372. and custom naming support.
  373. .. versionchanged:: 0.8 The attribute name ``type`` is used
  374. to specify the function's return type at the class level.
  375. Previously, the name ``__return_type__`` was used. This
  376. name is still recognized for backwards-compatibility.
  377. """
  378. coerce_arguments = True
  379. def __init__(self, *args, **kwargs):
  380. parsed_args = kwargs.pop('_parsed_args', None)
  381. if parsed_args is None:
  382. parsed_args = [_literal_as_binds(c, self.name) for c in args]
  383. self.packagenames = []
  384. self._bind = kwargs.get('bind', None)
  385. self.clause_expr = ClauseList(
  386. operator=operators.comma_op,
  387. group_contents=True, *parsed_args).self_group()
  388. self.type = sqltypes.to_instance(
  389. kwargs.pop("type_", None) or getattr(self, 'type', None))
  390. register_function("cast", Cast)
  391. register_function("extract", Extract)
  392. class next_value(GenericFunction):
  393. """Represent the 'next value', given a :class:`.Sequence`
  394. as its single argument.
  395. Compiles into the appropriate function on each backend,
  396. or will raise NotImplementedError if used on a backend
  397. that does not provide support for sequences.
  398. """
  399. type = sqltypes.Integer()
  400. name = "next_value"
  401. def __init__(self, seq, **kw):
  402. assert isinstance(seq, schema.Sequence), \
  403. "next_value() accepts a Sequence object as input."
  404. self._bind = kw.get('bind', None)
  405. self.sequence = seq
  406. @property
  407. def _from_objects(self):
  408. return []
  409. class AnsiFunction(GenericFunction):
  410. def __init__(self, **kwargs):
  411. GenericFunction.__init__(self, **kwargs)
  412. class ReturnTypeFromArgs(GenericFunction):
  413. """Define a function whose return type is the same as its arguments."""
  414. def __init__(self, *args, **kwargs):
  415. args = [_literal_as_binds(c, self.name) for c in args]
  416. kwargs.setdefault('type_', _type_from_args(args))
  417. kwargs['_parsed_args'] = args
  418. super(ReturnTypeFromArgs, self).__init__(*args, **kwargs)
  419. class coalesce(ReturnTypeFromArgs):
  420. pass
  421. class max(ReturnTypeFromArgs):
  422. pass
  423. class min(ReturnTypeFromArgs):
  424. pass
  425. class sum(ReturnTypeFromArgs):
  426. pass
  427. class now(GenericFunction):
  428. type = sqltypes.DateTime
  429. class concat(GenericFunction):
  430. type = sqltypes.String
  431. class char_length(GenericFunction):
  432. type = sqltypes.Integer
  433. def __init__(self, arg, **kwargs):
  434. GenericFunction.__init__(self, arg, **kwargs)
  435. class random(GenericFunction):
  436. pass
  437. class count(GenericFunction):
  438. r"""The ANSI COUNT aggregate function. With no arguments,
  439. emits COUNT \*.
  440. """
  441. type = sqltypes.Integer
  442. def __init__(self, expression=None, **kwargs):
  443. if expression is None:
  444. expression = literal_column('*')
  445. super(count, self).__init__(expression, **kwargs)
  446. class current_date(AnsiFunction):
  447. type = sqltypes.Date
  448. class current_time(AnsiFunction):
  449. type = sqltypes.Time
  450. class current_timestamp(AnsiFunction):
  451. type = sqltypes.DateTime
  452. class current_user(AnsiFunction):
  453. type = sqltypes.String
  454. class localtime(AnsiFunction):
  455. type = sqltypes.DateTime
  456. class localtimestamp(AnsiFunction):
  457. type = sqltypes.DateTime
  458. class session_user(AnsiFunction):
  459. type = sqltypes.String
  460. class sysdate(AnsiFunction):
  461. type = sqltypes.DateTime
  462. class user(AnsiFunction):
  463. type = sqltypes.String
  464. class array_agg(GenericFunction):
  465. """support for the ARRAY_AGG function.
  466. The ``func.array_agg(expr)`` construct returns an expression of
  467. type :class:`.types.ARRAY`.
  468. e.g.::
  469. stmt = select([func.array_agg(table.c.values)[2:5]])
  470. .. versionadded:: 1.1
  471. .. seealso::
  472. :func:`.postgresql.array_agg` - PostgreSQL-specific version that
  473. returns :class:`.postgresql.ARRAY`, which has PG-specific operators added.
  474. """
  475. type = sqltypes.ARRAY
  476. def __init__(self, *args, **kwargs):
  477. args = [_literal_as_binds(c) for c in args]
  478. kwargs.setdefault('type_', self.type(_type_from_args(args)))
  479. kwargs['_parsed_args'] = args
  480. super(array_agg, self).__init__(*args, **kwargs)
  481. class OrderedSetAgg(GenericFunction):
  482. """Define a function where the return type is based on the sort
  483. expression type as defined by the expression passed to the
  484. :meth:`.FunctionElement.within_group` method."""
  485. array_for_multi_clause = False
  486. def within_group_type(self, within_group):
  487. func_clauses = self.clause_expr.element
  488. order_by = sqlutil.unwrap_order_by(within_group.order_by)
  489. if self.array_for_multi_clause and len(func_clauses.clauses) > 1:
  490. return sqltypes.ARRAY(order_by[0].type)
  491. else:
  492. return order_by[0].type
  493. class mode(OrderedSetAgg):
  494. """implement the ``mode`` ordered-set aggregate function.
  495. This function must be used with the :meth:`.FunctionElement.within_group`
  496. modifier to supply a sort expression to operate upon.
  497. The return type of this function is the same as the sort expression.
  498. .. versionadded:: 1.1
  499. """
  500. class percentile_cont(OrderedSetAgg):
  501. """implement the ``percentile_cont`` ordered-set aggregate function.
  502. This function must be used with the :meth:`.FunctionElement.within_group`
  503. modifier to supply a sort expression to operate upon.
  504. The return type of this function is the same as the sort expression,
  505. or if the arguments are an array, an :class:`.types.ARRAY` of the sort
  506. expression's type.
  507. .. versionadded:: 1.1
  508. """
  509. array_for_multi_clause = True
  510. class percentile_disc(OrderedSetAgg):
  511. """implement the ``percentile_disc`` ordered-set aggregate function.
  512. This function must be used with the :meth:`.FunctionElement.within_group`
  513. modifier to supply a sort expression to operate upon.
  514. The return type of this function is the same as the sort expression,
  515. or if the arguments are an array, an :class:`.types.ARRAY` of the sort
  516. expression's type.
  517. .. versionadded:: 1.1
  518. """
  519. array_for_multi_clause = True
  520. class rank(GenericFunction):
  521. """Implement the ``rank`` hypothetical-set aggregate function.
  522. This function must be used with the :meth:`.FunctionElement.within_group`
  523. modifier to supply a sort expression to operate upon.
  524. The return type of this function is :class:`.Integer`.
  525. .. versionadded:: 1.1
  526. """
  527. type = sqltypes.Integer()
  528. class dense_rank(GenericFunction):
  529. """Implement the ``dense_rank`` hypothetical-set aggregate function.
  530. This function must be used with the :meth:`.FunctionElement.within_group`
  531. modifier to supply a sort expression to operate upon.
  532. The return type of this function is :class:`.Integer`.
  533. .. versionadded:: 1.1
  534. """
  535. type = sqltypes.Integer()
  536. class percent_rank(GenericFunction):
  537. """Implement the ``percent_rank`` hypothetical-set aggregate function.
  538. This function must be used with the :meth:`.FunctionElement.within_group`
  539. modifier to supply a sort expression to operate upon.
  540. The return type of this function is :class:`.Numeric`.
  541. .. versionadded:: 1.1
  542. """
  543. type = sqltypes.Numeric()
  544. class cume_dist(GenericFunction):
  545. """Implement the ``cume_dist`` hypothetical-set aggregate function.
  546. This function must be used with the :meth:`.FunctionElement.within_group`
  547. modifier to supply a sort expression to operate upon.
  548. The return type of this function is :class:`.Numeric`.
  549. .. versionadded:: 1.1
  550. """
  551. type = sqltypes.Numeric()