Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlalchemy/sql/functions.py: 54%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

536 statements  

1# sql/functions.py 

2# Copyright (C) 2005-2025 the SQLAlchemy authors and contributors 

3# <see AUTHORS file> 

4# 

5# This module is part of SQLAlchemy and is released under 

6# the MIT License: https://www.opensource.org/licenses/mit-license.php 

7 

8"""SQL function API, factories, and built-in functions.""" 

9 

10from __future__ import annotations 

11 

12import datetime 

13import decimal 

14from typing import Any 

15from typing import cast 

16from typing import Dict 

17from typing import List 

18from typing import Mapping 

19from typing import Optional 

20from typing import overload 

21from typing import Sequence 

22from typing import Tuple 

23from typing import Type 

24from typing import TYPE_CHECKING 

25from typing import TypeVar 

26from typing import Union 

27 

28from . import annotation 

29from . import coercions 

30from . import operators 

31from . import roles 

32from . import schema 

33from . import sqltypes 

34from . import type_api 

35from . import util as sqlutil 

36from ._typing import is_table_value_type 

37from .base import _entity_namespace 

38from .base import ColumnCollection 

39from .base import Executable 

40from .base import Generative 

41from .base import HasMemoized 

42from .elements import _type_from_args 

43from .elements import BinaryExpression 

44from .elements import BindParameter 

45from .elements import Cast 

46from .elements import ClauseList 

47from .elements import ColumnElement 

48from .elements import Extract 

49from .elements import FunctionFilter 

50from .elements import Grouping 

51from .elements import literal_column 

52from .elements import NamedColumn 

53from .elements import Over 

54from .elements import WithinGroup 

55from .selectable import FromClause 

56from .selectable import Select 

57from .selectable import TableValuedAlias 

58from .sqltypes import TableValueType 

59from .type_api import TypeEngine 

60from .visitors import InternalTraversal 

61from .. import util 

62 

63 

64if 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 

90def 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 

114class 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 ] 

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.: 

245 

246 .. sourcecode:: pycon+sql 

247 

248 >>> fn = func.generate_series(1, 5).table_valued( 

249 ... "value", "start", "stop", "step" 

250 ... ) 

251 

252 >>> print(select(fn)) 

253 {printsql}SELECT anon_1.value, anon_1.start, anon_1.stop, anon_1.step 

254 FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1{stop} 

255 

256 >>> print(select(fn.c.value, fn.c.stop).where(fn.c.value > 2)) 

257 {printsql}SELECT anon_1.value, anon_1.stop 

258 FROM generate_series(:generate_series_1, :generate_series_2) AS anon_1 

259 WHERE anon_1.value > :value_1{stop} 

260 

261 A WITH ORDINALITY expression may be generated by passing the keyword 

262 argument "with_ordinality": 

263 

264 .. sourcecode:: pycon+sql 

265 

266 >>> fn = func.generate_series(4, 1, -1).table_valued( 

267 ... "gen", with_ordinality="ordinality" 

268 ... ) 

269 >>> print(select(fn)) 

270 {printsql}SELECT anon_1.gen, anon_1.ordinality 

271 FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) WITH ORDINALITY AS anon_1 

272 

273 :param \*expr: A series of string column names that will be added to the 

274 ``.c`` collection of the resulting :class:`_sql.TableValuedAlias` 

275 construct as columns. :func:`_sql.column` objects with or without 

276 datatypes may also be used. 

277 

278 :param name: optional name to assign to the alias name that's generated. 

279 If omitted, a unique anonymizing name is used. 

280 

281 :param with_ordinality: string name that when present results in the 

282 ``WITH ORDINALITY`` clause being added to the alias, and the given 

283 string name will be added as a column to the .c collection 

284 of the resulting :class:`_sql.TableValuedAlias`. 

285 

286 :param joins_implicitly: when True, the table valued function may be 

287 used in the FROM clause without any explicit JOIN to other tables 

288 in the SQL query, and no "cartesian product" warning will be generated. 

289 May be useful for SQL functions such as ``func.json_each()``. 

290 

291 .. versionadded:: 1.4.33 

292 

293 .. versionadded:: 1.4.0b2 

294 

295 

296 .. seealso:: 

297 

298 :ref:`tutorial_functions_table_valued` - in the :ref:`unified_tutorial` 

299 

300 :ref:`postgresql_table_valued` - in the :ref:`postgresql_toplevel` documentation 

301 

302 :meth:`_functions.FunctionElement.scalar_table_valued` - variant of 

303 :meth:`_functions.FunctionElement.table_valued` which delivers the 

304 complete table valued expression as a scalar column expression 

305 

306 :meth:`_functions.FunctionElement.column_valued` 

307 

308 :meth:`_sql.TableValuedAlias.render_derived` - renders the alias 

309 using a derived column clause, e.g. ``AS name(col1, col2, ...)`` 

310 

311 """ # noqa: 501 

312 

313 new_func = self._generate() 

314 

315 with_ordinality = kw.pop("with_ordinality", None) 

316 joins_implicitly = kw.pop("joins_implicitly", None) 

317 name = kw.pop("name", None) 

318 

319 if with_ordinality: 

320 expr += (with_ordinality,) 

321 new_func._with_ordinality = True 

322 

323 new_func.type = new_func._table_value_type = TableValueType(*expr) 

324 

325 return new_func.alias(name=name, joins_implicitly=joins_implicitly) 

326 

327 def column_valued( 

328 self, name: Optional[str] = None, joins_implicitly: bool = False 

329 ) -> TableValuedColumn[_T]: 

330 """Return this :class:`_functions.FunctionElement` as a column expression that 

331 selects from itself as a FROM clause. 

332 

333 E.g.: 

334 

335 .. sourcecode:: pycon+sql 

336 

337 >>> from sqlalchemy import select, func 

338 >>> gs = func.generate_series(1, 5, -1).column_valued() 

339 >>> print(select(gs)) 

340 {printsql}SELECT anon_1 

341 FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) AS anon_1 

342 

343 This is shorthand for:: 

344 

345 gs = func.generate_series(1, 5, -1).alias().column 

346 

347 :param name: optional name to assign to the alias name that's generated. 

348 If omitted, a unique anonymizing name is used. 

349 

350 :param joins_implicitly: when True, the "table" portion of the column 

351 valued function may be a member of the FROM clause without any 

352 explicit JOIN to other tables in the SQL query, and no "cartesian 

353 product" warning will be generated. May be useful for SQL functions 

354 such as ``func.json_array_elements()``. 

355 

356 .. versionadded:: 1.4.46 

357 

358 .. seealso:: 

359 

360 :ref:`tutorial_functions_column_valued` - in the :ref:`unified_tutorial` 

361 

362 :ref:`postgresql_column_valued` - in the :ref:`postgresql_toplevel` documentation 

363 

364 :meth:`_functions.FunctionElement.table_valued` 

365 

366 """ # noqa: 501 

367 

368 return self.alias(name=name, joins_implicitly=joins_implicitly).column 

369 

370 @util.ro_non_memoized_property 

371 def columns(self) -> ColumnCollection[str, KeyedColumnElement[Any]]: # type: ignore[override] # noqa: E501 

372 r"""The set of columns exported by this :class:`.FunctionElement`. 

373 

374 This is a placeholder collection that allows the function to be 

375 placed in the FROM clause of a statement: 

376 

377 .. sourcecode:: pycon+sql 

378 

379 >>> from sqlalchemy import column, select, func 

380 >>> stmt = select(column("x"), column("y")).select_from(func.myfunction()) 

381 >>> print(stmt) 

382 {printsql}SELECT x, y FROM myfunction() 

383 

384 The above form is a legacy feature that is now superseded by the 

385 fully capable :meth:`_functions.FunctionElement.table_valued` 

386 method; see that method for details. 

387 

388 .. seealso:: 

389 

390 :meth:`_functions.FunctionElement.table_valued` - generates table-valued 

391 SQL function expressions. 

392 

393 """ # noqa: E501 

394 return self.c 

395 

396 @util.ro_memoized_property 

397 def c(self) -> ColumnCollection[str, KeyedColumnElement[Any]]: # type: ignore[override] # noqa: E501 

398 """synonym for :attr:`.FunctionElement.columns`.""" 

399 

400 return ColumnCollection( 

401 columns=[(col.key, col) for col in self._all_selected_columns] 

402 ) 

403 

404 @property 

405 def _all_selected_columns(self) -> Sequence[KeyedColumnElement[Any]]: 

406 if is_table_value_type(self.type): 

407 # TODO: this might not be fully accurate 

408 cols = cast( 

409 "Sequence[KeyedColumnElement[Any]]", self.type._elements 

410 ) 

411 else: 

412 cols = [self.label(None)] 

413 

414 return cols 

415 

416 @property 

417 def exported_columns( # type: ignore[override] 

418 self, 

419 ) -> ColumnCollection[str, KeyedColumnElement[Any]]: 

420 return self.columns 

421 

422 @HasMemoized.memoized_attribute 

423 def clauses(self) -> ClauseList: 

424 """Return the underlying :class:`.ClauseList` which contains 

