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 is operators.getitem and isinstance( 

747 self.type, sqltypes.ARRAY 

748 ): 

749 return Grouping(self) 

750 else: 

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

752 

753 @property 

754 def entity_namespace(self) -> _EntityNamespace: 

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

756 column expressions and not FromClauses. 

757 

758 """ 

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

760 # this adjustment in 1.4 

761 return _entity_namespace(self.clause_expr) 

762 

763 

764class FunctionAsBinary(BinaryExpression[Any]): 

765 _traverse_internals = [ 

766 ("sql_function", InternalTraversal.dp_clauseelement), 

767 ("left_index", InternalTraversal.dp_plain_obj), 

768 ("right_index", InternalTraversal.dp_plain_obj), 

769 ("modifiers", InternalTraversal.dp_plain_dict), 

770 ] 

771 

772 sql_function: FunctionElement[Any] 

773 left_index: int 

774 right_index: int 

775 

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

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

778 

779 def __init__( 

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

781 ) -> None: 

782 self.sql_function = fn 

783 self.left_index = left_index 

784 self.right_index = right_index 

785 

786 self.operator = operators.function_as_comparison_op 

787 self.type = sqltypes.BOOLEANTYPE 

788 self.negate = None 

789 self._is_implicitly_boolean = True 

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

791 

792 @property 

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

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

795 

796 @left_expr.setter 

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

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

799 

800 @property 

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

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

803 

804 @right_expr.setter 

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

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

807 

808 if not TYPE_CHECKING: 

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

810 # variable 

811 

812 left = left_expr 

813 right = right_expr 

814 

815 

816class ScalarFunctionColumn(NamedColumn[_T]): 

817 __visit_name__ = "scalar_function_column" 

818 

819 _traverse_internals = [ 

820 ("name", InternalTraversal.dp_anon_name), 

821 ("type", InternalTraversal.dp_type), 

822 ("fn", InternalTraversal.dp_clauseelement), 

823 ] 

824 

825 is_literal = False 

826 table = None 

827 

828 def __init__( 

829 self, 

830 fn: FunctionElement[_T], 

831 name: str, 

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

833 ) -> None: 

834 self.fn = fn 

835 self.name = name 

836 

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

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

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

840 

841 

842class _FunctionGenerator: 

843 """Generate SQL function expressions. 

844 

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

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

847 

848 .. sourcecode:: pycon+sql 

849 

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

851 {printsql}count(:param_1) 

852 

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

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

855 

856 .. sourcecode:: pycon+sql 

857 

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

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

860 

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

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

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

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

865 

866 .. sourcecode:: pycon+sql 

867 

868 >>> print(func.current_timestamp()) 

869 {printsql}CURRENT_TIMESTAMP 

870 

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

872 specify them in the same manner: 

873 

874 .. sourcecode:: pycon+sql 

875 

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

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

878 

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

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

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

882 treated as a string in expressions, specify 

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

884 

885 .. sourcecode:: pycon+sql 

886 

887 >>> print( 

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

889 ... + " " 

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

891 ... ) 

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

893 

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

895 :class:`.Function`. 

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

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

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

899 where it will be 

900 wrapped inside of a SELECT statement first:: 

901 

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

903 

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

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

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

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

908 perspective. 

909 

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

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

912 functions, see :ref:`generic_functions`. 

913 

914 .. note:: 

915 

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

917 standalone "stored procedures", especially those with special 

918 parameterization concerns. 

919 

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

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

922 procedures. 

923 

924 .. seealso:: 

925 

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

927 

928 :class:`.Function` 

929 

