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