425 the arguments for this :class:`.FunctionElement`. 

426 

427 """ 

428 return cast(ClauseList, self.clause_expr.element) 

429 

430 def over( 

431 self, 

432 *, 

433 partition_by: Optional[_ByArgument] = None, 

434 order_by: Optional[_ByArgument] = None, 

435 rows: Optional[Tuple[Optional[int], Optional[int]]] = None, 

436 range_: Optional[Tuple[Optional[int], Optional[int]]] = None, 

437 groups: Optional[Tuple[Optional[int], Optional[int]]] = None, 

438 ) -> Over[_T]: 

439 """Produce an OVER clause against this function. 

440 

441 Used against aggregate or so-called "window" functions, 

442 for database backends that support window functions. 

443 

444 The expression:: 

445 

446 func.row_number().over(order_by="x") 

447 

448 is shorthand for:: 

449 

450 from sqlalchemy import over 

451 

452 over(func.row_number(), order_by="x") 

453 

454 See :func:`_expression.over` for a full description. 

455 

456 .. seealso:: 

457 

458 :func:`_expression.over` 

459 

460 :ref:`tutorial_window_functions` - in the :ref:`unified_tutorial` 

461 

462 """ 

463 return Over( 

464 self, 

465 partition_by=partition_by, 

466 order_by=order_by, 

467 rows=rows, 

468 range_=range_, 

469 groups=groups, 

470 ) 

471 

472 def within_group( 

473 self, *order_by: _ColumnExpressionArgument[Any] 

474 ) -> WithinGroup[_T]: 

475 """Produce a WITHIN GROUP (ORDER BY expr) clause against this function. 

476 

477 Used against so-called "ordered set aggregate" and "hypothetical 

478 set aggregate" functions, including :class:`.percentile_cont`, 

479 :class:`.rank`, :class:`.dense_rank`, etc. 

480 

481 See :func:`_expression.within_group` for a full description. 

482 

483 .. seealso:: 

484 

485 :ref:`tutorial_functions_within_group` - 

486 in the :ref:`unified_tutorial` 

487 

488 

489 """ 

490 return WithinGroup(self, *order_by) 

491 

492 @overload 

493 def filter(self) -> Self: ... 

494 

495 @overload 

496 def filter( 

497 self, 

498 __criterion0: _ColumnExpressionArgument[bool], 

499 *criterion: _ColumnExpressionArgument[bool], 

500 ) -> FunctionFilter[_T]: ... 

501 

502 def filter( 

503 self, *criterion: _ColumnExpressionArgument[bool] 

504 ) -> Union[Self, FunctionFilter[_T]]: 

505 """Produce a FILTER clause against this function. 

506 

507 Used against aggregate and window functions, 

508 for database backends that support the "FILTER" clause. 

509 

510 The expression:: 

511 

512 func.count(1).filter(True) 

513 

514 is shorthand for:: 

515 

516 from sqlalchemy import funcfilter 

517 

518 funcfilter(func.count(1), True) 

519 

520 .. seealso:: 

521 

522 :ref:`tutorial_functions_within_group` - 

523 in the :ref:`unified_tutorial` 

524 

525 :class:`.FunctionFilter` 

526 

527 :func:`.funcfilter` 

528 

529 

530 """ 

531 if not criterion: 

532 return self 

533 return FunctionFilter(self, *criterion) 

534 

535 def as_comparison( 

536 self, left_index: int, right_index: int 

537 ) -> FunctionAsBinary: 

538 """Interpret this expression as a boolean comparison between two 

539 values. 

540 

541 This method is used for an ORM use case described at 

542 :ref:`relationship_custom_operator_sql_function`. 

543 

544 A hypothetical SQL function "is_equal()" which compares to values 

545 for equality would be written in the Core expression language as:: 

546 

547 expr = func.is_equal("a", "b") 

548 

549 If "is_equal()" above is comparing "a" and "b" for equality, the 

550 :meth:`.FunctionElement.as_comparison` method would be invoked as:: 

551 

552 expr = func.is_equal("a", "b").as_comparison(1, 2) 

553 

554 Where above, the integer value "1" refers to the first argument of the 

555 "is_equal()" function and the integer value "2" refers to the second. 

556 

557 This would create a :class:`.BinaryExpression` that is equivalent to:: 

558 

559 BinaryExpression("a", "b", operator=op.eq) 

560 

561 However, at the SQL level it would still render as 

562 "is_equal('a', 'b')". 

563 

564 The ORM, when it loads a related object or collection, needs to be able 

565 to manipulate the "left" and "right" sides of the ON clause of a JOIN 

566 expression. The purpose of this method is to provide a SQL function 

567 construct that can also supply this information to the ORM, when used 

568 with the :paramref:`_orm.relationship.primaryjoin` parameter. The 

569 return value is a containment object called :class:`.FunctionAsBinary`. 

570 

571 An ORM example is as follows:: 

572 

573 class Venue(Base): 

574 __tablename__ = "venue" 

575 id = Column(Integer, primary_key=True) 

576 name = Column(String) 

577 

578 descendants = relationship( 

579 "Venue", 

580 primaryjoin=func.instr( 

581 remote(foreign(name)), name + "/" 

582 ).as_comparison(1, 2) 

583 == 1, 

584 viewonly=True, 

585 order_by=name, 

586 ) 

587 

588 Above, the "Venue" class can load descendant "Venue" objects by 

589 determining if the name of the parent Venue is contained within the 

590 start of the hypothetical descendant value's name, e.g. "parent1" would 

591 match up to "parent1/child1", but not to "parent2/child1". 

592 

593 Possible use cases include the "materialized path" example given above, 

594 as well as making use of special SQL functions such as geometric 

595 functions to create join conditions. 

596 

597 :param left_index: the integer 1-based index of the function argument 

598 that serves as the "left" side of the expression. 

599 :param right_index: the integer 1-based index of the function argument 

600 that serves as the "right" side of the expression. 

601 

602 .. seealso:: 

603 

604 :ref:`relationship_custom_operator_sql_function` - 

605 example use within the ORM 

606 

607 """ 

608 return FunctionAsBinary(self, left_index, right_index) 

609 

610 @property 

611 def _from_objects(self) -> Any: 

612 return self.clauses._from_objects 

613 

614 def within_group_type( 

615 self, within_group: WithinGroup[_S] 

616 ) -> Optional[TypeEngine[_S]]: 

617 """For types that define their return type as based on the criteria 

618 within a WITHIN GROUP (ORDER BY) expression, called by the 

619 :class:`.WithinGroup` construct. 

620 

621 Returns None by default, in which case the function's normal ``.type`` 

622 is used. 

623 

624 """ 

625 

626 return None 

627 

628 def alias( 

629 self, name: Optional[str] = None, joins_implicitly: bool = False 

630 ) -> TableValuedAlias: 

631 r"""Produce a :class:`_expression.Alias` construct against this 

632 :class:`.FunctionElement`. 

633 

634 .. tip:: 

635 

636 The :meth:`_functions.FunctionElement.alias` method is part of the 

637 mechanism by which "table valued" SQL functions are created. 

638 However, most use cases are covered by higher level methods on 

639 :class:`_functions.FunctionElement` including 

640 :meth:`_functions.FunctionElement.table_valued`, and 

641 :meth:`_functions.FunctionElement.column_valued`. 

642 

643 This construct wraps the function in a named alias which 

644 is suitable for the FROM clause, in the style accepted for example 

645 by PostgreSQL. A column expression is also provided using the 

646 special ``.column`` attribute, which may 

647 be used to refer to the output of the function as a scalar value 

648 in the columns or where clause, for a backend such as PostgreSQL. 

649 

650 For a full table-valued expression, use the 

651 :meth:`_functions.FunctionElement.table_valued` method first to 

652 establish named columns. 

653 

654 e.g.: 

655 

656 .. sourcecode:: pycon+sql 

657 

658 >>> from sqlalchemy import func, select, column 

659 >>> data_view = func.unnest([1, 2, 3]).alias("data_view") 

660 >>> print(select(data_view.column)) 

661 {printsql}SELECT data_view 

662 FROM unnest(:unnest_1) AS data_view 

663 

