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