930 """ # noqa 

931 

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

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

934 self.opts = opts 

935 

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

937 # passthru __ attributes; fixes pydoc 

938 if name.startswith("__"): 

939 try: 

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

941 except KeyError: 

942 raise AttributeError(name) 

943 

944 elif name.endswith("_"): 

945 name = name[0:-1] 

946 f = _FunctionGenerator(**self.opts) 

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

948 return f 

949 

950 @overload 

951 def __call__( 

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

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

954 

955 @overload 

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

957 

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

959 o = self.opts.copy() 

960 o.update(kwargs) 

961 

962 tokens = len(self.__names) 

963 

964 if tokens == 2: 

965 package, fname = self.__names 

966 elif tokens == 1: 

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

968 else: 

969 package = None 

970 

971 if package is not None: 

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

973 if func is not None: 

974 return func(*c, **o) 

975 

976 return Function( 

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

978 ) 

979 

980 if TYPE_CHECKING: 

981 # START GENERATED FUNCTION ACCESSORS 

982 

983 # code within this block is **programmatically, 

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

985 

986 @property 

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

988 

989 @property 

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

991 

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

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

994 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

995 # _HasClauseElement as of mypy 1.15 

996 

997 @overload 

998 def array_agg( 

999 self, 

1000 col: ColumnElement[_T], 

1001 *args: _ColumnExpressionOrLiteralArgument[Any], 

1002 **kwargs: Any, 

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

1004 

1005 @overload 

1006 def array_agg( 

1007 self, 

1008 col: _ColumnExpressionArgument[_T], 

1009 *args: _ColumnExpressionOrLiteralArgument[Any], 

1010 **kwargs: Any, 

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

1012 

1013 @overload 

1014 def array_agg( 

1015 self, 

1016 col: _T, 

1017 *args: _ColumnExpressionOrLiteralArgument[Any], 

1018 **kwargs: Any, 

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

1020 

1021 def array_agg( 

1022 self, 

1023 col: _ColumnExpressionOrLiteralArgument[_T], 

1024 *args: _ColumnExpressionOrLiteralArgument[Any], 

1025 **kwargs: Any, 

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

1027 

1028 @property 

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

1030 

1031 @property 

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

1033 

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

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

1036 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1037 # _HasClauseElement as of mypy 1.15 

1038 

1039 @overload 

1040 def coalesce( 

1041 self, 

1042 col: ColumnElement[_T], 

1043 *args: _ColumnExpressionOrLiteralArgument[Any], 

1044 **kwargs: Any, 

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

1046 

1047 @overload 

1048 def coalesce( 

1049 self, 

1050 col: _ColumnExpressionArgument[_T], 

1051 *args: _ColumnExpressionOrLiteralArgument[Any], 

1052 **kwargs: Any, 

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

1054 

1055 @overload 

1056 def coalesce( 

1057 self, 

1058 col: _T, 

1059 *args: _ColumnExpressionOrLiteralArgument[Any], 

1060 **kwargs: Any, 

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

1062 

1063 def coalesce( 

1064 self, 

1065 col: _ColumnExpressionOrLiteralArgument[_T], 

1066 *args: _ColumnExpressionOrLiteralArgument[Any], 

1067 **kwargs: Any, 

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

1069 

1070 @property 

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

1072 

1073 @property 

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

1075 

1076 @property 

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

1078 

1079 @property 

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

1081 

1082 @property 

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

1084 

1085 @property 

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

1087 

1088 @property 

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

1090 

1091 @property 

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

1093 

1094 @property 

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

1096 

1097 @property 

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

1099 

1100 @property 

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

1102 

1103 @property 

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

1105 

1106 @property 

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

1108 

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

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

1111 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1112 # _HasClauseElement as of mypy 1.15 

1113 

1114 @overload 

1115 def max( # noqa: A001 

1116 self, 

1117 col: ColumnElement[_T], 

1118 *args: _ColumnExpressionOrLiteralArgument[Any], 

1119 **kwargs: Any, 

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

1121 

1122 @overload 

1123 def max( # noqa: A001 

1124 self, 

1125 col: _ColumnExpressionArgument[_T], 

1126 *args: _ColumnExpressionOrLiteralArgument[Any], 

1127 **kwargs: Any, 

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

1129 

1130 @overload 

1131 def max( # noqa: A001 

1132 self, 

1133 col: _T, 

1134 *args: _ColumnExpressionOrLiteralArgument[Any], 

1135 **kwargs: Any, 

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

1137 

1138 def max( # noqa: A001 

1139 self, 

1140 col: _ColumnExpressionOrLiteralArgument[_T], 

1141 *args: _ColumnExpressionOrLiteralArgument[Any], 

1142 **kwargs: Any, 

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

1144 

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

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

1147 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1148 # _HasClauseElement as of mypy 1.15 

1149 

1150 @overload 

1151 def min( # noqa: A001 

1152 self, 

1153 col: ColumnElement[_T], 

1154 *args: _ColumnExpressionOrLiteralArgument[Any], 

1155 **kwargs: Any, 

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

1157 

1158 @overload 

1159 def min( # noqa: A001 

1160 self, 

1161 col: _ColumnExpressionArgument[_T], 

1162 *args: _ColumnExpressionOrLiteralArgument[Any], 

1163 **kwargs: Any, 

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

1165 

1166 @overload 

1167 def min( # noqa: A001 

1168 self, 

1169 col: _T, 

1170 *args: _ColumnExpressionOrLiteralArgument[Any], 

1171 **kwargs: Any, 

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

1173 

1174 def min( # noqa: A001 

1175 self, 

1176 col: _ColumnExpressionOrLiteralArgument[_T], 

1177 *args: _ColumnExpressionOrLiteralArgument[Any], 

1178 **kwargs: Any, 

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

1180 

1181 @property 

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

1183 

1184 @property 

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

1186 

1187 @property 

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

1189 

1190 @property 

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

1192 

1193 @property 

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

1195 

1196 @property 

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

1198 

1199 @property 

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

1201 

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

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

1204 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1205 # _HasClauseElement as of mypy 1.15 

1206 

1207 @overload 

1208 def pow( # noqa: A001 

1209 self, 

1210 col: ColumnElement[_T], 

1211 *args: _ColumnExpressionOrLiteralArgument[Any], 

1212 **kwargs: Any, 

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

1214 

1215 @overload 

1216 def pow( # noqa: A001 

1217 self, 

1218 col: _ColumnExpressionArgument[_T], 

1219 *args: _ColumnExpressionOrLiteralArgument[Any], 

1220 **kwargs: Any, 

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

1222 

1223 @overload 

1224 def pow( # noqa: A001 

1225 self, 

1226 col: _T, 

1227 *args: _ColumnExpressionOrLiteralArgument[Any], 

1228 **kwargs: Any, 

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

1230 

1231 def pow( # noqa: A001 

1232 self, 

1233 col: _ColumnExpressionOrLiteralArgument[_T], 

1234 *args: _ColumnExpressionOrLiteralArgument[Any], 

1235 **kwargs: Any, 

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

1237 

1238 @property 

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

1240 

1241 @property 

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

1243 

1244 @property 

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

1246 

1247 @property 

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

1249 

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

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

1252 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1253 # _HasClauseElement as of mypy 1.15 

1254 

1255 @overload 

1256 def sum( # noqa: A001 

1257 self, 

1258 col: ColumnElement[_T], 

1259 *args: _ColumnExpressionOrLiteralArgument[Any], 

1260 **kwargs: Any, 

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

1262 

1263 @overload 

1264 def sum( # noqa: A001 

1265 self, 

1266 col: _ColumnExpressionArgument[_T], 

1267 *args: _ColumnExpressionOrLiteralArgument[Any], 

1268 **kwargs: Any, 

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

1270 

1271 @overload 

1272 def sum( # noqa: A001 

1273 self, 

1274 col: _T, 

1275 *args: _ColumnExpressionOrLiteralArgument[Any], 

1276 **kwargs: Any, 

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

1278 

1279 def sum( # noqa: A001 

1280 self, 

1281 col: _ColumnExpressionOrLiteralArgument[_T], 

1282 *args: _ColumnExpressionOrLiteralArgument[Any], 

1283 **kwargs: Any, 

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

1285 

1286 @property 

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

1288 

1289 @property 

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

1291 

1292 # END GENERATED FUNCTION ACCESSORS 

1293 

1294 

1295func = _FunctionGenerator() 

1296func.__doc__ = _FunctionGenerator.__doc__ 

1297 

1298modifier = _FunctionGenerator(group=False) 

1299 

1300 

1301class Function(FunctionElement[_T]): 

1302 r"""Describe a named SQL function. 

