SQLAlchemy 2.1.0b1__cp313-cp313-win_arm64.whl

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