functions.py 65 KB

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