1303 

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

1305 :data:`.func` generation object. 

1306 

1307 

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

1309 of the SQL function call. 

1310 

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

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

1313 function call. 

1314 

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

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

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

1318 dotted format, e.g.:: 

1319 

1320 func.mypackage.some_function(col1, col2) 

1321 

1322 .. seealso:: 

1323 

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

1325 

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

1327 :class:`.Function` instances. 

1328 

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

1330 types. 

1331 

1332 """ 

1333 

1334 __visit_name__ = "function" 

1335 

1336 _traverse_internals = FunctionElement._traverse_internals + [ 

1337 ("packagenames", InternalTraversal.dp_plain_obj), 

1338 ("name", InternalTraversal.dp_string), 

1339 ("type", InternalTraversal.dp_type), 

1340 ] 

1341 

1342 name: str 

1343 

1344 identifier: str 

1345 

1346 type: TypeEngine[_T] 

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

1348 type represented by this SQL function. 

1349 

1350 This datatype may be configured when generating a 

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

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

1353 

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

1355 

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

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

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

1359 "null type". 

1360 

1361 """ 

1362 

1363 @overload 

1364 def __init__( 

1365 self, 

1366 name: str, 

1367 *clauses: _ColumnExpressionOrLiteralArgument[_T], 

1368 type_: None = ..., 

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

1370 ) -> None: ... 

