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