664 The :meth:`_functions.FunctionElement.column_valued` method provides 

665 a shortcut for the above pattern: 

666 

667 .. sourcecode:: pycon+sql 

668 

669 >>> data_view = func.unnest([1, 2, 3]).column_valued("data_view") 

670 >>> print(select(data_view)) 

671 {printsql}SELECT data_view 

672 FROM unnest(:unnest_1) AS data_view 

673 

674 .. versionadded:: 1.4.0b2 Added the ``.column`` accessor 

675 

676 :param name: alias name, will be rendered as ``AS <name>`` in the 

677 FROM clause 

678 

679 :param joins_implicitly: when True, the table valued function may be 

680 used in the FROM clause without any explicit JOIN to other tables 

681 in the SQL query, and no "cartesian product" warning will be 

682 generated. May be useful for SQL functions such as 

683 ``func.json_each()``. 

684 

685 .. versionadded:: 1.4.33 

686 

687 .. seealso:: 

688 

689 :ref:`tutorial_functions_table_valued` - 

690 in the :ref:`unified_tutorial` 

691 

692 :meth:`_functions.FunctionElement.table_valued` 

693 

694 :meth:`_functions.FunctionElement.scalar_table_valued` 

695 

696 :meth:`_functions.FunctionElement.column_valued` 

697 

698 

699 """ 

700 

701 return TableValuedAlias._construct( 

702 self, 

703 name=name, 

704 table_value_type=self.type, 

705 joins_implicitly=joins_implicitly, 

706 ) 

707 

708 def select(self) -> Select[_T]: 

709 """Produce a :func:`_expression.select` construct 

710 against this :class:`.FunctionElement`. 

711 

712 This is shorthand for:: 

713 

714 s = select(function_element) 

715 

716 """ 

717 s: Select[_T] = Select(self) 

718 if self._execution_options: 

719 s = s.execution_options(**self._execution_options) 

720 return s 

721 

722 def _bind_param( 

723 self, 

724 operator: OperatorType, 

725 obj: Any, 

726 type_: Optional[TypeEngine[_T]] = None, 

727 expanding: bool = False, 

728 **kw: Any, 

729 ) -> BindParameter[_T]: 

730 return BindParameter( 

731 None, 

732 obj, 

733 _compared_to_operator=operator, 

734 _compared_to_type=self.type, 

735 unique=True, 

736 type_=type_, 

737 expanding=expanding, 

738 **kw, 

739 ) 

740 

741 def self_group(self, against: Optional[OperatorType] = None) -> ClauseElement: # type: ignore[override] # noqa E501 

742 # for the moment, we are parenthesizing all array-returning 

743 # expressions against getitem. This may need to be made 

744 # more portable if in the future we support other DBs 

745 # besides postgresql. 

746 if against in (operators.getitem, operators.json_getitem_op): 

747 return Grouping(self) 

748 else: 

749 return super().self_group(against=against) 

750 

751 @property 

752 def entity_namespace(self) -> _EntityNamespace: 

753 """overrides FromClause.entity_namespace as functions are generally 

754 column expressions and not FromClauses. 

755 

756 """ 

757 # ideally functions would not be fromclauses but we failed to make 

758 # this adjustment in 1.4 

759 return _entity_namespace(self.clause_expr) 

760 

761 

762class FunctionAsBinary(BinaryExpression[Any]): 

763 _traverse_internals = [ 

764 ("sql_function", InternalTraversal.dp_clauseelement), 

765 ("left_index", InternalTraversal.dp_plain_obj), 

766 ("right_index", InternalTraversal.dp_plain_obj), 

767 ("modifiers", InternalTraversal.dp_plain_dict), 

768 ] 

769 

770 sql_function: FunctionElement[Any] 

771 left_index: int 

772 right_index: int 

773 

774 def _gen_cache_key(self, anon_map: Any, bindparams: Any) -> Any: 

775 return ColumnElement._gen_cache_key(self, anon_map, bindparams) 

776 

777 def __init__( 

778 self, fn: FunctionElement[Any], left_index: int, right_index: int 

779 ) -> None: 

780 self.sql_function = fn 

781 self.left_index = left_index 

782 self.right_index = right_index 

783 

784 self.operator = operators.function_as_comparison_op 

785 self.type = sqltypes.BOOLEANTYPE 

786 self.negate = None 

787 self._is_implicitly_boolean = True 

788 self.modifiers = util.immutabledict({}) 

789 

790 @property 

791 def left_expr(self) -> ColumnElement[Any]: 

792 return self.sql_function.clauses.clauses[self.left_index - 1] 

793 

794 @left_expr.setter 

795 def left_expr(self, value: ColumnElement[Any]) -> None: 

796 self.sql_function.clauses.clauses[self.left_index - 1] = value 

797 

798 @property 

799 def right_expr(self) -> ColumnElement[Any]: 

800 return self.sql_function.clauses.clauses[self.right_index - 1] 

801 

802 @right_expr.setter 

803 def right_expr(self, value: ColumnElement[Any]) -> None: 

804 self.sql_function.clauses.clauses[self.right_index - 1] = value 

805 

806 if not TYPE_CHECKING: 

807 # mypy can't accommodate @property to replace an instance 

808 # variable 

809 

810 left = left_expr 

811 right = right_expr 

812 

813 

814class ScalarFunctionColumn(NamedColumn[_T]): 

815 __visit_name__ = "scalar_function_column" 

816 

817 _traverse_internals = [ 

818 ("name", InternalTraversal.dp_anon_name), 

819 ("type", InternalTraversal.dp_type), 

820 ("fn", InternalTraversal.dp_clauseelement), 

821 ] 

822 

823 is_literal = False 

824 table = None 

825 

826 def __init__( 

827 self, 

828 fn: FunctionElement[_T], 

829 name: str, 

830 type_: Optional[_TypeEngineArgument[_T]] = None, 

831 ) -> None: 

832 self.fn = fn 

833 self.name = name 

834 

835 # if type is None, we get NULLTYPE, which is our _T. But I don't 

836 # know how to get the overloads to express that correctly 

837 self.type = type_api.to_instance(type_) # type: ignore 

838 

839 

840class _FunctionGenerator: 

841 """Generate SQL function expressions. 

842 

843 :data:`.func` is a special object instance which generates SQL 

844 functions based on name-based attributes, e.g.: 

845 

846 .. sourcecode:: pycon+sql 

847 

848 >>> print(func.count(1)) 

849 {printsql}count(:param_1) 

850 

851 The returned object is an instance of :class:`.Function`, and is a 

852 column-oriented SQL element like any other, and is used in that way: 

853 

854 .. sourcecode:: pycon+sql 

855 

856 >>> print(select(func.count(table.c.id))) 

857 {printsql}SELECT count(sometable.id) FROM sometable 

858 

859 Any name can be given to :data:`.func`. If the function name is unknown to 

860 SQLAlchemy, it will be rendered exactly as is. For common SQL functions 

861 which SQLAlchemy is aware of, the name may be interpreted as a *generic 

862 function* which will be compiled appropriately to the target database: 

863 

864 .. sourcecode:: pycon+sql 

865 

866 >>> print(func.current_timestamp()) 

867 {printsql}CURRENT_TIMESTAMP 

868 

869 To call functions which are present in dot-separated packages, 

870 specify them in the same manner: 

871 

872 .. sourcecode:: pycon+sql 

873 

874 >>> print(func.stats.yield_curve(5, 10)) 

875 {printsql}stats.yield_curve(:yield_curve_1, :yield_curve_2) 

876 

877 SQLAlchemy can be made aware of the return type of functions to enable 

878 type-specific lexical and result-based behavior. For example, to ensure 

879 that a string-based function returns a Unicode value and is similarly 

880 treated as a string in expressions, specify 

881 :class:`~sqlalchemy.types.Unicode` as the type: 

882 

883 .. sourcecode:: pycon+sql 

884 

885 >>> print( 

886 ... func.my_string("hi", type_=Unicode) 

887 ... + " " 

888 ... + func.my_string("there", type_=Unicode) 

889 ... ) 

890 {printsql}my_string(:my_string_1) || :my_string_2 || my_string(:my_string_3) 

891 

892 The object returned by a :data:`.func` call is usually an instance of 

893 :class:`.Function`. 

894 This object meets the "column" interface, including comparison and labeling 

895 functions. The object can also be passed the :meth:`~.Connectable.execute` 

896 method of a :class:`_engine.Connection` or :class:`_engine.Engine`, 

897 where it will be 

898 wrapped inside of a SELECT statement first:: 

899 

900 print(connection.execute(func.current_timestamp()).scalar()) 

901 