1371 

1372 @overload 

1373 def __init__( 

1374 self, 

1375 name: str, 

1376 *clauses: _ColumnExpressionOrLiteralArgument[Any], 

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

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

1379 ) -> None: ... 

1380 

1381 def __init__( 

1382 self, 

1383 name: str, 

1384 *clauses: _ColumnExpressionOrLiteralArgument[Any], 

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

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

1387 ) -> None: 

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

1389 

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

1391 new :class:`.Function` instances. 

1392 

1393 """ 

1394 self.packagenames = packagenames or () 

1395 self.name = name 

1396 

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

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

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

1400 

1401 FunctionElement.__init__(self, *clauses) 

1402 

1403 def _bind_param( 

1404 self, 

1405 operator: OperatorType, 

1406 obj: Any, 

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

1408 expanding: bool = False, 

1409 **kw: Any, 

1410 ) -> BindParameter[_T]: 

1411 return BindParameter( 

1412 self.name, 

1413 obj, 

1414 _compared_to_operator=operator, 

1415 _compared_to_type=self.type, 

1416 type_=type_, 

1417 unique=True, 

1418 expanding=expanding, 

1419 **kw, 

1420 ) 

1421 

1422 

1423class GenericFunction(Function[_T]): 

1424 """Define a 'generic' function. 

1425 

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

1427 class that is instantiated automatically when called 

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

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

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

1431 given that name. The primary use case for defining 

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

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

1434 It can also include custom argument parsing schemes as well 

1435 as additional methods. 

1436 

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

1438 registered under the name of the class. For 

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

1440 be available immediately:: 

1441 

1442 from sqlalchemy.sql.functions import GenericFunction 

1443 from sqlalchemy.types import DateTime 

1444 

1445 

1446 class as_utc(GenericFunction): 

1447 type = DateTime() 

1448 inherit_cache = True 

1449 

1450 

1451 print(select(func.as_utc())) 

1452 

1453 User-defined generic functions can be organized into 

1454 packages by specifying the "package" attribute when defining 

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

1456 containing many functions may want to use this in order 

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

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

1459 "time":: 

1460 

1461 class as_utc(GenericFunction): 

1462 type = DateTime() 

1463 package = "time" 

1464 inherit_cache = True 

1465 

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

1467 using the package name ``time``:: 

1468 

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

1470 

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

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

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

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

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

1476 

1477 class GeoBuffer(GenericFunction): 

1478 type = Geometry() 

1479 package = "geo" 

1480 name = "ST_Buffer" 

1481 identifier = "buffer" 

1482 inherit_cache = True 

1483 

1484 The above function will render as follows: 

1485 

1486 .. sourcecode:: pycon+sql 

1487 

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

1489 {printsql}ST_Buffer() 

1490 

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

1492 contains special characters that require quoting. To force quoting 

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

1494 construct:: 

1495 

1496 from sqlalchemy.sql import quoted_name 

1497 

1498 

1499 class GeoBuffer(GenericFunction): 

1500 type = Geometry() 

1501 package = "geo" 

1502 name = quoted_name("ST_Buffer", True) 

1503 identifier = "buffer" 

1504 inherit_cache = True 

1505 

1506 The above function will render as: 

1507 

1508 .. sourcecode:: pycon+sql 

1509 

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

1511 {printsql}"ST_Buffer"() 

1512 

