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