902 In a few exception cases, the :data:`.func` accessor 

903 will redirect a name to a built-in expression such as :func:`.cast` 

904 or :func:`.extract`, as these names have well-known meaning 

905 but are not exactly the same as "functions" from a SQLAlchemy 

906 perspective. 

907 

908 Functions which are interpreted as "generic" functions know how to 

909 calculate their return type automatically. For a listing of known generic 

910 functions, see :ref:`generic_functions`. 

911 

912 .. note:: 

913 

914 The :data:`.func` construct has only limited support for calling 

915 standalone "stored procedures", especially those with special 

916 parameterization concerns. 

917 

918 See the section :ref:`stored_procedures` for details on how to use 

919 the DBAPI-level ``callproc()`` method for fully traditional stored 

920 procedures. 

921 

922 .. seealso:: 

923 

924 :ref:`tutorial_functions` - in the :ref:`unified_tutorial` 

925 

926 :class:`.Function` 

927 

928 """ # noqa 

929 

930 def __init__(self, **opts: Any) -> None: 

931 self.__names: List[str] = [] 

932 self.opts = opts 

933 

934 def __getattr__(self, name: str) -> _FunctionGenerator: 

935 # passthru __ attributes; fixes pydoc 

936 if name.startswith("__"): 

937 try: 

938 return self.__dict__[name] # type: ignore 

939 except KeyError: 

940 raise AttributeError(name) 

941 

942 elif name.endswith("_"): 

943 name = name[0:-1] 

944 f = _FunctionGenerator(**self.opts) 

945 f.__names = list(self.__names) + [name] 

946 return f 

947 

948 @overload 

949 def __call__( 

950 self, *c: Any, type_: _TypeEngineArgument[_T], **kwargs: Any 

951 ) -> Function[_T]: ... 

952 

953 @overload 

954 def __call__(self, *c: Any, **kwargs: Any) -> Function[Any]: ... 

955 

956 def __call__(self, *c: Any, **kwargs: Any) -> Function[Any]: 

957 o = self.opts.copy() 

958 o.update(kwargs) 

959 

960 tokens = len(self.__names) 

961 

962 if tokens == 2: 

963 package, fname = self.__names 

964 elif tokens == 1: 

965 package, fname = "_default", self.__names[0] 

966 else: 

967 package = None 

968 

969 if package is not None: 

970 func = _registry[package].get(fname.lower()) 

971 if func is not None: 

972 return func(*c, **o) 

973 

974 return Function( 

975 self.__names[-1], packagenames=tuple(self.__names[0:-1]), *c, **o 

976 ) 

977 

978 if TYPE_CHECKING: 

979 # START GENERATED FUNCTION ACCESSORS 

980 

981 # code within this block is **programmatically, 

982 # statically generated** by tools/generate_sql_functions.py 

983 

984 @property 

985 def aggregate_strings(self) -> Type[aggregate_strings]: ... 

986 

987 @property 

988 def ansifunction(self) -> Type[AnsiFunction[Any]]: ... 

989 

990 # set ColumnElement[_T] as a separate overload, to appease 

991 # mypy which seems to not want to accept _T from 

992 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

993 # _HasClauseElement as of mypy 1.15 

994 

995 @overload 

996 def array_agg( 

997 self, 

998 col: ColumnElement[_T], 

999 *args: _ColumnExpressionOrLiteralArgument[Any], 

1000 **kwargs: Any, 

1001 ) -> array_agg[_T]: ... 

1002 

1003 @overload 

1004 def array_agg( 

1005 self, 

1006 col: _ColumnExpressionArgument[_T], 

1007 *args: _ColumnExpressionOrLiteralArgument[Any], 

1008 **kwargs: Any, 

1009 ) -> array_agg[_T]: ... 

1010 

1011 @overload 

1012 def array_agg( 

1013 self, 

1014 col: _T, 

1015 *args: _ColumnExpressionOrLiteralArgument[Any], 

1016 **kwargs: Any, 

1017 ) -> array_agg[_T]: ... 

1018 

1019 def array_agg( 

1020 self, 

1021 col: _ColumnExpressionOrLiteralArgument[_T], 

1022 *args: _ColumnExpressionOrLiteralArgument[Any], 

1023 **kwargs: Any, 

1024 ) -> array_agg[_T]: ... 

1025 

1026 @property 

1027 def cast(self) -> Type[Cast[Any]]: ... 

1028 

1029 @property 

1030 def char_length(self) -> Type[char_length]: ... 

1031 

1032 # set ColumnElement[_T] as a separate overload, to appease 

1033 # mypy which seems to not want to accept _T from 

1034 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1035 # _HasClauseElement as of mypy 1.15 

1036 

1037 @overload 

1038 def coalesce( 

1039 self, 

1040 col: ColumnElement[_T], 

1041 *args: _ColumnExpressionOrLiteralArgument[Any], 

1042 **kwargs: Any, 

1043 ) -> coalesce[_T]: ... 

1044 

1045 @overload 

1046 def coalesce( 

1047 self, 

1048 col: _ColumnExpressionArgument[_T], 

1049 *args: _ColumnExpressionOrLiteralArgument[Any], 

1050 **kwargs: Any, 

1051 ) -> coalesce[_T]: ... 

1052 

1053 @overload 

1054 def coalesce( 

1055 self, 

1056 col: _T, 

1057 *args: _ColumnExpressionOrLiteralArgument[Any], 

1058 **kwargs: Any, 

1059 ) -> coalesce[_T]: ... 

1060 

1061 def coalesce( 

1062 self, 

1063 col: _ColumnExpressionOrLiteralArgument[_T], 

1064 *args: _ColumnExpressionOrLiteralArgument[Any], 

1065 **kwargs: Any, 

1066 ) -> coalesce[_T]: ... 

1067 

1068 @property 

1069 def concat(self) -> Type[concat]: ... 

1070 

1071 @property 

1072 def count(self) -> Type[count]: ... 

1073 

1074 @property 

1075 def cube(self) -> Type[cube[Any]]: ... 

1076 

1077 @property 

1078 def cume_dist(self) -> Type[cume_dist]: ... 

1079 

1080 @property 

1081 def current_date(self) -> Type[current_date]: ... 

1082 

1083 @property 

1084 def current_time(self) -> Type[current_time]: ... 

1085 

1086 @property 

1087 def current_timestamp(self) -> Type[current_timestamp]: ... 

1088 

1089 @property 

1090 def current_user(self) -> Type[current_user]: ... 

1091 

1092 @property 

1093 def dense_rank(self) -> Type[dense_rank]: ... 

1094 

1095 @property 

1096 def extract(self) -> Type[Extract]: ... 

1097 

1098 @property 

1099 def grouping_sets(self) -> Type[grouping_sets[Any]]: ... 

1100 

1101 @property 

1102 def localtime(self) -> Type[localtime]: ... 

1103 

1104 @property 

1105 def localtimestamp(self) -> Type[localtimestamp]: ... 

1106 

1107 # set ColumnElement[_T] as a separate overload, to appease 

1108 # mypy which seems to not want to accept _T from 

1109 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1110 # _HasClauseElement as of mypy 1.15 

1111 

1112 @overload 

1113 def max( # noqa: A001 

1114 self, 

1115 col: ColumnElement[_T], 

1116 *args: _ColumnExpressionOrLiteralArgument[Any], 

1117 **kwargs: Any, 

1118 ) -> max[_T]: ... 

1119 

1120 @overload 

1121 def max( # noqa: A001 

1122 self, 

1123 col: _ColumnExpressionArgument[_T], 

1124 *args: _ColumnExpressionOrLiteralArgument[Any], 

1125 **kwargs: Any, 

1126 ) -> max[_T]: ... 

1127 

1128 @overload 

1129 def max( # noqa: A001 

1130 self, 

1131 col: _T, 

1132 *args: _ColumnExpressionOrLiteralArgument[Any], 

1133 **kwargs: Any, 

1134 ) -> max[_T]: ... 

1135 

1136 def max( # noqa: A001 

1137 self, 

1138 col: _ColumnExpressionOrLiteralArgument[_T], 

1139 *args: _ColumnExpressionOrLiteralArgument[Any], 

1140 **kwargs: Any, 

1141 ) -> max[_T]: ... 

1142 

1143 # set ColumnElement[_T] as a separate overload, to appease 

1144 # mypy which seems to not want to accept _T from 

1145 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1146 # _HasClauseElement as of mypy 1.15 

1147 

1148 @overload 

1149 def min( # noqa: A001 

1150 self, 

1151 col: ColumnElement[_T], 

1152 *args: _ColumnExpressionOrLiteralArgument[Any], 

1153 **kwargs: Any, 

1154 ) -> min[_T]: ... 

1155 

1156 @overload 

1157 def min( # noqa: A001 

1158 self, 

1159 col: _ColumnExpressionArgument[_T], 

1160 *args: _ColumnExpressionOrLiteralArgument[Any], 

1161 **kwargs: Any, 

1162 ) -> min[_T]: ... 

1163 

1164 @overload 

1165 def min( # noqa: A001 

1166 self, 

1167 col: _T, 

1168 *args: _ColumnExpressionOrLiteralArgument[Any], 

1169 **kwargs: Any, 

1170 ) -> min[_T]: ... 

1171 

1172 def min( # noqa: A001 

1173 self, 

1174 col: _ColumnExpressionOrLiteralArgument[_T], 

1175 *args: _ColumnExpressionOrLiteralArgument[Any], 

1176 **kwargs: Any, 

1177 ) -> min[_T]: ... 

1178 

1179 @property 

1180 def mode(self) -> Type[mode[Any]]: ... 

1181 

1182 @property 

1183 def next_value(self) -> Type[next_value]: ... 

1184 

1185 @property 

1186 def now(self) -> Type[now]: ... 

1187 

1188 @property 

1189 def orderedsetagg(self) -> Type[OrderedSetAgg[Any]]: ... 

1190 

1191 @property 

1192 def percent_rank(self) -> Type[percent_rank]: ... 

1193 

1194 @property 

1195 def percentile_cont(self) -> Type[percentile_cont[Any]]: ... 

1196 

1197 @property 

1198 def percentile_disc(self) -> Type[percentile_disc[Any]]: ... 

1199 

1200 # set ColumnElement[_T] as a separate overload, to appease 

1201 # mypy which seems to not want to accept _T from 

1202 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1203 # _HasClauseElement as of mypy 1.15 

1204 

1205 @overload 

1206 def pow( # noqa: A001 

1207 self, 

1208 col: ColumnElement[_T], 

1209 *args: _ColumnExpressionOrLiteralArgument[Any], 

1210 **kwargs: Any, 

1211 ) -> pow[_T]: ... 

1212 

1213 @overload 

1214 def pow( # noqa: A001 

1215 self, 

1216 col: _ColumnExpressionArgument[_T], 

1217 *args: _ColumnExpressionOrLiteralArgument[Any], 

1218 **kwargs: Any, 

1219 ) -> pow[_T]: ... 

1220 

1221 @overload 

1222 def pow( # noqa: A001 

1223 self, 

1224 col: _T, 

1225 *args: _ColumnExpressionOrLiteralArgument[Any], 

1226 **kwargs: Any, 

1227 ) -> pow[_T]: ... 

1228 

1229 def pow( # noqa: A001 

1230 self, 

1231 col: _ColumnExpressionOrLiteralArgument[_T], 

1232 *args: _ColumnExpressionOrLiteralArgument[Any], 

1233 **kwargs: Any, 

1234 ) -> pow[_T]: ... 

1235 

1236 @property 

1237 def random(self) -> Type[random]: ... 

1238 

1239 @property 

1240 def rank(self) -> Type[rank]: ... 

1241 

1242 @property 

1243 def rollup(self) -> Type[rollup[Any]]: ... 

1244 

1245 @property 

1246 def session_user(self) -> Type[session_user]: ... 

1247 

1248 # set ColumnElement[_T] as a separate overload, to appease 

1249 # mypy which seems to not want to accept _T from 

1250 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1251 # _HasClauseElement as of mypy 1.15 

1252 

1253 @overload 

1254 def sum( # noqa: A001 

1255 self, 

1256 col: ColumnElement[_T], 

1257 *args: _ColumnExpressionOrLiteralArgument[Any], 

1258 **kwargs: Any, 

1259 ) -> sum[_T]: ... 

1260 

1261 @overload 

1262 def sum( # noqa: A001 

1263 self, 

1264 col: _ColumnExpressionArgument[_T], 

1265 *args: _ColumnExpressionOrLiteralArgument[Any], 

1266 **kwargs: Any, 

1267 ) -> sum[_T]: ... 

1268 

1269 @overload 

1270 def sum( # noqa: A001 

1271 self, 

1272 col: _T, 

1273 *args: _ColumnExpressionOrLiteralArgument[Any], 

1274 **kwargs: Any, 

1275 ) -> sum[_T]: ... 

1276 

1277 def sum( # noqa: A001 

1278 self, 

1279 col: _ColumnExpressionOrLiteralArgument[_T], 

1280 *args: _ColumnExpressionOrLiteralArgument[Any], 

1281 **kwargs: Any, 

1282 ) -> sum[_T]: ... 

1283 

1284 @property 

1285 def sysdate(self) -> Type[sysdate]: ... 

1286 

1287 @property 

1288 def user(self) -> Type[user]: ... 

1289 

1290 # END GENERATED FUNCTION ACCESSORS 

1291 

1292 

1293func = _FunctionGenerator() 

1294func.__doc__ = _FunctionGenerator.__doc__ 

1295 

1296modifier = _FunctionGenerator(group=False) 

1297 

1298 

1299class Function(FunctionElement[_T]): 

1300 r"""Describe a named SQL function. 

