1# sql/functions.py
2# Copyright (C) 2005-2026 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: https://www.opensource.org/licenses/mit-license.php
7
8"""SQL function API, factories, and built-in functions."""
9
10from __future__ import annotations
11
12import datetime
13import decimal
14from typing import Any
15from typing import cast
16from typing import Dict
17from typing import List
18from typing import Mapping
19from typing import Optional
20from typing import overload
21from typing import Sequence
22from typing import Tuple
23from typing import Type
24from typing import TYPE_CHECKING
25from typing import TypeVar
26from typing import Union
27
28from . import annotation
29from . import coercions
30from . import operators
31from . import roles
32from . import schema
33from . import sqltypes
34from . import type_api
35from . import util as sqlutil
36from ._typing import is_table_value_type
37from .base import _entity_namespace
38from .base import ColumnCollection
39from .base import Executable
40from .base import Generative
41from .base import HasMemoized
42from .elements import _type_from_args
43from .elements import BinaryExpression
44from .elements import BindParameter
45from .elements import Cast
46from .elements import ClauseList
47from .elements import ColumnElement
48from .elements import Extract
49from .elements import FunctionFilter
50from .elements import Grouping
51from .elements import literal_column
52from .elements import NamedColumn
53from .elements import Over
54from .elements import WithinGroup
55from .selectable import FromClause
56from .selectable import Select
57from .selectable import TableValuedAlias
58from .sqltypes import TableValueType
59from .type_api import TypeEngine
60from .visitors import InternalTraversal
61from .. import util
62
63
64if TYPE_CHECKING:
65 from ._typing import _ByArgument
66 from ._typing import _ColumnExpressionArgument
67 from ._typing import _ColumnExpressionOrLiteralArgument
68 from ._typing import _ColumnExpressionOrStrLabelArgument
69 from ._typing import _StarOrOne
70 from ._typing import _TypeEngineArgument
71 from .base import _EntityNamespace
72 from .elements import ClauseElement
73 from .elements import KeyedColumnElement
74 from .elements import TableValuedColumn
75 from .operators import OperatorType
76 from ..engine.base import Connection
77 from ..engine.cursor import CursorResult
78 from ..engine.interfaces import _CoreMultiExecuteParams
79 from ..engine.interfaces import CoreExecuteOptionsParameter
80 from ..util.typing import Self
81
82_T = TypeVar("_T", bound=Any)
83_S = TypeVar("_S", bound=Any)
84
85_registry: util.defaultdict[str, Dict[str, Type[Function[Any]]]] = (
86 util.defaultdict(dict)
87)
88
89
90def register_function(
91 identifier: str, fn: Type[Function[Any]], package: str = "_default"
92) -> None:
93 """Associate a callable with a particular func. name.
94
95 This is normally called by GenericFunction, but is also
96 available by itself so that a non-Function construct
97 can be associated with the :data:`.func` accessor (i.e.
98 CAST, EXTRACT).
99
100 """
101 reg = _registry[package]
102
103 identifier = str(identifier).lower()
104
105 # Check if a function with the same identifier is registered.
106 if identifier in reg:
107 util.warn(
108 "The GenericFunction '{}' is already registered and "
109 "is going to be overridden.".format(identifier)
110 )
111 reg[identifier] = fn
112
113
114class FunctionElement(Executable, ColumnElement[_T], FromClause, Generative):
115 """Base for SQL function-oriented constructs.
116
117 This is a `generic type <https://peps.python.org/pep-0484/#generics>`_,
118 meaning that type checkers and IDEs can be instructed on the types to
119 expect in a :class:`_engine.Result` for this function. See
120 :class:`.GenericFunction` for an example of how this is done.
121
122 .. seealso::
123
124 :ref:`tutorial_functions` - in the :ref:`unified_tutorial`
125
126 :class:`.Function` - named SQL function.
127
128 :data:`.func` - namespace which produces registered or ad-hoc
129 :class:`.Function` instances.
130
131 :class:`.GenericFunction` - allows creation of registered function
132 types.
133
134 """
135
136 _traverse_internals = [
137 ("clause_expr", InternalTraversal.dp_clauseelement),
138 ("_with_ordinality", InternalTraversal.dp_boolean),
139 ("_table_value_type", InternalTraversal.dp_has_cache_key),
140 ] + Executable._executable_traverse_internals
141
142 packagenames: Tuple[str, ...] = ()
143
144 _has_args = False
145 _with_ordinality = False
146 _table_value_type: Optional[TableValueType] = None
147
148 # some attributes that are defined between both ColumnElement and
149 # FromClause are set to Any here to avoid typing errors
150 primary_key: Any
151 _is_clone_of: Any
152
153 clause_expr: Grouping[Any]
154
155 def __init__(
156 self, *clauses: _ColumnExpressionOrLiteralArgument[Any]
157 ) -> None:
158 r"""Construct a :class:`.FunctionElement`.
159
160 :param \*clauses: list of column expressions that form the arguments
161 of the SQL function call.
162
163 :param \**kwargs: additional kwargs are typically consumed by
164 subclasses.
165
166 .. seealso::
167
168 :data:`.func`
169
170 :class:`.Function`
171
172 """
173 args: Sequence[_ColumnExpressionArgument[Any]] = [
174 coercions.expect(
175 roles.ExpressionElementRole,
176 c,
177 name=getattr(self, "name", None),
178 apply_propagate_attrs=self,
179 )
180 for c in clauses
181 ]
182 self._has_args = self._has_args or bool(args)
183 self.clause_expr = Grouping(
184 ClauseList(operator=operators.comma_op, group_contents=True, *args)
185 )
186
187 _non_anon_label = None
188
189 @property
190 def _proxy_key(self) -> Any:
191 return super()._proxy_key or getattr(self, "name", None)
192
193 def _execute_on_connection(
194 self,
195 connection: Connection,
196 distilled_params: _CoreMultiExecuteParams,
197 execution_options: CoreExecuteOptionsParameter,
198 ) -> CursorResult[Any]:
199 return connection._execute_function(
200 self, distilled_params, execution_options
201 )
202
203 def scalar_table_valued(
204 self, name: str, type_: Optional[_TypeEngineArgument[_T]] = None
205 ) -> ScalarFunctionColumn[_T]:
206 """Return a column expression that's against this
207 :class:`_functions.FunctionElement` as a scalar
208 table-valued expression.
209
210 The returned expression is similar to that returned by a single column
211 accessed off of a :meth:`_functions.FunctionElement.table_valued`
212 construct, except no FROM clause is generated; the function is rendered
213 in the similar way as a scalar subquery.
214
215 E.g.:
216
217 .. sourcecode:: pycon+sql
218
219 >>> from sqlalchemy import func, select
220 >>> fn = func.jsonb_each("{'k', 'v'}").scalar_table_valued("key")
221 >>> print(select(fn))
222 {printsql}SELECT (jsonb_each(:jsonb_each_1)).key
223
224 .. versionadded:: 1.4.0b2
225
226 .. seealso::
227
228 :meth:`_functions.FunctionElement.table_valued`
229
230 :meth:`_functions.FunctionElement.alias`
231
232 :meth:`_functions.FunctionElement.column_valued`
233
234 """ # noqa: E501
235
236 return ScalarFunctionColumn(self, name, type_)
237
238 def table_valued(
239 self, *expr: _ColumnExpressionOrStrLabelArgument[Any], **kw: Any
240 ) -> TableValuedAlias:
241 r"""Return a :class:`_sql.TableValuedAlias` representation of this
242 :class:`_functions.FunctionElement` with table-valued expressions added.
243
244 e.g. to use the SQLite form of ``generate_series()`` (including
245 hidden columns "start", "stop", "step"):
246
247 .. sourcecode:: pycon+sql
248
249 >>> fn = func.generate_series(1, 5).table_valued(
250 ... "value", "start", "stop", "step"
251 ... )
252
253 >>> print(select(fn))
254 {printsql}SELECT anon_1.value, anon_1.start, anon_1.stop, anon_1.step
255 FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1{stop}
256
257 >>> print(select(fn.c.value, fn.c.stop).where(fn.c.value > 2))
258 {printsql}SELECT anon_1.value, anon_1.stop
259 FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1
260 WHERE anon_1.value > :value_1{stop}
261
262 Backends like PostgreSQL need the accessed columns to be explicitly
263 named in "AS" clause. To achieve this, use
264 :meth:`_sql.TableValuedAlias.render_derived`; be sure to consult the
265 :ref:`PostgreSQL-specific documentation for table valued functions
266 <postgresql_table_valued>` for additional examples:
267
268 .. sourcecode:: pycon+sql
269
270 >>> fn = func.generate_series(1, 5).table_valued("value").render_derived()
271
272 >>> print(select(fn))
273 {printsql}SELECT anon_1.value FROM
274 generate_series(:generate_series_1, :generate_series_2) AS anon_1(value){stop}
275
276 A WITH ORDINALITY expression may be generated by passing the keyword
277 argument :paramref:`.FunctionElement.table_valued.with_ordinality`,
278 illustrated below using PostgreSQL's syntax:
279
280 .. sourcecode:: pycon+sql
281
282 >>> fn = func.generate_series(4, 1, -1).table_valued(
283 ... "gen", with_ordinality="ordinality"
284 ... )
285 >>> print(select(fn.render_derived()))
286 {printsql}SELECT anon_1.gen, anon_1.ordinality
287 FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3)
288 WITH ORDINALITY AS anon_1(gen, ordinality)
289
290 :param \*expr: A series of string column names that will be added to the
291 ``.c`` collection of the resulting :class:`_sql.TableValuedAlias`
292 construct as columns. :func:`_sql.column` objects with or without
293 datatypes may also be used.
294
295 :param name: optional name to assign to the alias name that's generated.
296 If omitted, a unique anonymizing name is used.
297
298 :param with_ordinality: string name that when present results in the
299 ``WITH ORDINALITY`` clause being added to the alias, and the given
300 string name will be added as a column to the .c collection
301 of the resulting :class:`_sql.TableValuedAlias`.
302
303 :param joins_implicitly: when True, the table valued function may be
304 used in the FROM clause without any explicit JOIN to other tables
305 in the SQL query, and no "cartesian product" warning will be generated.
306 May be useful for SQL functions such as ``func.json_each()``.
307
308 .. versionadded:: 1.4.33
309
310 .. versionadded:: 1.4.0b2
311
312
313 .. seealso::
314
315 :ref:`tutorial_functions_table_valued` - in the :ref:`unified_tutorial`
316
317 :ref:`Table-Valued Functions on PostgreSQL <postgresql_table_valued>` - in the :ref:`postgresql_toplevel` documentation
318
319 :meth:`_functions.FunctionElement.scalar_table_valued` - variant of
320 :meth:`_functions.FunctionElement.table_valued` which delivers the
321 complete table valued expression as a scalar column expression
322
323 :meth:`_functions.FunctionElement.column_valued`
324
325 :meth:`_sql.TableValuedAlias.render_derived` - renders the alias
326 using a derived column clause, e.g. ``AS name(col1, col2, ...)``
327
328 """ # noqa: 501
329
330 new_func = self._generate()
331
332 with_ordinality = kw.pop("with_ordinality", None)
333 joins_implicitly = kw.pop("joins_implicitly", None)
334 name = kw.pop("name", None)
335
336 if with_ordinality:
337 expr += (with_ordinality,)
338 new_func._with_ordinality = True
339
340 new_func.type = new_func._table_value_type = TableValueType(*expr)
341
342 return new_func.alias(name=name, joins_implicitly=joins_implicitly)
343
344 def column_valued(
345 self, name: Optional[str] = None, joins_implicitly: bool = False
346 ) -> TableValuedColumn[_T]:
347 """Return this :class:`_functions.FunctionElement` as a column expression that
348 selects from itself as a FROM clause.
349
350 E.g.:
351
352 .. sourcecode:: pycon+sql
353
354 >>> from sqlalchemy import select, func
355 >>> gs = func.generate_series(1, 5, -1).column_valued()
356 >>> print(select(gs))
357 {printsql}SELECT anon_1
358 FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) AS anon_1
359
360 This is shorthand for::
361
362 gs = func.generate_series(1, 5, -1).alias().column
363
364 :param name: optional name to assign to the alias name that's generated.
365 If omitted, a unique anonymizing name is used.
366
367 :param joins_implicitly: when True, the "table" portion of the column
368 valued function may be a member of the FROM clause without any
369 explicit JOIN to other tables in the SQL query, and no "cartesian
370 product" warning will be generated. May be useful for SQL functions
371 such as ``func.json_array_elements()``.
372
373 .. versionadded:: 1.4.46
374
375 .. seealso::
376
377 :ref:`tutorial_functions_column_valued` - in the :ref:`unified_tutorial`
378
379 :ref:`postgresql_column_valued` - in the :ref:`postgresql_toplevel` documentation
380
381 :meth:`_functions.FunctionElement.table_valued`
382
383 """ # noqa: 501
384
385 return self.alias(name=name, joins_implicitly=joins_implicitly).column
386
387 @util.ro_non_memoized_property
388 def columns(self) -> ColumnCollection[str, KeyedColumnElement[Any]]: # type: ignore[override] # noqa: E501
389 r"""The set of columns exported by this :class:`.FunctionElement`.
390
391 This is a placeholder collection that allows the function to be
392 placed in the FROM clause of a statement:
393
394 .. sourcecode:: pycon+sql
395
396 >>> from sqlalchemy import column, select, func
397 >>> stmt = select(column("x"), column("y")).select_from(func.myfunction())
398 >>> print(stmt)
399 {printsql}SELECT x, y FROM myfunction()
400
401 The above form is a legacy feature that is now superseded by the
402 fully capable :meth:`_functions.FunctionElement.table_valued`
403 method; see that method for details.
404
405 .. seealso::
406
407 :meth:`_functions.FunctionElement.table_valued` - generates table-valued
408 SQL function expressions.
409
410 """ # noqa: E501
411 return self.c
412
413 @util.ro_memoized_property
414 def c(self) -> ColumnCollection[str, KeyedColumnElement[Any]]: # type: ignore[override] # noqa: E501
415 """synonym for :attr:`.FunctionElement.columns`."""
416
417 return ColumnCollection(
418 columns=[(col.key, col) for col in self._all_selected_columns]
419 )
420
421 @property
422 def _all_selected_columns(self) -> Sequence[KeyedColumnElement[Any]]:
423 if is_table_value_type(self.type):
424 # TODO: this might not be fully accurate
425 cols = cast(
426 "Sequence[KeyedColumnElement[Any]]", self.type._elements
427 )
428 else:
429 cols = [self.label(None)]
430
431 return cols
432
433 @property
434 def exported_columns( # type: ignore[override]
435 self,
436 ) -> ColumnCollection[str, KeyedColumnElement[Any]]:
437 return self.columns
438
439 @HasMemoized.memoized_attribute
440 def clauses(self) -> ClauseList:
441 """Return the underlying :class:`.ClauseList` which contains
442 the arguments for this :class:`.FunctionElement`.
443
444 """
445 return cast(ClauseList, self.clause_expr.element)
446
447 def over(
448 self,
449 *,
450 partition_by: Optional[_ByArgument] = None,
451 order_by: Optional[_ByArgument] = None,
452 rows: Optional[Tuple[Optional[int], Optional[int]]] = None,
453 range_: Optional[Tuple[Optional[int], Optional[int]]] = None,
454 groups: Optional[Tuple[Optional[int], Optional[int]]] = None,
455 ) -> Over[_T]:
456 """Produce an OVER clause against this function.
457
458 Used against aggregate or so-called "window" functions,
459 for database backends that support window functions.
460
461 The expression::
462
463 func.row_number().over(order_by="x")
464
465 is shorthand for::
466
467 from sqlalchemy import over
468
469 over(func.row_number(), order_by="x")
470
471 See :func:`_expression.over` for a full description.
472
473 .. seealso::
474
475 :func:`_expression.over`
476
477 :ref:`tutorial_window_functions` - in the :ref:`unified_tutorial`
478
479 """
480 return Over(
481 self,
482 partition_by=partition_by,
483 order_by=order_by,
484 rows=rows,
485 range_=range_,
486 groups=groups,
487 )
488
489 def within_group(
490 self, *order_by: _ColumnExpressionArgument[Any]
491 ) -> WithinGroup[_T]:
492 """Produce a WITHIN GROUP (ORDER BY expr) clause against this function.
493
494 Used against so-called "ordered set aggregate" and "hypothetical
495 set aggregate" functions, including :class:`.percentile_cont`,
496 :class:`.rank`, :class:`.dense_rank`, etc.
497
498 See :func:`_expression.within_group` for a full description.
499
500 .. seealso::
501
502 :ref:`tutorial_functions_within_group` -
503 in the :ref:`unified_tutorial`
504
505
506 """
507 return WithinGroup(self, *order_by)
508
509 @overload
510 def filter(self) -> Self: ...
511
512 @overload
513 def filter(
514 self,
515 __criterion0: _ColumnExpressionArgument[bool],
516 *criterion: _ColumnExpressionArgument[bool],
517 ) -> FunctionFilter[_T]: ...
518
519 def filter(
520 self, *criterion: _ColumnExpressionArgument[bool]
521 ) -> Union[Self, FunctionFilter[_T]]:
522 """Produce a FILTER clause against this function.
523
524 Used against aggregate and window functions,
525 for database backends that support the "FILTER" clause.
526
527 The expression::
528
529 func.count(1).filter(True)
530
531 is shorthand for::
532
533 from sqlalchemy import funcfilter
534
535 funcfilter(func.count(1), True)
536
537 .. seealso::
538
539 :ref:`tutorial_functions_within_group` -
540 in the :ref:`unified_tutorial`
541
542 :class:`.FunctionFilter`
543
544 :func:`.funcfilter`
545
546
547 """
548 if not criterion:
549 return self
550 return FunctionFilter(self, *criterion)
551
552 def as_comparison(
553 self, left_index: int, right_index: int
554 ) -> FunctionAsBinary:
555 """Interpret this expression as a boolean comparison between two
556 values.
557
558 This method is used for an ORM use case described at
559 :ref:`relationship_custom_operator_sql_function`.
560
561 A hypothetical SQL function "is_equal()" which compares to values
562 for equality would be written in the Core expression language as::
563
564 expr = func.is_equal("a", "b")
565
566 If "is_equal()" above is comparing "a" and "b" for equality, the
567 :meth:`.FunctionElement.as_comparison` method would be invoked as::
568
569 expr = func.is_equal("a", "b").as_comparison(1, 2)
570
571 Where above, the integer value "1" refers to the first argument of the
572 "is_equal()" function and the integer value "2" refers to the second.
573
574 This would create a :class:`.BinaryExpression` that is equivalent to::
575
576 BinaryExpression("a", "b", operator=op.eq)
577
578 However, at the SQL level it would still render as
579 "is_equal('a', 'b')".
580
581 The ORM, when it loads a related object or collection, needs to be able
582 to manipulate the "left" and "right" sides of the ON clause of a JOIN
583 expression. The purpose of this method is to provide a SQL function
584 construct that can also supply this information to the ORM, when used
585 with the :paramref:`_orm.relationship.primaryjoin` parameter. The
586 return value is a containment object called :class:`.FunctionAsBinary`.
587
588 An ORM example is as follows::
589
590 class Venue(Base):
591 __tablename__ = "venue"
592 id = Column(Integer, primary_key=True)
593 name = Column(String)
594
595 descendants = relationship(
596 "Venue",
597 primaryjoin=func.instr(
598 remote(foreign(name)), name + "/"
599 ).as_comparison(1, 2)
600 == 1,
601 viewonly=True,
602 order_by=name,
603 )
604
605 Above, the "Venue" class can load descendant "Venue" objects by
606 determining if the name of the parent Venue is contained within the
607 start of the hypothetical descendant value's name, e.g. "parent1" would
608 match up to "parent1/child1", but not to "parent2/child1".
609
610 Possible use cases include the "materialized path" example given above,
611 as well as making use of special SQL functions such as geometric
612 functions to create join conditions.
613
614 :param left_index: the integer 1-based index of the function argument
615 that serves as the "left" side of the expression.
616 :param right_index: the integer 1-based index of the function argument
617 that serves as the "right" side of the expression.
618
619 .. versionadded:: 1.3
620
621 .. seealso::
622
623 :ref:`relationship_custom_operator_sql_function` -
624 example use within the ORM
625
626 """
627 return FunctionAsBinary(self, left_index, right_index)
628
629 @property
630 def _from_objects(self) -> Any:
631 return self.clauses._from_objects
632
633 def within_group_type(
634 self, within_group: WithinGroup[_S]
635 ) -> Optional[TypeEngine[_S]]:
636 """For types that define their return type as based on the criteria
637 within a WITHIN GROUP (ORDER BY) expression, called by the
638 :class:`.WithinGroup` construct.
639
640 Returns None by default, in which case the function's normal ``.type``
641 is used.
642
643 """
644
645 return None
646
647 def alias(
648 self, name: Optional[str] = None, joins_implicitly: bool = False
649 ) -> TableValuedAlias:
650 r"""Produce a :class:`_expression.Alias` construct against this
651 :class:`.FunctionElement`.
652
653 .. tip::
654
655 The :meth:`_functions.FunctionElement.alias` method is part of the
656 mechanism by which "table valued" SQL functions are created.
657 However, most use cases are covered by higher level methods on
658 :class:`_functions.FunctionElement` including
659 :meth:`_functions.FunctionElement.table_valued`, and
660 :meth:`_functions.FunctionElement.column_valued`.
661
662 This construct wraps the function in a named alias which
663 is suitable for the FROM clause, in the style accepted for example
664 by PostgreSQL. A column expression is also provided using the
665 special ``.column`` attribute, which may
666 be used to refer to the output of the function as a scalar value
667 in the columns or where clause, for a backend such as PostgreSQL.
668
669 For a full table-valued expression, use the
670 :meth:`_functions.FunctionElement.table_valued` method first to
671 establish named columns.
672
673 e.g.:
674
675 .. sourcecode:: pycon+sql
676
677 >>> from sqlalchemy import func, select, column
678 >>> data_view = func.unnest([1, 2, 3]).alias("data_view")
679 >>> print(select(data_view.column))
680 {printsql}SELECT data_view
681 FROM unnest(:unnest_1) AS data_view
682
683 The :meth:`_functions.FunctionElement.column_valued` method provides
684 a shortcut for the above pattern:
685
686 .. sourcecode:: pycon+sql
687
688 >>> data_view = func.unnest([1, 2, 3]).column_valued("data_view")
689 >>> print(select(data_view))
690 {printsql}SELECT data_view
691 FROM unnest(:unnest_1) AS data_view
692
693 .. versionadded:: 1.4.0b2 Added the ``.column`` accessor
694
695 :param name: alias name, will be rendered as ``AS <name>`` in the
696 FROM clause
697
698 :param joins_implicitly: when True, the table valued function may be
699 used in the FROM clause without any explicit JOIN to other tables
700 in the SQL query, and no "cartesian product" warning will be
701 generated. May be useful for SQL functions such as
702 ``func.json_each()``.
703
704 .. versionadded:: 1.4.33
705
706 .. seealso::
707
708 :ref:`tutorial_functions_table_valued` -
709 in the :ref:`unified_tutorial`
710
711 :meth:`_functions.FunctionElement.table_valued`
712
713 :meth:`_functions.FunctionElement.scalar_table_valued`
714
715 :meth:`_functions.FunctionElement.column_valued`
716
717
718 """
719
720 return TableValuedAlias._construct(
721 self,
722 name=name,
723 table_value_type=self.type,
724 joins_implicitly=joins_implicitly,
725 )
726
727 def select(self) -> Select[Tuple[_T]]:
728 """Produce a :func:`_expression.select` construct
729 against this :class:`.FunctionElement`.
730
731 This is shorthand for::
732
733 s = select(function_element)
734
735 """
736 s: Select[Any] = Select(self)
737 if self._execution_options:
738 s = s.execution_options(**self._execution_options)
739 return s
740
741 def _bind_param(
742 self,
743 operator: OperatorType,
744 obj: Any,
745 type_: Optional[TypeEngine[_T]] = None,
746 expanding: bool = False,
747 **kw: Any,
748 ) -> BindParameter[_T]:
749 return BindParameter(
750 None,
751 obj,
752 _compared_to_operator=operator,
753 _compared_to_type=self.type,
754 unique=True,
755 type_=type_,
756 expanding=expanding,
757 **kw,
758 )
759
760 def self_group(self, against: Optional[OperatorType] = None) -> ClauseElement: # type: ignore[override] # noqa E501
761 # for the moment, we are parenthesizing all array-returning
762 # expressions against getitem. This may need to be made
763 # more portable if in the future we support other DBs
764 # besides postgresql.
765 if against is operators.getitem and isinstance(
766 self.type, sqltypes.ARRAY
767 ):
768 return Grouping(self)
769 else:
770 return super().self_group(against=against)
771
772 @property
773 def entity_namespace(self) -> _EntityNamespace:
774 """overrides FromClause.entity_namespace as functions are generally
775 column expressions and not FromClauses.
776
777 """
778 # ideally functions would not be fromclauses but we failed to make
779 # this adjustment in 1.4
780 return _entity_namespace(self.clause_expr)
781
782
783class FunctionAsBinary(BinaryExpression[Any]):
784 _traverse_internals = [
785 ("sql_function", InternalTraversal.dp_clauseelement),
786 ("left_index", InternalTraversal.dp_plain_obj),
787 ("right_index", InternalTraversal.dp_plain_obj),
788 ("modifiers", InternalTraversal.dp_plain_dict),
789 ]
790
791 sql_function: FunctionElement[Any]
792 left_index: int
793 right_index: int
794
795 def _gen_cache_key(self, anon_map: Any, bindparams: Any) -> Any:
796 return ColumnElement._gen_cache_key(self, anon_map, bindparams)
797
798 def __init__(
799 self, fn: FunctionElement[Any], left_index: int, right_index: int
800 ) -> None:
801 self.sql_function = fn
802 self.left_index = left_index
803 self.right_index = right_index
804
805 self.operator = operators.function_as_comparison_op
806 self.type = sqltypes.BOOLEANTYPE
807 self.negate = None
808 self._is_implicitly_boolean = True
809 self.modifiers = util.immutabledict({})
810
811 @property
812 def left_expr(self) -> ColumnElement[Any]:
813 return self.sql_function.clauses.clauses[self.left_index - 1]
814
815 @left_expr.setter
816 def left_expr(self, value: ColumnElement[Any]) -> None:
817 self.sql_function.clauses.clauses[self.left_index - 1] = value
818
819 @property
820 def right_expr(self) -> ColumnElement[Any]:
821 return self.sql_function.clauses.clauses[self.right_index - 1]
822
823 @right_expr.setter
824 def right_expr(self, value: ColumnElement[Any]) -> None:
825 self.sql_function.clauses.clauses[self.right_index - 1] = value
826
827 if not TYPE_CHECKING:
828 # mypy can't accommodate @property to replace an instance
829 # variable
830
831 left = left_expr
832 right = right_expr
833
834
835class ScalarFunctionColumn(NamedColumn[_T]):
836 __visit_name__ = "scalar_function_column"
837
838 _traverse_internals = [
839 ("name", InternalTraversal.dp_anon_name),
840 ("type", InternalTraversal.dp_type),
841 ("fn", InternalTraversal.dp_clauseelement),
842 ]
843
844 is_literal = False
845 table = None
846
847 def __init__(
848 self,
849 fn: FunctionElement[_T],
850 name: str,
851 type_: Optional[_TypeEngineArgument[_T]] = None,
852 ) -> None:
853 self.fn = fn
854 self.name = name
855
856 # if type is None, we get NULLTYPE, which is our _T. But I don't
857 # know how to get the overloads to express that correctly
858 self.type = type_api.to_instance(type_) # type: ignore
859
860
861class _FunctionGenerator:
862 """Generate SQL function expressions.
863
864 :data:`.func` is a special object instance which generates SQL
865 functions based on name-based attributes, e.g.:
866
867 .. sourcecode:: pycon+sql
868
869 >>> print(func.count(1))
870 {printsql}count(:param_1)
871
872 The returned object is an instance of :class:`.Function`, and is a
873 column-oriented SQL element like any other, and is used in that way:
874
875 .. sourcecode:: pycon+sql
876
877 >>> print(select(func.count(table.c.id)))
878 {printsql}SELECT count(sometable.id) FROM sometable
879
880 Any name can be given to :data:`.func`. If the function name is unknown to
881 SQLAlchemy, it will be rendered exactly as is. For common SQL functions
882 which SQLAlchemy is aware of, the name may be interpreted as a *generic
883 function* which will be compiled appropriately to the target database:
884
885 .. sourcecode:: pycon+sql
886
887 >>> print(func.current_timestamp())
888 {printsql}CURRENT_TIMESTAMP
889
890 To call functions which are present in dot-separated packages,
891 specify them in the same manner:
892
893 .. sourcecode:: pycon+sql
894
895 >>> print(func.stats.yield_curve(5, 10))
896 {printsql}stats.yield_curve(:yield_curve_1, :yield_curve_2)
897
898 SQLAlchemy can be made aware of the return type of functions to enable
899 type-specific lexical and result-based behavior. For example, to ensure
900 that a string-based function returns a Unicode value and is similarly
901 treated as a string in expressions, specify
902 :class:`~sqlalchemy.types.Unicode` as the type:
903
904 .. sourcecode:: pycon+sql
905
906 >>> print(
907 ... func.my_string("hi", type_=Unicode)
908 ... + " "
909 ... + func.my_string("there", type_=Unicode)
910 ... )
911 {printsql}my_string(:my_string_1) || :my_string_2 || my_string(:my_string_3)
912
913 The object returned by a :data:`.func` call is usually an instance of
914 :class:`.Function`.
915 This object meets the "column" interface, including comparison and labeling
916 functions. The object can also be passed the :meth:`~.Connectable.execute`
917 method of a :class:`_engine.Connection` or :class:`_engine.Engine`,
918 where it will be
919 wrapped inside of a SELECT statement first::
920
921 print(connection.execute(func.current_timestamp()).scalar())
922
923 In a few exception cases, the :data:`.func` accessor
924 will redirect a name to a built-in expression such as :func:`.cast`
925 or :func:`.extract`, as these names have well-known meaning
926 but are not exactly the same as "functions" from a SQLAlchemy
927 perspective.
928
929 Functions which are interpreted as "generic" functions know how to
930 calculate their return type automatically. For a listing of known generic
931 functions, see :ref:`generic_functions`.
932
933 .. note::
934
935 The :data:`.func` construct has only limited support for calling
936 standalone "stored procedures", especially those with special
937 parameterization concerns.
938
939 See the section :ref:`stored_procedures` for details on how to use
940 the DBAPI-level ``callproc()`` method for fully traditional stored
941 procedures.
942
943 .. seealso::
944
945 :ref:`tutorial_functions` - in the :ref:`unified_tutorial`
946
947 :class:`.Function`
948
949 """ # noqa
950
951 def __init__(self, **opts: Any) -> None:
952 self.__names: List[str] = []
953 self.opts = opts
954
955 def __getattr__(self, name: str) -> _FunctionGenerator:
956 # passthru __ attributes; fixes pydoc
957 if name.startswith("__"):
958 try:
959 return self.__dict__[name] # type: ignore
960 except KeyError:
961 raise AttributeError(name)
962
963 elif name.endswith("_"):
964 name = name[0:-1]
965 f = _FunctionGenerator(**self.opts)
966 f.__names = list(self.__names) + [name]
967 return f
968
969 @overload
970 def __call__(
971 self, *c: Any, type_: _TypeEngineArgument[_T], **kwargs: Any
972 ) -> Function[_T]: ...
973
974 @overload
975 def __call__(self, *c: Any, **kwargs: Any) -> Function[Any]: ...
976
977 def __call__(self, *c: Any, **kwargs: Any) -> Function[Any]:
978 o = self.opts.copy()
979 o.update(kwargs)
980
981 tokens = len(self.__names)
982
983 if tokens == 2:
984 package, fname = self.__names
985 elif tokens == 1:
986 package, fname = "_default", self.__names[0]
987 else:
988 package = None
989
990 if package is not None:
991 func = _registry[package].get(fname.lower())
992 if func is not None:
993 return func(*c, **o)
994
995 return Function(
996 self.__names[-1], packagenames=tuple(self.__names[0:-1]), *c, **o
997 )
998
999 if TYPE_CHECKING:
1000 # START GENERATED FUNCTION ACCESSORS
1001
1002 # code within this block is **programmatically,
1003 # statically generated** by tools/generate_sql_functions.py
1004
1005 @property
1006 def aggregate_strings(self) -> Type[aggregate_strings]: ...
1007
1008 @property
1009 def ansifunction(self) -> Type[AnsiFunction[Any]]: ...
1010
1011 # set ColumnElement[_T] as a separate overload, to appease
1012 # mypy which seems to not want to accept _T from
1013 # _ColumnExpressionArgument. Seems somewhat related to the covariant
1014 # _HasClauseElement as of mypy 1.15
1015
1016 @overload
1017 def array_agg(
1018 self,
1019 col: ColumnElement[_T],
1020 *args: _ColumnExpressionOrLiteralArgument[Any],
1021 **kwargs: Any,
1022 ) -> array_agg[_T]: ...
1023
1024 @overload
1025 def array_agg(
1026 self,
1027 col: _ColumnExpressionArgument[_T],
1028 *args: _ColumnExpressionOrLiteralArgument[Any],
1029 **kwargs: Any,
1030 ) -> array_agg[_T]: ...
1031
1032 @overload
1033 def array_agg(
1034 self,
1035 col: _T,
1036 *args: _ColumnExpressionOrLiteralArgument[Any],
1037 **kwargs: Any,
1038 ) -> array_agg[_T]: ...
1039
1040 def array_agg(
1041 self,
1042 col: _ColumnExpressionOrLiteralArgument[_T],
1043 *args: _ColumnExpressionOrLiteralArgument[Any],
1044 **kwargs: Any,
1045 ) -> array_agg[_T]: ...
1046
1047 @property
1048 def cast(self) -> Type[Cast[Any]]: ...
1049
1050 @property
1051 def char_length(self) -> Type[char_length]: ...
1052
1053 # set ColumnElement[_T] as a separate overload, to appease
1054 # mypy which seems to not want to accept _T from
1055 # _ColumnExpressionArgument. Seems somewhat related to the covariant
1056 # _HasClauseElement as of mypy 1.15
1057
1058 @overload
1059 def coalesce(
1060 self,
1061 col: ColumnElement[_T],
1062 *args: _ColumnExpressionOrLiteralArgument[Any],
1063 **kwargs: Any,
1064 ) -> coalesce[_T]: ...
1065
1066 @overload
1067 def coalesce(
1068 self,
1069 col: _ColumnExpressionArgument[Optional[_T]],
1070 *args: _ColumnExpressionOrLiteralArgument[Any],
1071 **kwargs: Any,
1072 ) -> coalesce[_T]: ...
1073
1074 @overload
1075 def coalesce(
1076 self,
1077 col: Optional[_T],
1078 *args: _ColumnExpressionOrLiteralArgument[Any],
1079 **kwargs: Any,
1080 ) -> coalesce[_T]: ...
1081
1082 def coalesce(
1083 self,
1084 col: _ColumnExpressionOrLiteralArgument[Optional[_T]],
1085 *args: _ColumnExpressionOrLiteralArgument[Any],
1086 **kwargs: Any,
1087 ) -> coalesce[_T]: ...
1088
1089 @property
1090 def concat(self) -> Type[concat]: ...
1091
1092 @property
1093 def count(self) -> Type[count]: ...
1094
1095 @property
1096 def cube(self) -> Type[cube[Any]]: ...
1097
1098 @property
1099 def cume_dist(self) -> Type[cume_dist]: ...
1100
1101 @property
1102 def current_date(self) -> Type[current_date]: ...
1103
1104 @property
1105 def current_time(self) -> Type[current_time]: ...
1106
1107 @property
1108 def current_timestamp(self) -> Type[current_timestamp]: ...
1109
1110 @property
1111 def current_user(self) -> Type[current_user]: ...
1112
1113 @property
1114 def dense_rank(self) -> Type[dense_rank]: ...
1115
1116 @property
1117 def extract(self) -> Type[Extract]: ...
1118
1119 @property
1120 def grouping_sets(self) -> Type[grouping_sets[Any]]: ...
1121
1122 @property
1123 def localtime(self) -> Type[localtime]: ...
1124
1125 @property
1126 def localtimestamp(self) -> Type[localtimestamp]: ...
1127
1128 # set ColumnElement[_T] as a separate overload, to appease
1129 # mypy which seems to not want to accept _T from
1130 # _ColumnExpressionArgument. Seems somewhat related to the covariant
1131 # _HasClauseElement as of mypy 1.15
1132
1133 @overload
1134 def max( # noqa: A001
1135 self,
1136 col: ColumnElement[_T],
1137 *args: _ColumnExpressionOrLiteralArgument[Any],
1138 **kwargs: Any,
1139 ) -> max[_T]: ...
1140
1141 @overload
1142 def max( # noqa: A001
1143 self,
1144 col: _ColumnExpressionArgument[_T],
1145 *args: _ColumnExpressionOrLiteralArgument[Any],
1146 **kwargs: Any,
1147 ) -> max[_T]: ...
1148
1149 @overload
1150 def max( # noqa: A001
1151 self,
1152 col: _T,
1153 *args: _ColumnExpressionOrLiteralArgument[Any],
1154 **kwargs: Any,
1155 ) -> max[_T]: ...
1156
1157 def max( # noqa: A001
1158 self,
1159 col: _ColumnExpressionOrLiteralArgument[_T],
1160 *args: _ColumnExpressionOrLiteralArgument[Any],
1161 **kwargs: Any,
1162 ) -> max[_T]: ...
1163
1164 # set ColumnElement[_T] as a separate overload, to appease
1165 # mypy which seems to not want to accept _T from
1166 # _ColumnExpressionArgument. Seems somewhat related to the covariant
1167 # _HasClauseElement as of mypy 1.15
1168
1169 @overload
1170 def min( # noqa: A001
1171 self,
1172 col: ColumnElement[_T],
1173 *args: _ColumnExpressionOrLiteralArgument[Any],
1174 **kwargs: Any,
1175 ) -> min[_T]: ...
1176
1177 @overload
1178 def min( # noqa: A001
1179 self,
1180 col: _ColumnExpressionArgument[_T],
1181 *args: _ColumnExpressionOrLiteralArgument[Any],
1182 **kwargs: Any,
1183 ) -> min[_T]: ...
1184
1185 @overload
1186 def min( # noqa: A001
1187 self,
1188 col: _T,
1189 *args: _ColumnExpressionOrLiteralArgument[Any],
1190 **kwargs: Any,
1191 ) -> min[_T]: ...
1192
1193 def min( # noqa: A001
1194 self,
1195 col: _ColumnExpressionOrLiteralArgument[_T],
1196 *args: _ColumnExpressionOrLiteralArgument[Any],
1197 **kwargs: Any,
1198 ) -> min[_T]: ...
1199
1200 @property
1201 def mode(self) -> Type[mode[Any]]: ...
1202
1203 @property
1204 def next_value(self) -> Type[next_value]: ...
1205
1206 @property
1207 def now(self) -> Type[now]: ...
1208
1209 @property
1210 def orderedsetagg(self) -> Type[OrderedSetAgg[Any]]: ...
1211
1212 @property
1213 def percent_rank(self) -> Type[percent_rank]: ...
1214
1215 @property
1216 def percentile_cont(self) -> Type[percentile_cont[Any]]: ...
1217
1218 @property
1219 def percentile_disc(self) -> Type[percentile_disc[Any]]: ...
1220
1221 @property
1222 def random(self) -> Type[random]: ...
1223
1224 @property
1225 def rank(self) -> Type[rank]: ...
1226
1227 @property
1228 def rollup(self) -> Type[rollup[Any]]: ...
1229
1230 @property
1231 def session_user(self) -> Type[session_user]: ...
1232
1233 # set ColumnElement[_T] as a separate overload, to appease
1234 # mypy which seems to not want to accept _T from
1235 # _ColumnExpressionArgument. Seems somewhat related to the covariant
1236 # _HasClauseElement as of mypy 1.15
1237
1238 @overload
1239 def sum( # noqa: A001
1240 self,
1241 col: ColumnElement[_T],
1242 *args: _ColumnExpressionOrLiteralArgument[Any],
1243 **kwargs: Any,
1244 ) -> sum[_T]: ...
1245
1246 @overload
1247 def sum( # noqa: A001
1248 self,
1249 col: _ColumnExpressionArgument[_T],
1250 *args: _ColumnExpressionOrLiteralArgument[Any],
1251 **kwargs: Any,
1252 ) -> sum[_T]: ...
1253
1254 @overload
1255 def sum( # noqa: A001
1256 self,
1257 col: _T,
1258 *args: _ColumnExpressionOrLiteralArgument[Any],
1259 **kwargs: Any,
1260 ) -> sum[_T]: ...
1261
1262 def sum( # noqa: A001
1263 self,
1264 col: _ColumnExpressionOrLiteralArgument[_T],
1265 *args: _ColumnExpressionOrLiteralArgument[Any],
1266 **kwargs: Any,
1267 ) -> sum[_T]: ...
1268
1269 @property
1270 def sysdate(self) -> Type[sysdate]: ...
1271
1272 @property
1273 def user(self) -> Type[user]: ...
1274
1275 # END GENERATED FUNCTION ACCESSORS
1276
1277
1278func = _FunctionGenerator()
1279func.__doc__ = _FunctionGenerator.__doc__
1280
1281modifier = _FunctionGenerator(group=False)
1282
1283
1284class Function(FunctionElement[_T]):
1285 r"""Describe a named SQL function.
1286
1287 The :class:`.Function` object is typically generated from the
1288 :data:`.func` generation object.
1289
1290
1291 :param \*clauses: list of column expressions that form the arguments
1292 of the SQL function call.
1293
1294 :param type\_: optional :class:`.TypeEngine` datatype object that will be
1295 used as the return value of the column expression generated by this
1296 function call.
1297
1298 :param packagenames: a string which indicates package prefix names
1299 to be prepended to the function name when the SQL is generated.
1300 The :data:`.func` generator creates these when it is called using
1301 dotted format, e.g.::
1302
1303 func.mypackage.some_function(col1, col2)
1304
1305 .. seealso::
1306
1307 :ref:`tutorial_functions` - in the :ref:`unified_tutorial`
1308
1309 :data:`.func` - namespace which produces registered or ad-hoc
1310 :class:`.Function` instances.
1311
1312 :class:`.GenericFunction` - allows creation of registered function
1313 types.
1314
1315 """
1316
1317 __visit_name__ = "function"
1318
1319 _traverse_internals = FunctionElement._traverse_internals + [
1320 ("packagenames", InternalTraversal.dp_plain_obj),
1321 ("name", InternalTraversal.dp_string),
1322 ("type", InternalTraversal.dp_type),
1323 ]
1324
1325 name: str
1326
1327 identifier: str
1328
1329 type: TypeEngine[_T]
1330 """A :class:`_types.TypeEngine` object which refers to the SQL return
1331 type represented by this SQL function.
1332
1333 This datatype may be configured when generating a
1334 :class:`_functions.Function` object by passing the
1335 :paramref:`_functions.Function.type_` parameter, e.g.::
1336
1337 >>> select(func.lower("some VALUE", type_=String))
1338
1339 The small number of built-in classes of :class:`_functions.Function` come
1340 with a built-in datatype that's appropriate to the class of function and
1341 its arguments. For functions that aren't known, the type defaults to the
1342 "null type".
1343
1344 """
1345
1346 @overload
1347 def __init__(
1348 self,
1349 name: str,
1350 *clauses: _ColumnExpressionOrLiteralArgument[_T],
1351 type_: None = ...,
1352 packagenames: Optional[Tuple[str, ...]] = ...,
1353 ) -> None: ...
1354
1355 @overload
1356 def __init__(
1357 self,
1358 name: str,
1359 *clauses: _ColumnExpressionOrLiteralArgument[Any],
1360 type_: _TypeEngineArgument[_T] = ...,
1361 packagenames: Optional[Tuple[str, ...]] = ...,
1362 ) -> None: ...
1363
1364 def __init__(
1365 self,
1366 name: str,
1367 *clauses: _ColumnExpressionOrLiteralArgument[Any],
1368 type_: Optional[_TypeEngineArgument[_T]] = None,
1369 packagenames: Optional[Tuple[str, ...]] = None,
1370 ) -> None:
1371 """Construct a :class:`.Function`.
1372
1373 The :data:`.func` construct is normally used to construct
1374 new :class:`.Function` instances.
1375
1376 """
1377 self.packagenames = packagenames or ()
1378 self.name = name
1379
1380 # if type is None, we get NULLTYPE, which is our _T. But I don't
1381 # know how to get the overloads to express that correctly
1382 self.type = type_api.to_instance(type_) # type: ignore
1383
1384 FunctionElement.__init__(self, *clauses)
1385
1386 def _bind_param(
1387 self,
1388 operator: OperatorType,
1389 obj: Any,
1390 type_: Optional[TypeEngine[_T]] = None,
1391 expanding: bool = False,
1392 **kw: Any,
1393 ) -> BindParameter[_T]:
1394 return BindParameter(
1395 self.name,
1396 obj,
1397 _compared_to_operator=operator,
1398 _compared_to_type=self.type,
1399 type_=type_,
1400 unique=True,
1401 expanding=expanding,
1402 **kw,
1403 )
1404
1405
1406class GenericFunction(Function[_T]):
1407 """Define a 'generic' function.
1408
1409 A generic function is a pre-established :class:`.Function`
1410 class that is instantiated automatically when called
1411 by name from the :data:`.func` attribute. Note that
1412 calling any name from :data:`.func` has the effect that
1413 a new :class:`.Function` instance is created automatically,
1414 given that name. The primary use case for defining
1415 a :class:`.GenericFunction` class is so that a function
1416 of a particular name may be given a fixed return type.
1417 It can also include custom argument parsing schemes as well
1418 as additional methods.
1419
1420 Subclasses of :class:`.GenericFunction` are automatically
1421 registered under the name of the class. For
1422 example, a user-defined function ``as_utc()`` would
1423 be available immediately::
1424
1425 from sqlalchemy.sql.functions import GenericFunction
1426 from sqlalchemy.types import DateTime
1427
1428
1429 class as_utc(GenericFunction):
1430 type = DateTime()
1431 inherit_cache = True
1432
1433
1434 print(select(func.as_utc()))
1435
1436 User-defined generic functions can be organized into
1437 packages by specifying the "package" attribute when defining
1438 :class:`.GenericFunction`. Third party libraries
1439 containing many functions may want to use this in order
1440 to avoid name conflicts with other systems. For example,
1441 if our ``as_utc()`` function were part of a package
1442 "time"::
1443
1444 class as_utc(GenericFunction):
1445 type = DateTime()
1446 package = "time"
1447 inherit_cache = True
1448
1449 The above function would be available from :data:`.func`
1450 using the package name ``time``::
1451
1452 print(select(func.time.as_utc()))
1453
1454 A final option is to allow the function to be accessed
1455 from one name in :data:`.func` but to render as a different name.
1456 The ``identifier`` attribute will override the name used to
1457 access the function as loaded from :data:`.func`, but will retain
1458 the usage of ``name`` as the rendered name::
1459
1460 class GeoBuffer(GenericFunction):
1461 type = Geometry()
1462 package = "geo"
1463 name = "ST_Buffer"
1464 identifier = "buffer"
1465 inherit_cache = True
1466
1467 The above function will render as follows:
1468
1469 .. sourcecode:: pycon+sql
1470
1471 >>> print(func.geo.buffer())
1472 {printsql}ST_Buffer()
1473
1474 The name will be rendered as is, however without quoting unless the name
1475 contains special characters that require quoting. To force quoting
1476 on or off for the name, use the :class:`.sqlalchemy.sql.quoted_name`
1477 construct::
1478
1479 from sqlalchemy.sql import quoted_name
1480
1481
1482 class GeoBuffer(GenericFunction):
1483 type = Geometry()
1484 package = "geo"
1485 name = quoted_name("ST_Buffer", True)
1486 identifier = "buffer"
1487 inherit_cache = True
1488
1489 The above function will render as:
1490
1491 .. sourcecode:: pycon+sql
1492
1493 >>> print(func.geo.buffer())
1494 {printsql}"ST_Buffer"()
1495
1496 Type parameters for this class as a
1497 `generic type <https://peps.python.org/pep-0484/#generics>`_ can be passed
1498 and should match the type seen in a :class:`_engine.Result`. For example::
1499
1500 class as_utc(GenericFunction[datetime.datetime]):
1501 type = DateTime()
1502 inherit_cache = True
1503
1504 The above indicates that the following expression returns a ``datetime``
1505 object::
1506
1507 connection.scalar(select(func.as_utc()))
1508
1509 .. versionadded:: 1.3.13 The :class:`.quoted_name` construct is now
1510 recognized for quoting when used with the "name" attribute of the
1511 object, so that quoting can be forced on or off for the function
1512 name.
1513
1514
1515 """
1516
1517 coerce_arguments = True
1518 inherit_cache = True
1519
1520 _register: bool
1521
1522 name = "GenericFunction"
1523
1524 def __init_subclass__(cls) -> None:
1525 if annotation.Annotated not in cls.__mro__:
1526 cls._register_generic_function(cls.__name__, cls.__dict__)
1527 super().__init_subclass__()
1528
1529 @classmethod
1530 def _register_generic_function(
1531 cls, clsname: str, clsdict: Mapping[str, Any]
1532 ) -> None:
1533 cls.name = name = clsdict.get("name", clsname)
1534 cls.identifier = identifier = clsdict.get("identifier", name)
1535 package = clsdict.get("package", "_default")
1536 # legacy
1537 if "__return_type__" in clsdict:
1538 cls.type = clsdict["__return_type__"]
1539
1540 # Check _register attribute status
1541 cls._register = getattr(cls, "_register", True)
1542
1543 # Register the function if required
1544 if cls._register:
1545 register_function(identifier, cls, package)
1546 else:
1547 # Set _register to True to register child classes by default
1548 cls._register = True
1549
1550 def __init__(
1551 self, *args: _ColumnExpressionOrLiteralArgument[Any], **kwargs: Any
1552 ) -> None:
1553 parsed_args = kwargs.pop("_parsed_args", None)
1554 if parsed_args is None:
1555 parsed_args = [
1556 coercions.expect(
1557 roles.ExpressionElementRole,
1558 c,
1559 name=self.name,
1560 apply_propagate_attrs=self,
1561 )
1562 for c in args
1563 ]
1564 self._has_args = self._has_args or bool(parsed_args)
1565 self.packagenames = ()
1566
1567 self.clause_expr = Grouping(
1568 ClauseList(
1569 operator=operators.comma_op, group_contents=True, *parsed_args
1570 )
1571 )
1572
1573 self.type = type_api.to_instance( # type: ignore
1574 kwargs.pop("type_", None) or getattr(self, "type", None)
1575 )
1576
1577
1578register_function("cast", Cast) # type: ignore
1579register_function("extract", Extract) # type: ignore
1580
1581
1582class next_value(GenericFunction[int]):
1583 """Represent the 'next value', given a :class:`.Sequence`
1584 as its single argument.
1585
1586 Compiles into the appropriate function on each backend,
1587 or will raise NotImplementedError if used on a backend
1588 that does not provide support for sequences.
1589
1590 """
1591
1592 type = sqltypes.Integer()
1593 name = "next_value"
1594
1595 _traverse_internals = [
1596 ("sequence", InternalTraversal.dp_named_ddl_element)
1597 ]
1598
1599 def __init__(self, seq: schema.Sequence, **kw: Any) -> None:
1600 assert isinstance(
1601 seq, schema.Sequence
1602 ), "next_value() accepts a Sequence object as input."
1603 self.sequence = seq
1604 self.type = sqltypes.to_instance( # type: ignore
1605 seq.data_type or getattr(self, "type", None)
1606 )
1607
1608 def compare(self, other: Any, **kw: Any) -> bool:
1609 return (
1610 isinstance(other, next_value)
1611 and self.sequence.name == other.sequence.name
1612 )
1613
1614 @property
1615 def _from_objects(self) -> Any:
1616 return []
1617
1618
1619class AnsiFunction(GenericFunction[_T]):
1620 """Define a function in "ansi" format, which doesn't render parenthesis."""
1621
1622 inherit_cache = True
1623
1624 def __init__(
1625 self, *args: _ColumnExpressionArgument[Any], **kwargs: Any
1626 ) -> None:
1627 GenericFunction.__init__(self, *args, **kwargs)
1628
1629
1630class ReturnTypeFromArgs(GenericFunction[_T]):
1631 """Define a function whose return type is bound to the type of its
1632 arguments.
1633 """
1634
1635 inherit_cache = True
1636
1637 # set ColumnElement[_T] as a separate overload, to appease
1638 # mypy which seems to not want to accept _T from
1639 # _ColumnExpressionArgument. Seems somewhat related to the covariant
1640 # _HasClauseElement as of mypy 1.15
1641
1642 @overload
1643 def __init__(
1644 self,
1645 col: ColumnElement[_T],
1646 *args: _ColumnExpressionOrLiteralArgument[Any],
1647 **kwargs: Any,
1648 ) -> None: ...
1649
1650 @overload
1651 def __init__(
1652 self,
1653 col: _ColumnExpressionArgument[_T],
1654 *args: _ColumnExpressionOrLiteralArgument[Any],
1655 **kwargs: Any,
1656 ) -> None: ...
1657
1658 @overload
1659 def __init__(
1660 self,
1661 col: _T,
1662 *args: _ColumnExpressionOrLiteralArgument[Any],
1663 **kwargs: Any,
1664 ) -> None: ...
1665
1666 def __init__(
1667 self, *args: _ColumnExpressionOrLiteralArgument[_T], **kwargs: Any
1668 ) -> None:
1669 fn_args: Sequence[ColumnElement[Any]] = [
1670 coercions.expect(
1671 roles.ExpressionElementRole,
1672 c,
1673 name=self.name,
1674 apply_propagate_attrs=self,
1675 )
1676 for c in args
1677 ]
1678 kwargs.setdefault("type_", _type_from_args(fn_args))
1679 kwargs["_parsed_args"] = fn_args
1680 super().__init__(*fn_args, **kwargs)
1681
1682
1683class ReturnTypeFromOptionalArgs(ReturnTypeFromArgs[_T]):
1684 inherit_cache = True
1685
1686 @overload
1687 def __init__(
1688 self,
1689 col: ColumnElement[_T],
1690 *args: _ColumnExpressionOrLiteralArgument[Any],
1691 **kwargs: Any,
1692 ) -> None: ...
1693
1694 @overload
1695 def __init__(
1696 self,
1697 col: _ColumnExpressionArgument[Optional[_T]],
1698 *args: _ColumnExpressionOrLiteralArgument[Any],
1699 **kwargs: Any,
1700 ) -> None: ...
1701
1702 @overload
1703 def __init__(
1704 self,
1705 col: Optional[_T],
1706 *args: _ColumnExpressionOrLiteralArgument[Any],
1707 **kwargs: Any,
1708 ) -> None: ...
1709
1710 def __init__(
1711 self,
1712 *args: _ColumnExpressionOrLiteralArgument[Optional[_T]],
1713 **kwargs: Any,
1714 ) -> None:
1715 super().__init__(*args, **kwargs) # type: ignore
1716
1717
1718class coalesce(ReturnTypeFromOptionalArgs[_T]):
1719 _has_args = True
1720 inherit_cache = True
1721
1722
1723class max(ReturnTypeFromArgs[_T]): # noqa: A001
1724 """The SQL MAX() aggregate function."""
1725
1726 inherit_cache = True
1727
1728
1729class min(ReturnTypeFromArgs[_T]): # noqa: A001
1730 """The SQL MIN() aggregate function."""
1731
1732 inherit_cache = True
1733
1734
1735class sum(ReturnTypeFromArgs[_T]): # noqa: A001
1736 """The SQL SUM() aggregate function."""
1737
1738 inherit_cache = True
1739
1740
1741class now(GenericFunction[datetime.datetime]):
1742 """The SQL now() datetime function.
1743
1744 SQLAlchemy dialects will usually render this particular function
1745 in a backend-specific way, such as rendering it as ``CURRENT_TIMESTAMP``.
1746
1747 """
1748
1749 type = sqltypes.DateTime()
1750 inherit_cache = True
1751
1752
1753class concat(GenericFunction[str]):
1754 """The SQL CONCAT() function, which concatenates strings.
1755
1756 E.g.:
1757
1758 .. sourcecode:: pycon+sql
1759
1760 >>> print(select(func.concat("a", "b")))
1761 {printsql}SELECT concat(:concat_2, :concat_3) AS concat_1
1762
1763 String concatenation in SQLAlchemy is more commonly available using the
1764 Python ``+`` operator with string datatypes, which will render a
1765 backend-specific concatenation operator, such as :
1766
1767 .. sourcecode:: pycon+sql
1768
1769 >>> print(select(literal("a") + "b"))
1770 {printsql}SELECT :param_1 || :param_2 AS anon_1
1771
1772
1773 """
1774
1775 type = sqltypes.String()
1776 inherit_cache = True
1777
1778
1779class char_length(GenericFunction[int]):
1780 """The CHAR_LENGTH() SQL function."""
1781
1782 type = sqltypes.Integer()
1783 inherit_cache = True
1784
1785 def __init__(self, arg: _ColumnExpressionArgument[str], **kw: Any) -> None:
1786 # slight hack to limit to just one positional argument
1787 # not sure why this one function has this special treatment
1788 super().__init__(arg, **kw)
1789
1790
1791class random(GenericFunction[float]):
1792 """The RANDOM() SQL function."""
1793
1794 _has_args = True
1795 inherit_cache = True
1796
1797
1798class count(GenericFunction[int]):
1799 r"""The ANSI COUNT aggregate function. With no arguments,
1800 emits COUNT \*.
1801
1802 E.g.::
1803
1804 from sqlalchemy import func
1805 from sqlalchemy import select
1806 from sqlalchemy import table, column
1807
1808 my_table = table("some_table", column("id"))
1809
1810 stmt = select(func.count()).select_from(my_table)
1811
1812 Executing ``stmt`` would emit:
1813
1814 .. sourcecode:: sql
1815
1816 SELECT count(*) AS count_1
1817 FROM some_table
1818
1819
1820 """
1821
1822 type = sqltypes.Integer()
1823 inherit_cache = True
1824
1825 def __init__(
1826 self,
1827 expression: Union[
1828 _ColumnExpressionArgument[Any], _StarOrOne, None
1829 ] = None,
1830 **kwargs: Any,
1831 ) -> None:
1832 if expression is None:
1833 expression = literal_column("*")
1834 super().__init__(expression, **kwargs)
1835
1836
1837class current_date(AnsiFunction[datetime.date]):
1838 """The CURRENT_DATE() SQL function."""
1839
1840 type = sqltypes.Date()
1841 inherit_cache = True
1842
1843
1844class current_time(AnsiFunction[datetime.time]):
1845 """The CURRENT_TIME() SQL function."""
1846
1847 type = sqltypes.Time()
1848 inherit_cache = True
1849
1850
1851class current_timestamp(AnsiFunction[datetime.datetime]):
1852 """The CURRENT_TIMESTAMP() SQL function."""
1853
1854 type = sqltypes.DateTime()
1855 inherit_cache = True
1856
1857
1858class current_user(AnsiFunction[str]):
1859 """The CURRENT_USER() SQL function."""
1860
1861 type = sqltypes.String()
1862 inherit_cache = True
1863
1864
1865class localtime(AnsiFunction[datetime.datetime]):
1866 """The localtime() SQL function."""
1867
1868 type = sqltypes.DateTime()
1869 inherit_cache = True
1870
1871
1872class localtimestamp(AnsiFunction[datetime.datetime]):
1873 """The localtimestamp() SQL function."""
1874
1875 type = sqltypes.DateTime()
1876 inherit_cache = True
1877
1878
1879class session_user(AnsiFunction[str]):
1880 """The SESSION_USER() SQL function."""
1881
1882 type = sqltypes.String()
1883 inherit_cache = True
1884
1885
1886class sysdate(AnsiFunction[datetime.datetime]):
1887 """The SYSDATE() SQL function."""
1888
1889 type = sqltypes.DateTime()
1890 inherit_cache = True
1891
1892
1893class user(AnsiFunction[str]):
1894 """The USER() SQL function."""
1895
1896 type = sqltypes.String()
1897 inherit_cache = True
1898
1899
1900class array_agg(ReturnTypeFromArgs[Sequence[_T]]):
1901 """Support for the ARRAY_AGG function.
1902
1903 The ``func.array_agg(expr)`` construct returns an expression of
1904 type :class:`_types.ARRAY`.
1905
1906 e.g.::
1907
1908 stmt = select(func.array_agg(table.c.values)[2:5])
1909
1910 .. seealso::
1911
1912 :func:`_postgresql.array_agg` - PostgreSQL-specific version that
1913 returns :class:`_postgresql.ARRAY`, which has PG-specific operators
1914 added.
1915
1916 """
1917
1918 inherit_cache = True
1919
1920 def __init__(
1921 self, *args: _ColumnExpressionArgument[Any], **kwargs: Any
1922 ) -> None:
1923 fn_args: Sequence[ColumnElement[Any]] = [
1924 coercions.expect(
1925 roles.ExpressionElementRole, c, apply_propagate_attrs=self
1926 )
1927 for c in args
1928 ]
1929
1930 default_array_type = kwargs.pop("_default_array_type", sqltypes.ARRAY)
1931 if "type_" not in kwargs:
1932 type_from_args = _type_from_args(fn_args)
1933 if isinstance(type_from_args, sqltypes.ARRAY):
1934 kwargs["type_"] = type_from_args
1935 else:
1936 kwargs["type_"] = default_array_type(
1937 type_from_args, dimensions=1
1938 )
1939 kwargs["_parsed_args"] = fn_args
1940 super().__init__(*fn_args, **kwargs)
1941
1942
1943class OrderedSetAgg(GenericFunction[_T]):
1944 """Define a function where the return type is based on the sort
1945 expression type as defined by the expression passed to the
1946 :meth:`.FunctionElement.within_group` method."""
1947
1948 array_for_multi_clause = False
1949 inherit_cache = True
1950
1951 def within_group_type(
1952 self, within_group: WithinGroup[Any]
1953 ) -> TypeEngine[Any]:
1954 func_clauses = cast(ClauseList, self.clause_expr.element)
1955 order_by: Sequence[ColumnElement[Any]] = sqlutil.unwrap_order_by(
1956 within_group.order_by
1957 )
1958 if self.array_for_multi_clause and len(func_clauses.clauses) > 1:
1959 return sqltypes.ARRAY(order_by[0].type)
1960 else:
1961 return order_by[0].type
1962
1963
1964class mode(OrderedSetAgg[_T]):
1965 """Implement the ``mode`` ordered-set aggregate function.
1966
1967 This function must be used with the :meth:`.FunctionElement.within_group`
1968 modifier to supply a sort expression to operate upon.
1969
1970 The return type of this function is the same as the sort expression.
1971
1972 """
1973
1974 inherit_cache = True
1975
1976
1977class percentile_cont(OrderedSetAgg[_T]):
1978 """Implement the ``percentile_cont`` ordered-set aggregate function.
1979
1980 This function must be used with the :meth:`.FunctionElement.within_group`
1981 modifier to supply a sort expression to operate upon.
1982
1983 The return type of this function is the same as the sort expression,
1984 or if the arguments are an array, an :class:`_types.ARRAY` of the sort
1985 expression's type.
1986
1987 """
1988
1989 array_for_multi_clause = True
1990 inherit_cache = True
1991
1992
1993class percentile_disc(OrderedSetAgg[_T]):
1994 """Implement the ``percentile_disc`` ordered-set aggregate function.
1995
1996 This function must be used with the :meth:`.FunctionElement.within_group`
1997 modifier to supply a sort expression to operate upon.
1998
1999 The return type of this function is the same as the sort expression,
2000 or if the arguments are an array, an :class:`_types.ARRAY` of the sort
2001 expression's type.
2002
2003 """
2004
2005 array_for_multi_clause = True
2006 inherit_cache = True
2007
2008
2009class rank(GenericFunction[int]):
2010 """Implement the ``rank`` hypothetical-set aggregate function.
2011
2012 This function must be used with the :meth:`.FunctionElement.within_group`
2013 modifier to supply a sort expression to operate upon.
2014
2015 The return type of this function is :class:`.Integer`.
2016
2017 """
2018
2019 type = sqltypes.Integer()
2020 inherit_cache = True
2021
2022
2023class dense_rank(GenericFunction[int]):
2024 """Implement the ``dense_rank`` hypothetical-set aggregate function.
2025
2026 This function must be used with the :meth:`.FunctionElement.within_group`
2027 modifier to supply a sort expression to operate upon.
2028
2029 The return type of this function is :class:`.Integer`.
2030
2031 """
2032
2033 type = sqltypes.Integer()
2034 inherit_cache = True
2035
2036
2037class percent_rank(GenericFunction[decimal.Decimal]):
2038 """Implement the ``percent_rank`` hypothetical-set aggregate function.
2039
2040 This function must be used with the :meth:`.FunctionElement.within_group`
2041 modifier to supply a sort expression to operate upon.
2042
2043 The return type of this function is :class:`.Numeric`.
2044
2045 """
2046
2047 type: sqltypes.Numeric[decimal.Decimal] = sqltypes.Numeric()
2048 inherit_cache = True
2049
2050
2051class cume_dist(GenericFunction[decimal.Decimal]):
2052 """Implement the ``cume_dist`` hypothetical-set aggregate function.
2053
2054 This function must be used with the :meth:`.FunctionElement.within_group`
2055 modifier to supply a sort expression to operate upon.
2056
2057 The return type of this function is :class:`.Numeric`.
2058
2059 """
2060
2061 type: sqltypes.Numeric[decimal.Decimal] = sqltypes.Numeric()
2062 inherit_cache = True
2063
2064
2065class cube(GenericFunction[_T]):
2066 r"""Implement the ``CUBE`` grouping operation.
2067
2068 This function is used as part of the GROUP BY of a statement,
2069 e.g. :meth:`_expression.Select.group_by`::
2070
2071 stmt = select(
2072 func.sum(table.c.value), table.c.col_1, table.c.col_2
2073 ).group_by(func.cube(table.c.col_1, table.c.col_2))
2074
2075 .. versionadded:: 1.2
2076
2077 """
2078
2079 _has_args = True
2080 inherit_cache = True
2081
2082
2083class rollup(GenericFunction[_T]):
2084 r"""Implement the ``ROLLUP`` grouping operation.
2085
2086 This function is used as part of the GROUP BY of a statement,
2087 e.g. :meth:`_expression.Select.group_by`::
2088
2089 stmt = select(
2090 func.sum(table.c.value), table.c.col_1, table.c.col_2
2091 ).group_by(func.rollup(table.c.col_1, table.c.col_2))
2092
2093 .. versionadded:: 1.2
2094
2095 """
2096
2097 _has_args = True
2098 inherit_cache = True
2099
2100
2101class grouping_sets(GenericFunction[_T]):
2102 r"""Implement the ``GROUPING SETS`` grouping operation.
2103
2104 This function is used as part of the GROUP BY of a statement,
2105 e.g. :meth:`_expression.Select.group_by`::
2106
2107 stmt = select(
2108 func.sum(table.c.value), table.c.col_1, table.c.col_2
2109 ).group_by(func.grouping_sets(table.c.col_1, table.c.col_2))
2110
2111 In order to group by multiple sets, use the :func:`.tuple_` construct::
2112
2113 from sqlalchemy import tuple_
2114
2115 stmt = select(
2116 func.sum(table.c.value), table.c.col_1, table.c.col_2, table.c.col_3
2117 ).group_by(
2118 func.grouping_sets(
2119 tuple_(table.c.col_1, table.c.col_2),
2120 tuple_(table.c.value, table.c.col_3),
2121 )
2122 )
2123
2124 .. versionadded:: 1.2
2125
2126 """ # noqa: E501
2127
2128 _has_args = True
2129 inherit_cache = True
2130
2131
2132class aggregate_strings(GenericFunction[str]):
2133 """Implement a generic string aggregation function.
2134
2135 This function will concatenate non-null values into a string and
2136 separate the values by a delimiter.
2137
2138 This function is compiled on a per-backend basis, into functions
2139 such as ``group_concat()``, ``string_agg()``, or ``LISTAGG()``.
2140
2141 e.g. Example usage with delimiter '.'::
2142
2143 stmt = select(func.aggregate_strings(table.c.str_col, "."))
2144
2145 The return type of this function is :class:`.String`.
2146
2147 .. versionadded: 2.0.21
2148
2149 """
2150
2151 type = sqltypes.String()
2152 _has_args = True
2153 inherit_cache = True
2154
2155 def __init__(
2156 self, clause: _ColumnExpressionArgument[Any], separator: str
2157 ) -> None:
2158 super().__init__(clause, separator)