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