1301 

1302 The :class:`.Function` object is typically generated from the 

1303 :data:`.func` generation object. 

1304 

1305 

1306 :param \*clauses: list of column expressions that form the arguments 

1307 of the SQL function call. 

1308 

1309 :param type\_: optional :class:`.TypeEngine` datatype object that will be 

1310 used as the return value of the column expression generated by this 

1311 function call. 

1312 

1313 :param packagenames: a string which indicates package prefix names 

1314 to be prepended to the function name when the SQL is generated. 

1315 The :data:`.func` generator creates these when it is called using 

1316 dotted format, e.g.:: 

1317 

1318 func.mypackage.some_function(col1, col2) 

1319 

1320 .. seealso:: 

1321 

1322 :ref:`tutorial_functions` - in the :ref:`unified_tutorial` 

1323 

1324 :data:`.func` - namespace which produces registered or ad-hoc 

1325 :class:`.Function` instances. 

1326 

1327 :class:`.GenericFunction` - allows creation of registered function 

1328 types. 

1329 

1330 """ 

1331 

1332 __visit_name__ = "function" 

1333 

1334 _traverse_internals = FunctionElement._traverse_internals + [ 

1335 ("packagenames", InternalTraversal.dp_plain_obj), 

1336 ("name", InternalTraversal.dp_string), 

1337 ("type", InternalTraversal.dp_type), 

1338 ] 

1339 

1340 name: str 

1341 

1342 identifier: str 

1343 

1344 type: TypeEngine[_T] 

1345 """A :class:`_types.TypeEngine` object which refers to the SQL return 

1346 type represented by this SQL function. 

1347 

1348 This datatype may be configured when generating a 

1349 :class:`_functions.Function` object by passing the 

1350 :paramref:`_functions.Function.type_` parameter, e.g.:: 

1351 

1352 >>> select(func.lower("some VALUE", type_=String)) 

1353 

1354 The small number of built-in classes of :class:`_functions.Function` come 

1355 with a built-in datatype that's appropriate to the class of function and 

1356 its arguments. For functions that aren't known, the type defaults to the 

1357 "null type". 

1358 

1359 """ 

1360 

1361 @overload 

1362 def __init__( 

1363 self, 

1364 name: str, 

1365 *clauses: _ColumnExpressionOrLiteralArgument[_T], 

1366 type_: None = ..., 

1367 packagenames: Optional[Tuple[str, ...]] = ..., 

1368 ) -> None: ... 

1369 

1370 @overload 

1371 def __init__( 

1372 self, 

1373 name: str, 

1374 *clauses: _ColumnExpressionOrLiteralArgument[Any], 

1375 type_: _TypeEngineArgument[_T] = ..., 

1376 packagenames: Optional[Tuple[str, ...]] = ..., 

1377 ) -> None: ... 

1378 

1379 def __init__( 

1380 self, 

1381 name: str, 

1382 *clauses: _ColumnExpressionOrLiteralArgument[Any], 

1383 type_: Optional[_TypeEngineArgument[_T]] = None, 

1384 packagenames: Optional[Tuple[str, ...]] = None, 

1385 ) -> None: 

1386 """Construct a :class:`.Function`. 

1387 

1388 The :data:`.func` construct is normally used to construct 

1389 new :class:`.Function` instances. 

1390 