1513 Type parameters for this class as a 

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

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

1516 

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

1518 type = DateTime() 

1519 inherit_cache = True 

1520 

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

1522 object:: 

1523 

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

1525 

1526 """ 

1527 

1528 coerce_arguments = True 

1529 inherit_cache = True 

1530 

1531 _register: bool 

1532 

1533 name = "GenericFunction" 

1534 

1535 def __init_subclass__(cls) -> None: 

1536 if annotation.Annotated not in cls.__mro__: 

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

1538 super().__init_subclass__() 

1539 

1540 @classmethod 

1541 def _register_generic_function( 

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

1543 ) -> None: 

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

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

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

1547 # legacy 

1548 if "__return_type__" in clsdict: 

1549 cls.type = clsdict["__return_type__"] 

1550 

1551 # Check _register attribute status 

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

1553 

1554 # Register the function if required 

1555 if cls._register: 

1556 register_function(identifier, cls, package) 

1557 else: 

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

1559 cls._register = True 

1560 

1561 def __init__( 

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

1563 ) -> None: 

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

1565 if parsed_args is None: 

1566 parsed_args = [ 

1567 coercions.expect( 

1568 roles.ExpressionElementRole, 

1569 c, 

1570 name=self.name, 

1571 apply_propagate_attrs=self, 

1572 ) 

1573 for c in args 

1574 ] 

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

1576 self.packagenames = () 

1577 

1578 self.clause_expr = Grouping( 

1579 ClauseList( 

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

1581 ) 

1582 ) 

1583 

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

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

1586 ) 

1587 

1588 

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

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

1591 

1592 

1593class next_value(GenericFunction[int]): 

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

1595 as its single argument. 

1596 

1597 Compiles into the appropriate function on each backend, 

1598 or will raise NotImplementedError if used on a backend 

1599 that does not provide support for sequences. 

1600 

1601 """ 

1602 

1603 type = sqltypes.Integer() 

1604 name = "next_value" 

1605 

1606 _traverse_internals = [ 

1607 ("sequence", InternalTraversal.dp_named_ddl_element) 

1608 ] 

1609 

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

1611 assert isinstance( 

1612 seq, schema.Sequence 

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

1614 self.sequence = seq 

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

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

1617 ) 

1618 

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

1620 return ( 

1621 isinstance(other, next_value) 

1622 and self.sequence.name == other.sequence.name 

1623 ) 

1624 

1625 @property 

1626 def _from_objects(self) -> Any: 

1627 return [] 

1628 

1629 

1630class AnsiFunction(GenericFunction[_T]): 

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

1632 

1633 inherit_cache = True 

1634 

1635 def __init__( 

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

1637 ) -> None: 

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

1639 

1640 

1641class ReturnTypeFromArgs(GenericFunction[_T]): 

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

1643 arguments. 

1644 """ 

1645 

1646 inherit_cache = True 

1647 

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

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

1650 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1651 # _HasClauseElement as of mypy 1.15 

1652 

1653 @overload 

1654 def __init__( 

1655 self, 

1656 col: ColumnElement[_T], 

1657 *args: _ColumnExpressionOrLiteralArgument[Any], 

1658 **kwargs: Any, 

1659 ) -> None: ... 

1660 

1661 @overload 

1662 def __init__( 

1663 self, 

1664 col: _ColumnExpressionArgument[_T], 

1665 *args: _ColumnExpressionOrLiteralArgument[Any], 

1666 **kwargs: Any, 

1667 ) -> None: ... 

1668 

1669 @overload 

1670 def __init__( 

1671 self, 

1672 col: _T, 

1673 *args: _ColumnExpressionOrLiteralArgument[Any], 

1674 **kwargs: Any, 

1675 ) -> None: ... 

1676 

1677 def __init__( 

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

1679 ) -> None: 

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

1681 coercions.expect( 

1682 roles.ExpressionElementRole, 

1683 c, 

1684 name=self.name, 

1685 apply_propagate_attrs=self, 

1686 ) 

1687 for c in args 

1688 ] 

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

1690 kwargs["_parsed_args"] = fn_args 

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

1692 

1693 

1694class coalesce(ReturnTypeFromArgs[_T]): 

1695 _has_args = True 

1696 inherit_cache = True 

1697 

1698 

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

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

1701 

1702 inherit_cache = True 

1703 

1704 

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

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

1707 

1708 inherit_cache = True 

1709 

1710 

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

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

1713 

1714 inherit_cache = True 

1715 

1716 

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

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

1719 

1720 SQLAlchemy dialects will usually render this particular function 

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

1722 

1723 """ 