1391 """ 

1392 self.packagenames = packagenames or () 

1393 self.name = name 

1394 

1395 # if type is None, we get NULLTYPE, which is our _T. But I don't 

1396 # know how to get the overloads to express that correctly 

1397 self.type = type_api.to_instance(type_) # type: ignore 

1398 

1399 FunctionElement.__init__(self, *clauses) 

1400 

1401 def _bind_param( 

1402 self, 

1403 operator: OperatorType, 

1404 obj: Any, 

1405 type_: Optional[TypeEngine[_T]] = None, 

1406 expanding: bool = False, 

1407 **kw: Any, 

1408 ) -> BindParameter[_T]: 

1409 return BindParameter( 

1410 self.name, 

1411 obj, 

1412 _compared_to_operator=operator, 

1413 _compared_to_type=self.type, 

1414 type_=type_, 

1415 unique=True, 

1416 expanding=expanding, 

1417 **kw, 

1418 ) 

1419 

1420 

1421class GenericFunction(Function[_T]): 

1422 """Define a 'generic' function. 

1423 

1424 A generic function is a pre-established :class:`.Function` 

1425 class that is instantiated automatically when called 

1426 by name from the :data:`.func` attribute. Note that 

1427 calling any name from :data:`.func` has the effect that 

1428 a new :class:`.Function` instance is created automatically, 

1429 given that name. The primary use case for defining 

1430 a :class:`.GenericFunction` class is so that a function 

1431 of a particular name may be given a fixed return type. 

1432 It can also include custom argument parsing schemes as well 

1433 as additional methods. 

1434 

1435 Subclasses of :class:`.GenericFunction` are automatically 

1436 registered under the name of the class. For 

1437 example, a user-defined function ``as_utc()`` would 

1438 be available immediately:: 

1439 

1440 from sqlalchemy.sql.functions import GenericFunction 

1441 from sqlalchemy.types import DateTime 

1442 

1443 

1444 class as_utc(GenericFunction): 

1445 type = DateTime() 

1446 inherit_cache = True 

1447 

1448 

1449 print(select(func.as_utc())) 

1450 

1451 User-defined generic functions can be organized into 

1452 packages by specifying the "package" attribute when defining 

1453 :class:`.GenericFunction`. Third party libraries 

1454 containing many functions may want to use this in order 

1455 to avoid name conflicts with other systems. For example, 

1456 if our ``as_utc()`` function were part of a package 

1457 "time":: 

1458 

1459 class as_utc(GenericFunction): 

1460 type = DateTime() 

1461 package = "time" 

1462 inherit_cache = True 

1463 

1464 The above function would be available from :data:`.func` 

1465 using the package name ``time``:: 

1466 

1467 print(select(func.time.as_utc())) 

1468 

1469 A final option is to allow the function to be accessed 

1470 from one name in :data:`.func` but to render as a different name. 

1471 The ``identifier`` attribute will override the name used to 

1472 access the function as loaded from :data:`.func`, but will retain 

1473 the usage of ``name`` as the rendered name:: 

1474 

1475 class GeoBuffer(GenericFunction): 

1476 type = Geometry() 

1477 package = "geo" 

1478 name = "ST_Buffer" 

1479 identifier = "buffer" 

1480 inherit_cache = True 

1481 

1482 The above function will render as follows: 

1483 

1484 .. sourcecode:: pycon+sql 

1485 

1486 >>> print(func.geo.buffer()) 

1487 {printsql}ST_Buffer() 

1488 

1489 The name will be rendered as is, however without quoting unless the name 

1490 contains special characters that require quoting. To force quoting 

1491 on or off for the name, use the :class:`.sqlalchemy.sql.quoted_name` 

1492 construct:: 

1493 

1494 from sqlalchemy.sql import quoted_name 

1495 

1496 

1497 class GeoBuffer(GenericFunction): 

1498 type = Geometry() 

1499 package = "geo" 

1500 name = quoted_name("ST_Buffer", True) 

1501 identifier = "buffer" 

1502 inherit_cache = True 

1503 

1504 The above function will render as: 

1505 

1506 .. sourcecode:: pycon+sql 

1507 

1508 >>> print(func.geo.buffer()) 

1509 {printsql}"ST_Buffer"() 

1510 

1511 Type parameters for this class as a 

1512 `generic type <https://peps.python.org/pep-0484/#generics>`_ can be passed 

1513 and should match the type seen in a :class:`_engine.Result`. For example:: 

1514 

1515 class as_utc(GenericFunction[datetime.datetime]): 

1516 type = DateTime() 

1517 inherit_cache = True 

1518 

1519 The above indicates that the following expression returns a ``datetime`` 

1520 object:: 

1521 

1522 connection.scalar(select(func.as_utc())) 

1523 

1524 """ 

1525 

1526 coerce_arguments = True 

1527 inherit_cache = True 

1528 

1529 _register: bool 

1530 

1531 name = "GenericFunction" 

1532 

1533 def __init_subclass__(cls) -> None: 

1534 if annotation.Annotated not in cls.__mro__: 

1535 cls._register_generic_function(cls.__name__, cls.__dict__) 

1536 super().__init_subclass__() 

1537 

1538 @classmethod 

1539 def _register_generic_function( 

1540 cls, clsname: str, clsdict: Mapping[str, Any] 

1541 ) -> None: 

1542 cls.name = name = clsdict.get("name", clsname) 

1543 cls.identifier = identifier = clsdict.get("identifier", name) 

1544 package = clsdict.get("package", "_default") 

1545 # legacy 

1546 if "__return_type__" in clsdict: 

1547 cls.type = clsdict["__return_type__"] 

1548 

1549 # Check _register attribute status 

1550 cls._register = getattr(cls, "_register", True) 

1551 

1552 # Register the function if required 

1553 if cls._register: 

1554 register_function(identifier, cls, package) 

1555 else: 

1556 # Set _register to True to register child classes by default 

1557 cls._register = True 

1558 

1559 def __init__( 

1560 self, *args: _ColumnExpressionOrLiteralArgument[Any], **kwargs: Any 

1561 ) -> None: 

1562 parsed_args = kwargs.pop("_parsed_args", None) 

1563 if parsed_args is None: 

1564 parsed_args = [ 

1565 coercions.expect( 

1566 roles.ExpressionElementRole, 

1567 c, 

1568 name=self.name, 

1569 apply_propagate_attrs=self, 

1570 ) 

1571 for c in args 

1572 ] 

1573 self._has_args = self._has_args or bool(parsed_args) 

1574 self.packagenames = () 

1575 

1576 self.clause_expr = Grouping( 

1577 ClauseList( 

1578 operator=operators.comma_op, group_contents=True, *parsed_args 

1579 ) 

1580 ) 

1581 

1582 self.type = type_api.to_instance( # type: ignore 

1583 kwargs.pop("type_", None) or getattr(self, "type", None) 

1584 ) 

1585 

1586 

1587register_function("cast", Cast) # type: ignore 

1588register_function("extract", Extract) # type: ignore 

1589 

1590 

1591class next_value(GenericFunction[int]): 

1592 """Represent the 'next value', given a :class:`.Sequence` 

1593 as its single argument. 

1594 

1595 Compiles into the appropriate function on each backend, 

1596 or will raise NotImplementedError if used on a backend 

1597 that does not provide support for sequences. 

1598 

1599 """ 

1600 

1601 type = sqltypes.Integer() 

1602 name = "next_value" 

1603 

1604 _traverse_internals = [ 

1605 ("sequence", InternalTraversal.dp_named_ddl_element) 

1606 ] 

1607 

1608 def __init__(self, seq: schema.Sequence, **kw: Any) -> None: 

1609 assert isinstance( 

1610 seq, schema.Sequence 

1611 ), "next_value() accepts a Sequence object as input." 

1612 self.sequence = seq 

1613 self.type = sqltypes.to_instance( # type: ignore 

1614 seq.data_type or getattr(self, "type", None) 

1615 ) 

1616 

1617 def compare(self, other: Any, **kw: Any) -> bool: 

1618 return ( 

1619 isinstance(other, next_value) 

1620 and self.sequence.name == other.sequence.name 

1621 ) 

1622 

1623 @property 

1624 def _from_objects(self) -> Any: 

1625 return [] 

1626 

1627 

1628class AnsiFunction(GenericFunction[_T]): 

1629 """Define a function in "ansi" format, which doesn't render parenthesis.""" 

1630 

1631 inherit_cache = True 

1632 

1633 def __init__( 

1634 self, *args: _ColumnExpressionArgument[Any], **kwargs: Any 

1635 ) -> None: 

1636 GenericFunction.__init__(self, *args, **kwargs) 

1637 

1638 

1639class ReturnTypeFromArgs(GenericFunction[_T]): 

1640 """Define a function whose return type is bound to the type of its 

1641 arguments. 

1642 """ 

1643 

1644 inherit_cache = True 

1645 

1646 # set ColumnElement[_T] as a separate overload, to appease 

1647 # mypy which seems to not want to accept _T from 

1648 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1649 # _HasClauseElement as of mypy 1.15 

1650 

1651 @overload 

1652 def __init__( 

1653 self, 

1654 col: ColumnElement[_T], 

1655 *args: _ColumnExpressionOrLiteralArgument[Any], 

1656 **kwargs: Any, 

1657 ) -> None: ... 

1658 

1659 @overload 

1660 def __init__( 

1661 self, 

1662 col: _ColumnExpressionArgument[_T], 

1663 *args: _ColumnExpressionOrLiteralArgument[Any], 

1664 **kwargs: Any, 

1665 ) -> None: ... 

1666 

1667 @overload 

1668 def __init__( 

1669 self, 

1670 col: _T, 

1671 *args: _ColumnExpressionOrLiteralArgument[Any], 

1672 **kwargs: Any, 

1673 ) -> None: ... 

1674 

1675 def __init__( 

1676 self, *args: _ColumnExpressionOrLiteralArgument[_T], **kwargs: Any 

1677 ) -> None: 

1678 fn_args: Sequence[ColumnElement[Any]] = [ 

1679 coercions.expect( 

1680 roles.ExpressionElementRole, 

1681 c, 

1682 name=self.name, 

1683 apply_propagate_attrs=self, 

1684 ) 

1685 for c in args 

1686 ] 

1687 kwargs.setdefault("type_", _type_from_args(fn_args)) 

1688 kwargs["_parsed_args"] = fn_args 

1689 super().__init__(*fn_args, **kwargs) 

1690 

1691 

1692class coalesce(ReturnTypeFromArgs[_T]): 

1693 _has_args = True 

1694 inherit_cache = True 

1695 

1696 

1697class max(ReturnTypeFromArgs[_T]): # noqa: A001 

1698 """The SQL MAX() aggregate function.""" 

1699 

1700 inherit_cache = True 

1701 

1702 

1703class min(ReturnTypeFromArgs[_T]): # noqa: A001 

1704 """The SQL MIN() aggregate function.""" 

1705 

1706 inherit_cache = True 

1707 

1708 

1709class sum(ReturnTypeFromArgs[_T]): # noqa: A001 

1710 """The SQL SUM() aggregate function.""" 

1711 

1712 inherit_cache = True 

1713 

1714 

1715class now(GenericFunction[datetime.datetime]): 

1716 """The SQL now() datetime function. 

1717 

1718 SQLAlchemy dialects will usually render this particular function 

1719 in a backend-specific way, such as rendering it as ``CURRENT_TIMESTAMP``. 

1720 

1721 """ 

1722 

1723 type = sqltypes.DateTime() 

1724 inherit_cache = True 

1725 

1726 

1727class pow(ReturnTypeFromArgs[_T]): # noqa: A001 

1728 """The SQL POW() function which performs the power operator. 

1729 

1730 E.g.: 

1731 

1732 .. sourcecode:: pycon+sql 

1733 

1734 >>> print(select(func.pow(2, 8))) 

1735 {printsql}SELECT pow(:pow_2, :pow_3) AS pow_1 

1736 

1737 .. versionadded:: 2.1 

1738 

1739 """ 

1740 

1741 inherit_cache = True 

1742 

1743 

1744class concat(GenericFunction[str]): 

1745 """The SQL CONCAT() function, which concatenates strings. 

1746 

1747 E.g.: 

1748 

1749 .. sourcecode:: pycon+sql 

1750 

1751 >>> print(select(func.concat("a", "b"))) 

1752 {printsql}SELECT concat(:concat_2, :concat_3) AS concat_1 

1753 

1754 String concatenation in SQLAlchemy is more commonly available using the 

1755 Python ``+`` operator with string datatypes, which will render a 

1756 backend-specific concatenation operator, such as : 

1757 

1758 .. sourcecode:: pycon+sql 

1759 

1760 >>> print(select(literal("a") + "b")) 

1761 {printsql}SELECT :param_1 || :param_2 AS anon_1 

1762 

1763 

1764 """ 

1765 

1766 type = sqltypes.String() 

1767 inherit_cache = True 

1768 

1769 

1770class char_length(GenericFunction[int]): 

1771 """The CHAR_LENGTH() SQL function.""" 

1772 

1773 type = sqltypes.Integer() 

1774 inherit_cache = True 

1775 

1776 def __init__(self, arg: _ColumnExpressionArgument[str], **kw: Any) -> None: 

1777 # slight hack to limit to just one positional argument 

1778 # not sure why this one function has this special treatment 

1779 super().__init__(arg, **kw) 

1780 

1781 

1782class random(GenericFunction[float]): 

1783 """The RANDOM() SQL function.""" 

1784 

1785 _has_args = True 

1786 inherit_cache = True 

1787 

1788 

1789class count(GenericFunction[int]): 

1790 r"""The ANSI COUNT aggregate function. With no arguments, 

1791 emits COUNT \*. 

1792 

1793 E.g.:: 

1794 

1795 from sqlalchemy import func 

1796 from sqlalchemy import select 

1797 from sqlalchemy import table, column 

1798 

1799 my_table = table("some_table", column("id")) 

1800 

1801 stmt = select(func.count()).select_from(my_table) 

1802 

1803 Executing ``stmt`` would emit: 

1804 

1805 .. sourcecode:: sql 

1806 

1807 SELECT count(*) AS count_1 

1808 FROM some_table 

1809 

1810 

1811 """ 

1812 

1813 type = sqltypes.Integer() 

1814 inherit_cache = True 

1815 

1816 def __init__( 

1817 self, 

1818 expression: Union[ 

1819 _ColumnExpressionArgument[Any], _StarOrOne, None 

1820 ] = None, 

1821 **kwargs: Any, 

1822 ) -> None: 

1823 if expression is None: 

1824 expression = literal_column("*") 

1825 super().__init__(expression, **kwargs) 

1826 

1827 

1828class current_date(AnsiFunction[datetime.date]): 

1829 """The CURRENT_DATE() SQL function.""" 

1830 

1831 type = sqltypes.Date() 

1832 inherit_cache = True 

1833 

1834 

1835class current_time(AnsiFunction[datetime.time]): 

1836 """The CURRENT_TIME() SQL function.""" 

1837 

1838 type = sqltypes.Time() 

1839 inherit_cache = True 

1840 

1841 

1842class current_timestamp(AnsiFunction[datetime.datetime]): 

1843 """The CURRENT_TIMESTAMP() SQL function.""" 

1844 

1845 type = sqltypes.DateTime() 

1846 inherit_cache = True 

1847 

1848 

1849class current_user(AnsiFunction[str]): 

1850 """The CURRENT_USER() SQL function.""" 

1851 

1852 type = sqltypes.String() 

1853 inherit_cache = True 

1854 

1855 

1856class localtime(AnsiFunction[datetime.datetime]): 

1857 """The localtime() SQL function.""" 

1858 

1859 type = sqltypes.DateTime() 

1860 inherit_cache = True 

1861 

1862 

1863class localtimestamp(AnsiFunction[datetime.datetime]): 

1864 """The localtimestamp() SQL function.""" 

1865 

1866 type = sqltypes.DateTime() 

1867 inherit_cache = True 

1868 

1869 

1870class session_user(AnsiFunction[str]): 

1871 """The SESSION_USER() SQL function.""" 

1872 

1873 type = sqltypes.String() 

1874 inherit_cache = True 

1875 

1876 

1877class sysdate(AnsiFunction[datetime.datetime]): 

1878 """The SYSDATE() SQL function.""" 

1879 

1880 type = sqltypes.DateTime() 

1881 inherit_cache = True 

1882 

1883 

1884class user(AnsiFunction[str]): 

1885 """The USER() SQL function.""" 

1886 

1887 type = sqltypes.String() 

1888 inherit_cache = True 

1889 

1890 

1891class array_agg(ReturnTypeFromArgs[Sequence[_T]]): 

1892 """Support for the ARRAY_AGG function. 

1893 

1894 The ``func.array_agg(expr)`` construct returns an expression of 

1895 type :class:`_types.ARRAY`. 

1896 

1897 e.g.:: 

1898 

1899 stmt = select(func.array_agg(table.c.values)[2:5]) 

1900 

1901 .. seealso:: 

1902 

1903 :func:`_postgresql.array_agg` - PostgreSQL-specific version that 

1904 returns :class:`_postgresql.ARRAY`, which has PG-specific operators 

1905 added. 

1906 

1907 """ 

1908 