1724 

1725 type = sqltypes.DateTime() 

1726 inherit_cache = True 

1727 

1728 

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

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

1731 

1732 E.g.: 

1733 

1734 .. sourcecode:: pycon+sql 

1735 

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

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

1738 

1739 .. versionadded:: 2.1 

1740 

1741 """ 

1742 

1743 inherit_cache = True 

1744 

1745 

1746class concat(GenericFunction[str]): 

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

1748 

1749 E.g.: 

1750 

1751 .. sourcecode:: pycon+sql 

1752 

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

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

1755 

1756 String concatenation in SQLAlchemy is more commonly available using the 

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

1758 backend-specific concatenation operator, such as : 

1759 

1760 .. sourcecode:: pycon+sql 

1761 

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

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

1764 

1765 

1766 """ 

1767 

1768 type = sqltypes.String() 

1769 inherit_cache = True 

1770 

1771 

1772class char_length(GenericFunction[int]): 

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

1774 

1775 type = sqltypes.Integer() 

1776 inherit_cache = True 

1777 

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

1779 # slight hack to limit to just one positional argument 

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

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

1782 

1783 

1784class random(GenericFunction[float]): 

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

1786 

1787 _has_args = True 

1788 inherit_cache = True 

1789 

1790 

1791class count(GenericFunction[int]): 

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

1793 emits COUNT \*. 

1794 

1795 E.g.:: 

1796 

1797 from sqlalchemy import func 

1798 from sqlalchemy import select 

1799 from sqlalchemy import table, column 

1800 

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

1802 

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

1804 

1805 Executing ``stmt`` would emit: 

1806 

1807 .. sourcecode:: sql 

1808 

1809 SELECT count(*) AS count_1 

1810 FROM some_table 

1811 

1812 

1813 """ 

1814 

1815 type = sqltypes.Integer() 

1816 inherit_cache = True 

1817 

1818 def __init__( 

1819 self, 

1820 expression: Union[ 

1821 _ColumnExpressionArgument[Any], _StarOrOne, None 

1822 ] = None, 

1823 **kwargs: Any, 

1824 ) -> None: 

1825 if expression is None: 

1826 expression = literal_column("*") 

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

1828 

1829 

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

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

1832 

1833 type = sqltypes.Date() 

1834 inherit_cache = True 

1835 

1836 

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

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

1839 

1840 type = sqltypes.Time() 

1841 inherit_cache = True 

1842 

1843 

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

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

1846 

1847 type = sqltypes.DateTime() 

1848 inherit_cache = True 

1849 

1850 

1851class current_user(AnsiFunction[str]): 

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

1853 

1854 type = sqltypes.String() 

1855 inherit_cache = True 

1856 

1857 

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

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

1860 

1861 type = sqltypes.DateTime() 

1862 inherit_cache = True 

1863 

1864 

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

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

1867 

1868 type = sqltypes.DateTime() 

1869 inherit_cache = True 

1870 

1871 

1872class session_user(AnsiFunction[str]): 

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

1874 

1875 type = sqltypes.String() 

1876 inherit_cache = True 

1877 

1878 

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

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

1881 

1882 type = sqltypes.DateTime() 

1883 inherit_cache = True 

1884 

1885 

1886class user(AnsiFunction[str]): 

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

1888 

1889 type = sqltypes.String() 

1890 inherit_cache = True 

1891 

1892 

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

1894 """Support for the ARRAY_AGG function. 

1895 

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

1897 type :class:`_types.ARRAY`. 

1898 

1899 e.g.:: 

1900 

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

1902 

1903 .. seealso:: 

1904 

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

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

1907 added. 

1908 