1909 inherit_cache = True 

1910 

1911 def __init__( 

1912 self, *args: _ColumnExpressionArgument[Any], **kwargs: Any 

1913 ) -> None: 

1914 fn_args: Sequence[ColumnElement[Any]] = [ 

1915 coercions.expect( 

1916 roles.ExpressionElementRole, c, apply_propagate_attrs=self 

1917 ) 

1918 for c in args 

1919 ] 

1920 

1921 default_array_type = kwargs.pop("_default_array_type", sqltypes.ARRAY) 

1922 if "type_" not in kwargs: 

1923 type_from_args = _type_from_args(fn_args) 

1924 if isinstance(type_from_args, sqltypes.ARRAY): 

1925 kwargs["type_"] = type_from_args 

1926 else: 

1927 kwargs["type_"] = default_array_type( 

1928 type_from_args, dimensions=1 

1929 ) 

1930 kwargs["_parsed_args"] = fn_args 

1931 super().__init__(*fn_args, **kwargs) 

1932 

1933 

1934class OrderedSetAgg(GenericFunction[_T]): 

1935 """Define a function where the return type is based on the sort 

1936 expression type as defined by the expression passed to the 

1937 :meth:`.FunctionElement.within_group` method.""" 

1938 

1939 array_for_multi_clause = False 

1940 inherit_cache = True 

1941 

1942 def within_group_type( 

1943 self, within_group: WithinGroup[Any] 

1944 ) -> TypeEngine[Any]: 

1945 func_clauses = cast(ClauseList, self.clause_expr.element) 

1946 order_by: Sequence[ColumnElement[Any]] = sqlutil.unwrap_order_by( 

1947 within_group.order_by 

1948 ) 

1949 if self.array_for_multi_clause and len(func_clauses.clauses) > 1: 

1950 return sqltypes.ARRAY(order_by[0].type) 

1951 else: 

1952 return order_by[0].type 

1953 

1954 

1955class mode(OrderedSetAgg[_T]): 

1956 """Implement the ``mode`` ordered-set aggregate function. 

1957 

1958 This function must be used with the :meth:`.FunctionElement.within_group` 

1959 modifier to supply a sort expression to operate upon. 

1960 

1961 The return type of this function is the same as the sort expression. 

1962 

1963 """ 

1964 

1965 inherit_cache = True 

1966 

1967 

1968class percentile_cont(OrderedSetAgg[_T]): 

1969 """Implement the ``percentile_cont`` ordered-set aggregate function. 

1970 

1971 This function must be used with the :meth:`.FunctionElement.within_group` 

1972 modifier to supply a sort expression to operate upon. 

1973 

1974 The return type of this function is the same as the sort expression, 

1975 or if the arguments are an array, an :class:`_types.ARRAY` of the sort 

1976 expression's type. 

1977 

1978 """ 

1979 

1980 array_for_multi_clause = True 

1981 inherit_cache = True 

1982 

1983 

1984class percentile_disc(OrderedSetAgg[_T]): 

1985 """Implement the ``percentile_disc`` ordered-set aggregate function. 

1986 

1987 This function must be used with the :meth:`.FunctionElement.within_group` 

1988 modifier to supply a sort expression to operate upon. 

1989 

1990 The return type of this function is the same as the sort expression, 

1991 or if the arguments are an array, an :class:`_types.ARRAY` of the sort 

1992 expression's type. 

1993 

1994 """ 

1995 

1996 array_for_multi_clause = True 

1997 inherit_cache = True 

1998 

1999 

2000class rank(GenericFunction[int]): 

2001 """Implement the ``rank`` hypothetical-set aggregate function. 

2002 

2003 This function must be used with the :meth:`.FunctionElement.within_group` 

2004 modifier to supply a sort expression to operate upon. 

2005 

2006 The return type of this function is :class:`.Integer`. 

2007 

2008 """ 

2009 

2010 type = sqltypes.Integer() 

2011 inherit_cache = True 

2012 

2013 

2014class dense_rank(GenericFunction[int]): 

2015 """Implement the ``dense_rank`` hypothetical-set aggregate function. 

2016 

2017 This function must be used with the :meth:`.FunctionElement.within_group` 

2018 modifier to supply a sort expression to operate upon. 

2019 

2020 The return type of this function is :class:`.Integer`. 

2021 

2022 """ 

2023 

2024 type = sqltypes.Integer() 

2025 inherit_cache = True 

2026 

2027 

2028class percent_rank(GenericFunction[decimal.Decimal]): 

2029 """Implement the ``percent_rank`` hypothetical-set aggregate function. 

2030 

2031 This function must be used with the :meth:`.FunctionElement.within_group` 

2032 modifier to supply a sort expression to operate upon. 

2033 

2034 The return type of this function is :class:`.Numeric`. 

2035 

2036 """ 

2037 

2038 type: sqltypes.Numeric[decimal.Decimal] = sqltypes.Numeric() 

2039 inherit_cache = True 

2040 

2041 

2042class cume_dist(GenericFunction[decimal.Decimal]): 

2043 """Implement the ``cume_dist`` hypothetical-set aggregate function. 

2044 

2045 This function must be used with the :meth:`.FunctionElement.within_group` 

2046 modifier to supply a sort expression to operate upon. 

2047 

2048 The return type of this function is :class:`.Numeric`. 

2049 

2050 """ 

2051 

2052 type: sqltypes.Numeric[decimal.Decimal] = sqltypes.Numeric() 

2053 inherit_cache = True 

2054 

2055 

2056class cube(GenericFunction[_T]): 

2057 r"""Implement the ``CUBE`` grouping operation. 

2058 

2059 This function is used as part of the GROUP BY of a statement, 

2060 e.g. :meth:`_expression.Select.group_by`:: 

2061 

2062 stmt = select( 

2063 func.sum(table.c.value), table.c.col_1, table.c.col_2 

2064 ).group_by(func.cube(table.c.col_1, table.c.col_2)) 

2065 

2066 """ 

2067 

2068 _has_args = True 

2069 inherit_cache = True 

2070 

2071 

2072class rollup(GenericFunction[_T]): 

2073 r"""Implement the ``ROLLUP`` grouping operation. 

2074 

2075 This function is used as part of the GROUP BY of a statement, 

2076 e.g. :meth:`_expression.Select.group_by`:: 

2077 

2078 stmt = select( 

2079 func.sum(table.c.value), table.c.col_1, table.c.col_2 

2080 ).group_by(func.rollup(table.c.col_1, table.c.col_2)) 

2081 

2082 """ 

2083 

2084 _has_args = True 

2085 inherit_cache = True 

2086 

2087 

2088class grouping_sets(GenericFunction[_T]): 

2089 r"""Implement the ``GROUPING SETS`` grouping operation. 

2090 

2091 This function is used as part of the GROUP BY of a statement, 

2092 e.g. :meth:`_expression.Select.group_by`:: 

2093 

2094 stmt = select( 

2095 func.sum(table.c.value), table.c.col_1, table.c.col_2 

2096 ).group_by(func.grouping_sets(table.c.col_1, table.c.col_2)) 

2097 

2098 In order to group by multiple sets, use the :func:`.tuple_` construct:: 

2099 

2100 from sqlalchemy import tuple_ 

2101 

2102 stmt = select( 

2103 func.sum(table.c.value), table.c.col_1, table.c.col_2, table.c.col_3 

2104 ).group_by( 

2105 func.grouping_sets( 

2106 tuple_(table.c.col_1, table.c.col_2), 

2107 tuple_(table.c.value, table.c.col_3), 

2108 ) 

2109 ) 

2110 

2111 """ # noqa: E501 

2112 

2113 _has_args = True 

2114 inherit_cache = True 

2115 

2116 

2117class aggregate_strings(GenericFunction[str]): 

2118 """Implement a generic string aggregation function. 

2119 

2120 This function will concatenate non-null values into a string and 

2121 separate the values by a delimiter. 

2122 

2123 This function is compiled on a per-backend basis, into functions 

2124 such as ``group_concat()``, ``string_agg()``, or ``LISTAGG()``. 

2125 

2126 e.g. Example usage with delimiter '.':: 

2127 

2128 stmt = select(func.aggregate_strings(table.c.str_col, ".")) 

2129 

2130 The return type of this function is :class:`.String`. 

2131 

2132 .. versionadded:: 2.0.21 

2133 

2134 """ 

2135 

2136 type = sqltypes.String() 

2137 _has_args = True 

2138 inherit_cache = True 

2139 

2140 def __init__( 

2141 self, clause: _ColumnExpressionArgument[Any], separator: str 

2142 ) -> None: 

2143 super().__init__(clause, separator)