1909 """ 

1910 

1911 inherit_cache = True 

1912 

1913 def __init__( 

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

1915 ) -> None: 

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

1917 coercions.expect( 

1918 roles.ExpressionElementRole, c, apply_propagate_attrs=self 

1919 ) 

1920 for c in args 

1921 ] 

1922 

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

1924 if "type_" not in kwargs: 

1925 type_from_args = _type_from_args(fn_args) 

1926 if isinstance(type_from_args, sqltypes.ARRAY): 

1927 kwargs["type_"] = type_from_args 

1928 else: 

1929 kwargs["type_"] = default_array_type( 

1930 type_from_args, dimensions=1 

1931 ) 

1932 kwargs["_parsed_args"] = fn_args 

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

1934 

1935 

1936class OrderedSetAgg(GenericFunction[_T]): 

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

1938 expression type as defined by the expression passed to the 

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

1940 

1941 array_for_multi_clause = False 

1942 inherit_cache = True 

1943 

1944 def within_group_type( 

1945 self, within_group: WithinGroup[Any] 

1946 ) -> TypeEngine[Any]: 

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

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

1949 within_group.order_by 

1950 ) 

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

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

1953 else: 

1954 return order_by[0].type 

1955 

1956 

1957class mode(OrderedSetAgg[_T]): 

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

1959 

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

1961 modifier to supply a sort expression to operate upon. 

1962 

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

1964 

1965 """ 

1966 

1967 inherit_cache = True 

1968 

1969 

1970class percentile_cont(OrderedSetAgg[_T]): 

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

1972 

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

1974 modifier to supply a sort expression to operate upon. 

1975 

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

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

1978 expression's type. 

1979 

1980 """ 

1981 

1982 array_for_multi_clause = True 

1983 inherit_cache = True 

1984 

1985 

1986class percentile_disc(OrderedSetAgg[_T]): 

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

1988 

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

1990 modifier to supply a sort expression to operate upon. 

1991 

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

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

1994 expression's type. 

1995 

1996 """ 

1997 

1998 array_for_multi_clause = True 

1999 inherit_cache = True 

2000 

2001 

2002class rank(GenericFunction[int]): 

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

2004 

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

2006 modifier to supply a sort expression to operate upon. 

2007 

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

2009 

2010 """ 

2011 

2012 type = sqltypes.Integer() 

2013 inherit_cache = True 

2014 

2015 

2016class dense_rank(GenericFunction[int]): 

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

2018 

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

2020 modifier to supply a sort expression to operate upon. 

2021 

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

2023 

2024 """ 

2025 

2026 type = sqltypes.Integer() 

2027 inherit_cache = True 

2028 

2029 

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

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

2032 

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

2034 modifier to supply a sort expression to operate upon. 

2035 

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

2037 

2038 """ 

2039 

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

2041 inherit_cache = True 

2042 

2043 

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

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

2046 

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

2048 modifier to supply a sort expression to operate upon. 

2049 

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

2051 

2052 """ 

2053 

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

2055 inherit_cache = True 

2056 

2057 

2058class cube(GenericFunction[_T]): 

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

2060 

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

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

2063 

2064 stmt = select( 

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

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

2067 

2068 """ 

2069 

2070 _has_args = True 

2071 inherit_cache = True 

2072 

2073 

2074class rollup(GenericFunction[_T]): 

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

2076 

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

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

2079 

2080 stmt = select( 

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

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

2083 

2084 """ 

2085 

2086 _has_args = True 

2087 inherit_cache = True 

2088 

2089 

2090class grouping_sets(GenericFunction[_T]): 

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

2092 

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

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

2095 

2096 stmt = select( 

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

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

2099 

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

2101 

2102 from sqlalchemy import tuple_ 

2103 

2104 stmt = select( 

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

2106 ).group_by( 

2107 func.grouping_sets( 

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

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

2110 ) 

2111 ) 

2112 

2113 """ # noqa: E501 

2114 

2115 _has_args = True 

2116 inherit_cache = True 

2117 

2118 

2119class aggregate_strings(GenericFunction[str]): 

2120 """Implement a generic string aggregation function. 

2121 

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

2123 separate the values by a delimiter. 

2124 

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

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

2127 

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

2129 

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

2131 

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

2133 

2134 .. versionadded:: 2.0.21 

2135 

2136 """ 

2137 

2138 type = sqltypes.String() 

2139 _has_args = True 

2140 inherit_cache = True 

2141 

2142 def __init__( 

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

2144 ) -> None: 

2145 super().__init__(clause, separator)