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

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

539 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 AggregateOrderBy 

44from .elements import BinaryExpression 

45from .elements import BindParameter 

46from .elements import Cast 

47from .elements import ClauseList 

48from .elements import ColumnElement 

49from .elements import Extract 

50from .elements import FunctionFilter 

51from .elements import Grouping 

52from .elements import literal_column 

53from .elements import NamedColumn 

54from .elements import Over 

55from .elements import WithinGroup 

56from .selectable import FromClause 

57from .selectable import Select 

58from .selectable import TableValuedAlias 

59from .sqltypes import TableValueType 

60from .type_api import TypeEngine 

61from .visitors import InternalTraversal 

62from .. import util 

63 

64 

65if TYPE_CHECKING: 

66 from ._typing import _ByArgument 

67 from ._typing import _ColumnExpressionArgument 

68 from ._typing import _ColumnExpressionOrLiteralArgument 

69 from ._typing import _ColumnExpressionOrStrLabelArgument 

70 from ._typing import _StarOrOne 

71 from ._typing import _TypeEngineArgument 

72 from .base import _EntityNamespace 

73 from .elements import ClauseElement 

74 from .elements import KeyedColumnElement 

75 from .elements import TableValuedColumn 

76 from .operators import OperatorType 

77 from ..engine.base import Connection 

78 from ..engine.cursor import CursorResult 

79 from ..engine.interfaces import _CoreMultiExecuteParams 

80 from ..engine.interfaces import CoreExecuteOptionsParameter 

81 from ..util.typing import Self 

82 

83_T = TypeVar("_T", bound=Any) 

84_S = TypeVar("_S", bound=Any) 

85 

86_registry: util.defaultdict[str, Dict[str, Type[Function[Any]]]] = ( 

87 util.defaultdict(dict) 

88) 

89 

90 

91def register_function( 

92 identifier: str, fn: Type[Function[Any]], package: str = "_default" 

93) -> None: 

94 """Associate a callable with a particular func. name. 

95 

96 This is normally called by GenericFunction, but is also 

97 available by itself so that a non-Function construct 

98 can be associated with the :data:`.func` accessor (i.e. 

99 CAST, EXTRACT). 

100 

101 """ 

102 reg = _registry[package] 

103 

104 identifier = str(identifier).lower() 

105 

106 # Check if a function with the same identifier is registered. 

107 if identifier in reg: 

108 util.warn( 

109 "The GenericFunction '{}' is already registered and " 

110 "is going to be overridden.".format(identifier) 

111 ) 

112 reg[identifier] = fn 

113 

114 

115class FunctionElement(Executable, ColumnElement[_T], FromClause, Generative): 

116 """Base for SQL function-oriented constructs. 

117 

118 This is a `generic type <https://peps.python.org/pep-0484/#generics>`_, 

119 meaning that type checkers and IDEs can be instructed on the types to 

120 expect in a :class:`_engine.Result` for this function. See 

121 :class:`.GenericFunction` for an example of how this is done. 

122 

123 .. seealso:: 

124 

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

126 

127 :class:`.Function` - named SQL function. 

128 

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

130 :class:`.Function` instances. 

131 

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

133 types. 

134 

135 """ 

136 

137 _traverse_internals = [ 

138 ("clause_expr", InternalTraversal.dp_clauseelement), 

139 ("_with_ordinality", InternalTraversal.dp_boolean), 

140 ("_table_value_type", InternalTraversal.dp_has_cache_key), 

141 ] + Executable._executable_traverse_internals 

142 

143 packagenames: Tuple[str, ...] = () 

144 

145 _has_args = False 

146 _with_ordinality = False 

147 _table_value_type: Optional[TableValueType] = None 

148 

149 # some attributes that are defined between both ColumnElement and 

150 # FromClause are set to Any here to avoid typing errors 

151 primary_key: Any 

152 _is_clone_of: Any 

153 

154 clause_expr: Grouping[Any] 

155 

156 def __init__( 

157 self, *clauses: _ColumnExpressionOrLiteralArgument[Any] 

158 ) -> None: 

159 r"""Construct a :class:`.FunctionElement`. 

160 

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

162 of the SQL function call. 

163 

164 :param \**kwargs: additional kwargs are typically consumed by 

165 subclasses. 

166 

167 .. seealso:: 

168 

169 :data:`.func` 

170 

171 :class:`.Function` 

172 

173 """ 

174 args: Sequence[_ColumnExpressionArgument[Any]] = [ 

175 coercions.expect( 

176 roles.ExpressionElementRole, 

177 c, 

178 name=getattr(self, "name", None), 

179 apply_propagate_attrs=self, 

180 ) 

181 for c in clauses 

182 ] 

183 self._has_args = self._has_args or bool(args) 

184 self.clause_expr = Grouping( 

185 ClauseList(operator=operators.comma_op, group_contents=True, *args) 

186 ) 

187 

188 _non_anon_label = None 

189 

190 @property 

191 def _proxy_key(self) -> Any: 

192 return super()._proxy_key or getattr(self, "name", None) 

193 

194 def _execute_on_connection( 

195 self, 

196 connection: Connection, 

197 distilled_params: _CoreMultiExecuteParams, 

198 execution_options: CoreExecuteOptionsParameter, 

199 ) -> CursorResult[Any]: 

200 return connection._execute_function( 

201 self, distilled_params, execution_options 

202 ) 

203 

204 def scalar_table_valued( 

205 self, name: str, type_: Optional[_TypeEngineArgument[_T]] = None 

206 ) -> ScalarFunctionColumn[_T]: 

207 """Return a column expression that's against this 

208 :class:`_functions.FunctionElement` as a scalar 

209 table-valued expression. 

210 

211 The returned expression is similar to that returned by a single column 

212 accessed off of a :meth:`_functions.FunctionElement.table_valued` 

213 construct, except no FROM clause is generated; the function is rendered 

214 in the similar way as a scalar subquery. 

215 

216 E.g.: 

217 

218 .. sourcecode:: pycon+sql 

219 

220 >>> from sqlalchemy import func, select 

221 >>> fn = func.jsonb_each("{'k', 'v'}").scalar_table_valued("key") 

222 >>> print(select(fn)) 

223 {printsql}SELECT (jsonb_each(:jsonb_each_1)).key 

224 

225 .. versionadded:: 1.4.0b2 

226 

227 .. seealso:: 

228 

229 :meth:`_functions.FunctionElement.table_valued` 

230 

231 :meth:`_functions.FunctionElement.alias` 

232 

233 :meth:`_functions.FunctionElement.column_valued` 

234 

235 """ # noqa: E501 

236 

237 return ScalarFunctionColumn(self, name, type_) 

238 

239 def table_valued( 

240 self, *expr: _ColumnExpressionOrStrLabelArgument[Any], **kw: Any 

241 ) -> TableValuedAlias: 

242 r"""Return a :class:`_sql.TableValuedAlias` representation of this 

243 :class:`_functions.FunctionElement` with table-valued expressions added. 

244 

245 e.g.: 

246 

247 .. sourcecode:: pycon+sql 

248 

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

250 ... "value", "start", "stop", "step" 

251 ... ) 

252 

253 >>> print(select(fn)) 

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

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

256 

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

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

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

260 WHERE anon_1.value > :value_1{stop} 

261 

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

263 argument "with_ordinality": 

264 

265 .. sourcecode:: pycon+sql 

266 

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

268 ... "gen", with_ordinality="ordinality" 

269 ... ) 

270 >>> print(select(fn)) 

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

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

273 

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

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

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

277 datatypes may also be used. 

278 

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

280 If omitted, a unique anonymizing name is used. 

281 

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

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

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

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

286 

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

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

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

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

291 

292 .. versionadded:: 1.4.33 

293 

294 .. versionadded:: 1.4.0b2 

295 

296 

297 .. seealso:: 

298 

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

300 

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

302 

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

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

305 complete table valued expression as a scalar column expression 

306 

307 :meth:`_functions.FunctionElement.column_valued` 

308 

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

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

311 

312 """ # noqa: 501 

313 

314 new_func = self._generate() 

315 

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

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

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

319 

320 if with_ordinality: 

321 expr += (with_ordinality,) 

322 new_func._with_ordinality = True 

323 

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

325 

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

327 

328 def column_valued( 

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

330 ) -> TableValuedColumn[_T]: 

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

332 selects from itself as a FROM clause. 

333 

334 E.g.: 

335 

336 .. sourcecode:: pycon+sql 

337 

338 >>> from sqlalchemy import select, func 

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

340 >>> print(select(gs)) 

341 {printsql}SELECT anon_1 

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

343 

344 This is shorthand for:: 

345 

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

347 

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

349 If omitted, a unique anonymizing name is used. 

350 

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

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

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

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

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

356 

357 .. versionadded:: 1.4.46 

358 

359 .. seealso:: 

360 

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

362 

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

364 

365 :meth:`_functions.FunctionElement.table_valued` 

366 

367 """ # noqa: 501 

368 

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

370 

371 @util.ro_non_memoized_property 

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

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

374 

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

376 placed in the FROM clause of a statement: 

377 

378 .. sourcecode:: pycon+sql 

379 

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

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

382 >>> print(stmt) 

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

384 

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

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

387 method; see that method for details. 

388 

389 .. seealso:: 

390 

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

392 SQL function expressions. 

393 

394 """ # noqa: E501 

395 return self.c 

396 

397 @util.ro_memoized_property 

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

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

400 

401 return ColumnCollection( 

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

403 ) 

404 

405 @property 

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

407 if is_table_value_type(self.type): 

408 # TODO: this might not be fully accurate 

409 cols = cast( 

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

411 ) 

412 else: 

413 cols = [self.label(None)] 

414 

415 return cols 

416 

417 @property 

418 def exported_columns( # type: ignore[override] 

419 self, 

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

421 return self.columns 

422 

423 @HasMemoized.memoized_attribute 

424 def clauses(self) -> ClauseList: 

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

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

427 

428 """ 

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

430 

431 def over( 

432 self, 

433 *, 

434 partition_by: Optional[_ByArgument] = None, 

435 order_by: Optional[_ByArgument] = None, 

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

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

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

439 ) -> Over[_T]: 

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

441 

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

443 for database backends that support window functions. 

444 

445 The expression:: 

446 

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

448 

449 is shorthand for:: 

450 

451 from sqlalchemy import over 

452 

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

454 

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

456 

457 .. seealso:: 

458 

459 :func:`_expression.over` 

460 

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

462 

463 """ 

464 return Over( 

465 self, 

466 partition_by=partition_by, 

467 order_by=order_by, 

468 rows=rows, 

469 range_=range_, 

470 groups=groups, 

471 ) 

472 

473 def aggregate_order_by( 

474 self, *order_by: _ColumnExpressionArgument[Any] 

475 ) -> AggregateOrderBy[_T]: 

476 r"""Produce a :class:`.AggregateOrderBy` object against a function. 

477 

478 Used for aggregating functions such as :class:`_functions.array_agg`, 

479 ``group_concat``, ``json_agg`` on backends that support ordering via an 

480 embedded ORDER BY parameter, e.g. PostgreSQL, MySQL/MariaDB, SQLite. 

481 When used on backends like Oracle and SQL Server, SQL compilation uses 

482 that of :class:`.WithinGroup`. 

483 

484 See :func:`_expression.aggregate_order_by` for a full description. 

485 

486 .. versionadded:: 2.0.44 Generalized the PostgreSQL-specific 

487 :func:`_postgresql.aggregate_order_by` function to a method on 

488 :class:`.Function` that is backend agnostic. 

489 

490 .. seealso:: 

491 

492 :class:`_functions.aggregate_strings` - backend-agnostic string 

493 concatenation function which also supports ORDER BY 

494 

495 """ 

496 

497 return AggregateOrderBy(self, *order_by) 

498 

499 def within_group( 

500 self, *order_by: _ColumnExpressionArgument[Any] 

501 ) -> WithinGroup[_T]: 

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

503 

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

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

506 :class:`.rank`, :class:`.dense_rank`, etc. This feature is typically 

507 used by PostgreSQL, Oracle Database, and Microsoft SQL Server. 

508 

509 For simple ORDER BY expressions within aggregate functions on 

510 PostgreSQL, MySQL/MariaDB, SQLite, see :func:`_sql.aggregate_order_by`. 

511 

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

513 

514 .. seealso:: 

515 

516 :ref:`tutorial_functions_within_group` - 

517 in the :ref:`unified_tutorial` 

518 

519 

520 """ 

521 return WithinGroup(self, *order_by) 

522 

523 @overload 

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

525 

526 @overload 

527 def filter( 

528 self, 

529 __criterion0: _ColumnExpressionArgument[bool], 

530 *criterion: _ColumnExpressionArgument[bool], 

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

532 

533 def filter( 

534 self, *criterion: _ColumnExpressionArgument[bool] 

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

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

537 

538 Used against aggregate and window functions, 

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

540 

541 The expression:: 

542 

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

544 

545 is shorthand for:: 

546 

547 from sqlalchemy import funcfilter 

548 

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

550 

551 .. seealso:: 

552 

553 :ref:`tutorial_functions_within_group` - 

554 in the :ref:`unified_tutorial` 

555 

556 :class:`.FunctionFilter` 

557 

558 :func:`.funcfilter` 

559 

560 

561 """ 

562 if not criterion: 

563 return self 

564 return FunctionFilter(self, *criterion) 

565 

566 def as_comparison( 

567 self, left_index: int, right_index: int 

568 ) -> FunctionAsBinary: 

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

570 values. 

571 

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

573 :ref:`relationship_custom_operator_sql_function`. 

574 

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

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

577 

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

579 

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

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

582 

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

584 

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

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

587 

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

589 

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

591 

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

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

594 

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

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

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

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

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

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

601 

602 An ORM example is as follows:: 

603 

604 class Venue(Base): 

605 __tablename__ = "venue" 

606 id = Column(Integer, primary_key=True) 

607 name = Column(String) 

608 

609 descendants = relationship( 

610 "Venue", 

611 primaryjoin=func.instr( 

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

613 ).as_comparison(1, 2) 

614 == 1, 

615 viewonly=True, 

616 order_by=name, 

617 ) 

618 

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

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

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

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

623 

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

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

626 functions to create join conditions. 

627 

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

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

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

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

632 

633 .. seealso:: 

634 

635 :ref:`relationship_custom_operator_sql_function` - 

636 example use within the ORM 

637 

638 """ 

639 return FunctionAsBinary(self, left_index, right_index) 

640 

641 @property 

642 def _from_objects(self) -> Any: 

643 return self.clauses._from_objects 

644 

645 def within_group_type( 

646 self, within_group: WithinGroup[_S] 

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

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

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

650 :class:`.WithinGroup` construct. 

651 

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

653 is used. 

654 

655 """ 

656 

657 return None 

658 

659 def alias( 

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

661 ) -> TableValuedAlias: 

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

663 :class:`.FunctionElement`. 

664 

665 .. tip:: 

666 

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

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

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

670 :class:`_functions.FunctionElement` including 

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

672 :meth:`_functions.FunctionElement.column_valued`. 

673 

674 This construct wraps the function in a named alias which 

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

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

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

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

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

680 

681 For a full table-valued expression, use the 

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

683 establish named columns. 

684 

685 e.g.: 

686 

687 .. sourcecode:: pycon+sql 

688 

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

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

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

692 {printsql}SELECT data_view 

693 FROM unnest(:unnest_1) AS data_view 

694 

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

696 a shortcut for the above pattern: 

697 

698 .. sourcecode:: pycon+sql 

699 

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

701 >>> print(select(data_view)) 

702 {printsql}SELECT data_view 

703 FROM unnest(:unnest_1) AS data_view 

704 

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

706 

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

708 FROM clause 

709 

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

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

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

713 generated. May be useful for SQL functions such as 

714 ``func.json_each()``. 

715 

716 .. versionadded:: 1.4.33 

717 

718 .. seealso:: 

719 

720 :ref:`tutorial_functions_table_valued` - 

721 in the :ref:`unified_tutorial` 

722 

723 :meth:`_functions.FunctionElement.table_valued` 

724 

725 :meth:`_functions.FunctionElement.scalar_table_valued` 

726 

727 :meth:`_functions.FunctionElement.column_valued` 

728 

729 

730 """ 

731 

732 return TableValuedAlias._construct( 

733 self, 

734 name=name, 

735 table_value_type=self.type, 

736 joins_implicitly=joins_implicitly, 

737 ) 

738 

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

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

741 against this :class:`.FunctionElement`. 

742 

743 This is shorthand for:: 

744 

745 s = select(function_element) 

746 

747 """ 

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

749 if self._execution_options: 

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

751 return s 

752 

753 def _bind_param( 

754 self, 

755 operator: OperatorType, 

756 obj: Any, 

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

758 expanding: bool = False, 

759 **kw: Any, 

760 ) -> BindParameter[_T]: 

761 return BindParameter( 

762 None, 

763 obj, 

764 _compared_to_operator=operator, 

765 _compared_to_type=self.type, 

766 unique=True, 

767 type_=type_, 

768 expanding=expanding, 

769 **kw, 

770 ) 

771 

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

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

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

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

776 # besides postgresql. 

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

778 return Grouping(self) 

779 else: 

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

781 

782 @property 

783 def entity_namespace(self) -> _EntityNamespace: 

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

785 column expressions and not FromClauses. 

786 

787 """ 

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

789 # this adjustment in 1.4 

790 return _entity_namespace(self.clause_expr) 

791 

792 

793class FunctionAsBinary(BinaryExpression[Any]): 

794 _traverse_internals = [ 

795 ("sql_function", InternalTraversal.dp_clauseelement), 

796 ("left_index", InternalTraversal.dp_plain_obj), 

797 ("right_index", InternalTraversal.dp_plain_obj), 

798 ("modifiers", InternalTraversal.dp_plain_dict), 

799 ] 

800 

801 sql_function: FunctionElement[Any] 

802 left_index: int 

803 right_index: int 

804 

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

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

807 

808 def __init__( 

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

810 ) -> None: 

811 self.sql_function = fn 

812 self.left_index = left_index 

813 self.right_index = right_index 

814 

815 self.operator = operators.function_as_comparison_op 

816 self.type = sqltypes.BOOLEANTYPE 

817 self.negate = None 

818 self._is_implicitly_boolean = True 

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

820 

821 @property 

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

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

824 

825 @left_expr.setter 

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

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

828 

829 @property 

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

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

832 

833 @right_expr.setter 

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

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

836 

837 if not TYPE_CHECKING: 

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

839 # variable 

840 

841 left = left_expr 

842 right = right_expr 

843 

844 

845class ScalarFunctionColumn(NamedColumn[_T]): 

846 __visit_name__ = "scalar_function_column" 

847 

848 _traverse_internals = [ 

849 ("name", InternalTraversal.dp_anon_name), 

850 ("type", InternalTraversal.dp_type), 

851 ("fn", InternalTraversal.dp_clauseelement), 

852 ] 

853 

854 is_literal = False 

855 table = None 

856 

857 def __init__( 

858 self, 

859 fn: FunctionElement[_T], 

860 name: str, 

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

862 ) -> None: 

863 self.fn = fn 

864 self.name = name 

865 

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

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

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

869 

870 

871class _FunctionGenerator: 

872 """Generate SQL function expressions. 

873 

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

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

876 

877 .. sourcecode:: pycon+sql 

878 

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

880 {printsql}count(:param_1) 

881 

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

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

884 

885 .. sourcecode:: pycon+sql 

886 

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

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

889 

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

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

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

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

894 

895 .. sourcecode:: pycon+sql 

896 

897 >>> print(func.current_timestamp()) 

898 {printsql}CURRENT_TIMESTAMP 

899 

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

901 specify them in the same manner: 

902 

903 .. sourcecode:: pycon+sql 

904 

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

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

907 

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

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

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

911 treated as a string in expressions, specify 

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

913 

914 .. sourcecode:: pycon+sql 

915 

916 >>> print( 

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

918 ... + " " 

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

920 ... ) 

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

922 

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

924 :class:`.Function`. 

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

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

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

928 where it will be 

929 wrapped inside of a SELECT statement first:: 

930 

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

932 

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

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

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

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

937 perspective. 

938 

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

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

941 functions, see :ref:`generic_functions`. 

942 

943 .. note:: 

944 

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

946 standalone "stored procedures", especially those with special 

947 parameterization concerns. 

948 

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

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

951 procedures. 

952 

953 .. seealso:: 

954 

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

956 

957 :class:`.Function` 

958 

959 """ # noqa 

960 

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

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

963 self.opts = opts 

964 

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

966 # passthru __ attributes; fixes pydoc 

967 if name.startswith("__"): 

968 try: 

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

970 except KeyError: 

971 raise AttributeError(name) 

972 

973 elif name.endswith("_"): 

974 name = name[0:-1] 

975 f = _FunctionGenerator(**self.opts) 

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

977 return f 

978 

979 @overload 

980 def __call__( 

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

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

983 

984 @overload 

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

986 

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

988 o = self.opts.copy() 

989 o.update(kwargs) 

990 

991 tokens = len(self.__names) 

992 

993 if tokens == 2: 

994 package, fname = self.__names 

995 elif tokens == 1: 

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

997 else: 

998 package = None 

999 

1000 if package is not None: 

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

1002 if func is not None: 

1003 return func(*c, **o) 

1004 

1005 return Function( 

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

1007 ) 

1008 

1009 if TYPE_CHECKING: 

1010 # START GENERATED FUNCTION ACCESSORS 

1011 

1012 # code within this block is **programmatically, 

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

1014 

1015 @property 

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

1017 

1018 @property 

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

1020 

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

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

1023 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1024 # _HasClauseElement as of mypy 1.15 

1025 

1026 @overload 

1027 def array_agg( 

1028 self, 

1029 col: ColumnElement[_T], 

1030 *args: _ColumnExpressionOrLiteralArgument[Any], 

1031 **kwargs: Any, 

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

1033 

1034 @overload 

1035 def array_agg( 

1036 self, 

1037 col: _ColumnExpressionArgument[_T], 

1038 *args: _ColumnExpressionOrLiteralArgument[Any], 

1039 **kwargs: Any, 

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

1041 

1042 @overload 

1043 def array_agg( 

1044 self, 

1045 col: _T, 

1046 *args: _ColumnExpressionOrLiteralArgument[Any], 

1047 **kwargs: Any, 

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

1049 

1050 def array_agg( 

1051 self, 

1052 col: _ColumnExpressionOrLiteralArgument[_T], 

1053 *args: _ColumnExpressionOrLiteralArgument[Any], 

1054 **kwargs: Any, 

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

1056 

1057 @property 

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

1059 

1060 @property 

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

1062 

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

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

1065 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1066 # _HasClauseElement as of mypy 1.15 

1067 

1068 @overload 

1069 def coalesce( 

1070 self, 

1071 col: ColumnElement[_T], 

1072 *args: _ColumnExpressionOrLiteralArgument[Any], 

1073 **kwargs: Any, 

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

1075 

1076 @overload 

1077 def coalesce( 

1078 self, 

1079 col: _ColumnExpressionArgument[_T], 

1080 *args: _ColumnExpressionOrLiteralArgument[Any], 

1081 **kwargs: Any, 

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

1083 

1084 @overload 

1085 def coalesce( 

1086 self, 

1087 col: _T, 

1088 *args: _ColumnExpressionOrLiteralArgument[Any], 

1089 **kwargs: Any, 

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

1091 

1092 def coalesce( 

1093 self, 

1094 col: _ColumnExpressionOrLiteralArgument[_T], 

1095 *args: _ColumnExpressionOrLiteralArgument[Any], 

1096 **kwargs: Any, 

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

1098 

1099 @property 

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

1101 

1102 @property 

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

1104 

1105 @property 

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

1107 

1108 @property 

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

1110 

1111 @property 

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

1113 

1114 @property 

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

1116 

1117 @property 

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

1119 

1120 @property 

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

1122 

1123 @property 

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

1125 

1126 @property 

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

1128 

1129 @property 

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

1131 

1132 @property 

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

1134 

1135 @property 

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

1137 

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

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

1140 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1141 # _HasClauseElement as of mypy 1.15 

1142 

1143 @overload 

1144 def max( # noqa: A001 

1145 self, 

1146 col: ColumnElement[_T], 

1147 *args: _ColumnExpressionOrLiteralArgument[Any], 

1148 **kwargs: Any, 

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

1150 

1151 @overload 

1152 def max( # noqa: A001 

1153 self, 

1154 col: _ColumnExpressionArgument[_T], 

1155 *args: _ColumnExpressionOrLiteralArgument[Any], 

1156 **kwargs: Any, 

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

1158 

1159 @overload 

1160 def max( # noqa: A001 

1161 self, 

1162 col: _T, 

1163 *args: _ColumnExpressionOrLiteralArgument[Any], 

1164 **kwargs: Any, 

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

1166 

1167 def max( # noqa: A001 

1168 self, 

1169 col: _ColumnExpressionOrLiteralArgument[_T], 

1170 *args: _ColumnExpressionOrLiteralArgument[Any], 

1171 **kwargs: Any, 

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

1173 

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

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

1176 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1177 # _HasClauseElement as of mypy 1.15 

1178 

1179 @overload 

1180 def min( # noqa: A001 

1181 self, 

1182 col: ColumnElement[_T], 

1183 *args: _ColumnExpressionOrLiteralArgument[Any], 

1184 **kwargs: Any, 

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

1186 

1187 @overload 

1188 def min( # noqa: A001 

1189 self, 

1190 col: _ColumnExpressionArgument[_T], 

1191 *args: _ColumnExpressionOrLiteralArgument[Any], 

1192 **kwargs: Any, 

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

1194 

1195 @overload 

1196 def min( # noqa: A001 

1197 self, 

1198 col: _T, 

1199 *args: _ColumnExpressionOrLiteralArgument[Any], 

1200 **kwargs: Any, 

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

1202 

1203 def min( # noqa: A001 

1204 self, 

1205 col: _ColumnExpressionOrLiteralArgument[_T], 

1206 *args: _ColumnExpressionOrLiteralArgument[Any], 

1207 **kwargs: Any, 

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

1209 

1210 @property 

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

1212 

1213 @property 

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

1215 

1216 @property 

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

1218 

1219 @property 

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

1221 

1222 @property 

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

1224 

1225 @property 

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

1227 

1228 @property 

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

1230 

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

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

1233 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1234 # _HasClauseElement as of mypy 1.15 

1235 

1236 @overload 

1237 def pow( # noqa: A001 

1238 self, 

1239 col: ColumnElement[_T], 

1240 *args: _ColumnExpressionOrLiteralArgument[Any], 

1241 **kwargs: Any, 

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

1243 

1244 @overload 

1245 def pow( # noqa: A001 

1246 self, 

1247 col: _ColumnExpressionArgument[_T], 

1248 *args: _ColumnExpressionOrLiteralArgument[Any], 

1249 **kwargs: Any, 

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

1251 

1252 @overload 

1253 def pow( # noqa: A001 

1254 self, 

1255 col: _T, 

1256 *args: _ColumnExpressionOrLiteralArgument[Any], 

1257 **kwargs: Any, 

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

1259 

1260 def pow( # noqa: A001 

1261 self, 

1262 col: _ColumnExpressionOrLiteralArgument[_T], 

1263 *args: _ColumnExpressionOrLiteralArgument[Any], 

1264 **kwargs: Any, 

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

1266 

1267 @property 

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

1269 

1270 @property 

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

1272 

1273 @property 

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

1275 

1276 @property 

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

1278 

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

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

1281 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1282 # _HasClauseElement as of mypy 1.15 

1283 

1284 @overload 

1285 def sum( # noqa: A001 

1286 self, 

1287 col: ColumnElement[_T], 

1288 *args: _ColumnExpressionOrLiteralArgument[Any], 

1289 **kwargs: Any, 

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

1291 

1292 @overload 

1293 def sum( # noqa: A001 

1294 self, 

1295 col: _ColumnExpressionArgument[_T], 

1296 *args: _ColumnExpressionOrLiteralArgument[Any], 

1297 **kwargs: Any, 

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

1299 

1300 @overload 

1301 def sum( # noqa: A001 

1302 self, 

1303 col: _T, 

1304 *args: _ColumnExpressionOrLiteralArgument[Any], 

1305 **kwargs: Any, 

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

1307 

1308 def sum( # noqa: A001 

1309 self, 

1310 col: _ColumnExpressionOrLiteralArgument[_T], 

1311 *args: _ColumnExpressionOrLiteralArgument[Any], 

1312 **kwargs: Any, 

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

1314 

1315 @property 

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

1317 

1318 @property 

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

1320 

1321 # END GENERATED FUNCTION ACCESSORS 

1322 

1323 

1324func = _FunctionGenerator() 

1325func.__doc__ = _FunctionGenerator.__doc__ 

1326 

1327modifier = _FunctionGenerator(group=False) 

1328 

1329 

1330class Function(FunctionElement[_T]): 

1331 r"""Describe a named SQL function. 

1332 

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

1334 :data:`.func` generation object. 

1335 

1336 

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

1338 of the SQL function call. 

1339 

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

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

1342 function call. 

1343 

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

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

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

1347 dotted format, e.g.:: 

1348 

1349 func.mypackage.some_function(col1, col2) 

1350 

1351 .. seealso:: 

1352 

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

1354 

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

1356 :class:`.Function` instances. 

1357 

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

1359 types. 

1360 

1361 """ 

1362 

1363 __visit_name__ = "function" 

1364 

1365 _traverse_internals = FunctionElement._traverse_internals + [ 

1366 ("packagenames", InternalTraversal.dp_plain_obj), 

1367 ("name", InternalTraversal.dp_string), 

1368 ("type", InternalTraversal.dp_type), 

1369 ] 

1370 

1371 name: str 

1372 

1373 identifier: str 

1374 

1375 type: TypeEngine[_T] 

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

1377 type represented by this SQL function. 

1378 

1379 This datatype may be configured when generating a 

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

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

1382 

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

1384 

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

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

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

1388 "null type". 

1389 

1390 """ 

1391 

1392 @overload 

1393 def __init__( 

1394 self, 

1395 name: str, 

1396 *clauses: _ColumnExpressionOrLiteralArgument[_T], 

1397 type_: None = ..., 

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

1399 ) -> None: ... 

1400 

1401 @overload 

1402 def __init__( 

1403 self, 

1404 name: str, 

1405 *clauses: _ColumnExpressionOrLiteralArgument[Any], 

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

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

1408 ) -> None: ... 

1409 

1410 def __init__( 

1411 self, 

1412 name: str, 

1413 *clauses: _ColumnExpressionOrLiteralArgument[Any], 

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

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

1416 ) -> None: 

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

1418 

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

1420 new :class:`.Function` instances. 

1421 

1422 """ 

1423 self.packagenames = packagenames or () 

1424 self.name = name 

1425 

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

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

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

1429 

1430 FunctionElement.__init__(self, *clauses) 

1431 

1432 def _bind_param( 

1433 self, 

1434 operator: OperatorType, 

1435 obj: Any, 

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

1437 expanding: bool = False, 

1438 **kw: Any, 

1439 ) -> BindParameter[_T]: 

1440 return BindParameter( 

1441 self.name, 

1442 obj, 

1443 _compared_to_operator=operator, 

1444 _compared_to_type=self.type, 

1445 type_=type_, 

1446 unique=True, 

1447 expanding=expanding, 

1448 **kw, 

1449 ) 

1450 

1451 

1452class GenericFunction(Function[_T]): 

1453 """Define a 'generic' function. 

1454 

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

1456 class that is instantiated automatically when called 

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

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

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

1460 given that name. The primary use case for defining 

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

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

1463 It can also include custom argument parsing schemes as well 

1464 as additional methods. 

1465 

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

1467 registered under the name of the class. For 

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

1469 be available immediately:: 

1470 

1471 from sqlalchemy.sql.functions import GenericFunction 

1472 from sqlalchemy.types import DateTime 

1473 

1474 

1475 class as_utc(GenericFunction): 

1476 type = DateTime() 

1477 inherit_cache = True 

1478 

1479 

1480 print(select(func.as_utc())) 

1481 

1482 User-defined generic functions can be organized into 

1483 packages by specifying the "package" attribute when defining 

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

1485 containing many functions may want to use this in order 

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

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

1488 "time":: 

1489 

1490 class as_utc(GenericFunction): 

1491 type = DateTime() 

1492 package = "time" 

1493 inherit_cache = True 

1494 

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

1496 using the package name ``time``:: 

1497 

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

1499 

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

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

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

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

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

1505 

1506 class GeoBuffer(GenericFunction): 

1507 type = Geometry() 

1508 package = "geo" 

1509 name = "ST_Buffer" 

1510 identifier = "buffer" 

1511 inherit_cache = True 

1512 

1513 The above function will render as follows: 

1514 

1515 .. sourcecode:: pycon+sql 

1516 

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

1518 {printsql}ST_Buffer() 

1519 

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

1521 contains special characters that require quoting. To force quoting 

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

1523 construct:: 

1524 

1525 from sqlalchemy.sql import quoted_name 

1526 

1527 

1528 class GeoBuffer(GenericFunction): 

1529 type = Geometry() 

1530 package = "geo" 

1531 name = quoted_name("ST_Buffer", True) 

1532 identifier = "buffer" 

1533 inherit_cache = True 

1534 

1535 The above function will render as: 

1536 

1537 .. sourcecode:: pycon+sql 

1538 

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

1540 {printsql}"ST_Buffer"() 

1541 

1542 Type parameters for this class as a 

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

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

1545 

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

1547 type = DateTime() 

1548 inherit_cache = True 

1549 

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

1551 object:: 

1552 

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

1554 

1555 """ 

1556 

1557 coerce_arguments = True 

1558 inherit_cache = True 

1559 

1560 _register: bool 

1561 

1562 name = "GenericFunction" 

1563 

1564 def __init_subclass__(cls) -> None: 

1565 if annotation.Annotated not in cls.__mro__: 

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

1567 super().__init_subclass__() 

1568 

1569 @classmethod 

1570 def _register_generic_function( 

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

1572 ) -> None: 

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

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

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

1576 # legacy 

1577 if "__return_type__" in clsdict: 

1578 cls.type = clsdict["__return_type__"] 

1579 

1580 # Check _register attribute status 

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

1582 

1583 # Register the function if required 

1584 if cls._register: 

1585 register_function(identifier, cls, package) 

1586 else: 

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

1588 cls._register = True 

1589 

1590 def __init__( 

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

1592 ) -> None: 

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

1594 if parsed_args is None: 

1595 parsed_args = [ 

1596 coercions.expect( 

1597 roles.ExpressionElementRole, 

1598 c, 

1599 name=self.name, 

1600 apply_propagate_attrs=self, 

1601 ) 

1602 for c in args 

1603 ] 

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

1605 self.packagenames = () 

1606 

1607 self.clause_expr = Grouping( 

1608 ClauseList( 

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

1610 ) 

1611 ) 

1612 

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

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

1615 ) 

1616 

1617 

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

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

1620 

1621 

1622class next_value(GenericFunction[int]): 

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

1624 as its single argument. 

1625 

1626 Compiles into the appropriate function on each backend, 

1627 or will raise NotImplementedError if used on a backend 

1628 that does not provide support for sequences. 

1629 

1630 """ 

1631 

1632 type = sqltypes.Integer() 

1633 name = "next_value" 

1634 

1635 _traverse_internals = [ 

1636 ("sequence", InternalTraversal.dp_named_ddl_element) 

1637 ] 

1638 

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

1640 assert isinstance( 

1641 seq, schema.Sequence 

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

1643 self.sequence = seq 

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

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

1646 ) 

1647 

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

1649 return ( 

1650 isinstance(other, next_value) 

1651 and self.sequence.name == other.sequence.name 

1652 ) 

1653 

1654 @property 

1655 def _from_objects(self) -> Any: 

1656 return [] 

1657 

1658 

1659class AnsiFunction(GenericFunction[_T]): 

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

1661 

1662 inherit_cache = True 

1663 

1664 def __init__( 

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

1666 ) -> None: 

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

1668 

1669 

1670class ReturnTypeFromArgs(GenericFunction[_T]): 

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

1672 arguments. 

1673 """ 

1674 

1675 inherit_cache = True 

1676 

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

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

1679 # _ColumnExpressionArgument. Seems somewhat related to the covariant 

1680 # _HasClauseElement as of mypy 1.15 

1681 

1682 @overload 

1683 def __init__( 

1684 self, 

1685 col: ColumnElement[_T], 

1686 *args: _ColumnExpressionOrLiteralArgument[Any], 

1687 **kwargs: Any, 

1688 ) -> None: ... 

1689 

1690 @overload 

1691 def __init__( 

1692 self, 

1693 col: _ColumnExpressionArgument[_T], 

1694 *args: _ColumnExpressionOrLiteralArgument[Any], 

1695 **kwargs: Any, 

1696 ) -> None: ... 

1697 

1698 @overload 

1699 def __init__( 

1700 self, 

1701 col: _T, 

1702 *args: _ColumnExpressionOrLiteralArgument[Any], 

1703 **kwargs: Any, 

1704 ) -> None: ... 

1705 

1706 def __init__( 

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

1708 ) -> None: 

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

1710 coercions.expect( 

1711 roles.ExpressionElementRole, 

1712 c, 

1713 name=self.name, 

1714 apply_propagate_attrs=self, 

1715 ) 

1716 for c in args 

1717 ] 

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

1719 kwargs["_parsed_args"] = fn_args 

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

1721 

1722 

1723class coalesce(ReturnTypeFromArgs[_T]): 

1724 _has_args = True 

1725 inherit_cache = True 

1726 

1727 

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

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

1730 

1731 inherit_cache = True 

1732 

1733 

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

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

1736 

1737 inherit_cache = True 

1738 

1739 

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

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

1742 

1743 inherit_cache = True 

1744 

1745 

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

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

1748 

1749 SQLAlchemy dialects will usually render this particular function 

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

1751 

1752 """ 

1753 

1754 type = sqltypes.DateTime() 

1755 inherit_cache = True 

1756 

1757 

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

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

1760 

1761 E.g.: 

1762 

1763 .. sourcecode:: pycon+sql 

1764 

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

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

1767 

1768 .. versionadded:: 2.1 

1769 

1770 """ 

1771 

1772 inherit_cache = True 

1773 

1774 

1775class concat(GenericFunction[str]): 

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

1777 

1778 E.g.: 

1779 

1780 .. sourcecode:: pycon+sql 

1781 

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

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

1784 

1785 String concatenation in SQLAlchemy is more commonly available using the 

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

1787 backend-specific concatenation operator, such as : 

1788 

1789 .. sourcecode:: pycon+sql 

1790 

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

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

1793 

1794 

1795 """ 

1796 

1797 type = sqltypes.String() 

1798 inherit_cache = True 

1799 

1800 

1801class char_length(GenericFunction[int]): 

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

1803 

1804 type = sqltypes.Integer() 

1805 inherit_cache = True 

1806 

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

1808 # slight hack to limit to just one positional argument 

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

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

1811 

1812 

1813class random(GenericFunction[float]): 

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

1815 

1816 _has_args = True 

1817 inherit_cache = True 

1818 

1819 

1820class count(GenericFunction[int]): 

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

1822 emits COUNT \*. 

1823 

1824 E.g.:: 

1825 

1826 from sqlalchemy import func 

1827 from sqlalchemy import select 

1828 from sqlalchemy import table, column 

1829 

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

1831 

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

1833 

1834 Executing ``stmt`` would emit: 

1835 

1836 .. sourcecode:: sql 

1837 

1838 SELECT count(*) AS count_1 

1839 FROM some_table 

1840 

1841 

1842 """ 

1843 

1844 type = sqltypes.Integer() 

1845 inherit_cache = True 

1846 

1847 def __init__( 

1848 self, 

1849 expression: Union[ 

1850 _ColumnExpressionArgument[Any], _StarOrOne, None 

1851 ] = None, 

1852 **kwargs: Any, 

1853 ) -> None: 

1854 if expression is None: 

1855 expression = literal_column("*") 

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

1857 

1858 

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

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

1861 

1862 type = sqltypes.Date() 

1863 inherit_cache = True 

1864 

1865 

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

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

1868 

1869 type = sqltypes.Time() 

1870 inherit_cache = True 

1871 

1872 

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

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

1875 

1876 type = sqltypes.DateTime() 

1877 inherit_cache = True 

1878 

1879 

1880class current_user(AnsiFunction[str]): 

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

1882 

1883 type = sqltypes.String() 

1884 inherit_cache = True 

1885 

1886 

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

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

1889 

1890 type = sqltypes.DateTime() 

1891 inherit_cache = True 

1892 

1893 

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

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

1896 

1897 type = sqltypes.DateTime() 

1898 inherit_cache = True 

1899 

1900 

1901class session_user(AnsiFunction[str]): 

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

1903 

1904 type = sqltypes.String() 

1905 inherit_cache = True 

1906 

1907 

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

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

1910 

1911 type = sqltypes.DateTime() 

1912 inherit_cache = True 

1913 

1914 

1915class user(AnsiFunction[str]): 

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

1917 

1918 type = sqltypes.String() 

1919 inherit_cache = True 

1920 

1921 

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

1923 """Support for the ARRAY_AGG function. 

1924 

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

1926 type :class:`_types.ARRAY`. 

1927 

1928 e.g.:: 

1929 

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

1931 

1932 .. seealso:: 

1933 

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

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

1936 added. 

1937 

1938 """ 

1939 

1940 inherit_cache = True 

1941 

1942 def __init__( 

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

1944 ) -> None: 

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

1946 coercions.expect( 

1947 roles.ExpressionElementRole, c, apply_propagate_attrs=self 

1948 ) 

1949 for c in args 

1950 ] 

1951 

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

1953 if "type_" not in kwargs: 

1954 type_from_args = _type_from_args(fn_args) 

1955 if isinstance(type_from_args, sqltypes.ARRAY): 

1956 kwargs["type_"] = type_from_args 

1957 else: 

1958 kwargs["type_"] = default_array_type( 

1959 type_from_args, dimensions=1 

1960 ) 

1961 kwargs["_parsed_args"] = fn_args 

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

1963 

1964 

1965class OrderedSetAgg(GenericFunction[_T]): 

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

1967 expression type as defined by the expression passed to the 

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

1969 

1970 array_for_multi_clause = False 

1971 inherit_cache = True 

1972 

1973 def within_group_type( 

1974 self, within_group: WithinGroup[Any] 

1975 ) -> TypeEngine[Any]: 

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

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

1978 within_group.order_by 

1979 ) 

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

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

1982 else: 

1983 return order_by[0].type 

1984 

1985 

1986class mode(OrderedSetAgg[_T]): 

1987 """Implement the ``mode`` 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 

1994 """ 

1995 

1996 inherit_cache = True 

1997 

1998 

1999class percentile_cont(OrderedSetAgg[_T]): 

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

2001 

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

2003 modifier to supply a sort expression to operate upon. 

2004 

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

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

2007 expression's type. 

2008 

2009 """ 

2010 

2011 array_for_multi_clause = True 

2012 inherit_cache = True 

2013 

2014 

2015class percentile_disc(OrderedSetAgg[_T]): 

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

2017 

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

2019 modifier to supply a sort expression to operate upon. 

2020 

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

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

2023 expression's type. 

2024 

2025 """ 

2026 

2027 array_for_multi_clause = True 

2028 inherit_cache = True 

2029 

2030 

2031class rank(GenericFunction[int]): 

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

2033 

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

2035 modifier to supply a sort expression to operate upon. 

2036 

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

2038 

2039 """ 

2040 

2041 type = sqltypes.Integer() 

2042 inherit_cache = True 

2043 

2044 

2045class dense_rank(GenericFunction[int]): 

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

2047 

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

2049 modifier to supply a sort expression to operate upon. 

2050 

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

2052 

2053 """ 

2054 

2055 type = sqltypes.Integer() 

2056 inherit_cache = True 

2057 

2058 

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

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

2061 

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

2063 modifier to supply a sort expression to operate upon. 

2064 

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

2066 

2067 """ 

2068 

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

2070 inherit_cache = True 

2071 

2072 

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

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

2075 

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

2077 modifier to supply a sort expression to operate upon. 

2078 

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

2080 

2081 """ 

2082 

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

2084 inherit_cache = True 

2085 

2086 

2087class cube(GenericFunction[_T]): 

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

2089 

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

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

2092 

2093 stmt = select( 

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

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

2096 

2097 """ 

2098 

2099 _has_args = True 

2100 inherit_cache = True 

2101 

2102 

2103class rollup(GenericFunction[_T]): 

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

2105 

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

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

2108 

2109 stmt = select( 

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

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

2112 

2113 """ 

2114 

2115 _has_args = True 

2116 inherit_cache = True 

2117 

2118 

2119class grouping_sets(GenericFunction[_T]): 

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

2121 

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

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

2124 

2125 stmt = select( 

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

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

2128 

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

2130 

2131 from sqlalchemy import tuple_ 

2132 

2133 stmt = select( 

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

2135 ).group_by( 

2136 func.grouping_sets( 

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

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

2139 ) 

2140 ) 

2141 

2142 """ # noqa: E501 

2143 

2144 _has_args = True 

2145 inherit_cache = True 

2146 

2147 

2148class aggregate_strings(GenericFunction[str]): 

2149 """Implement a generic string aggregation function. 

2150 

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

2152 separate the values by a delimiter. 

2153 

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

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

2156 

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

2158 

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

2160 

2161 .. versionadded:: 2.0.21 

2162 

2163 To add ordering to the expression, use the 

2164 :meth:`_functions.FunctionElement.aggregate_order_by` modifier method, 

2165 which will emit ORDER BY within the appropriate part of the column 

2166 expression (varies by backend):: 

2167 

2168 stmt = select( 

2169 func.aggregate_strings(table.c.str_col, ".").aggregate_order_by( 

2170 table.c.str_col 

2171 ) 

2172 ) 

2173 

2174 .. versionadded:: 2.1 added :meth:`_functions.FunctionElement.aggregate_order_by` 

2175 for all aggregate functions. 

2176 

2177 :param clause: the SQL expression to be concatenated 

2178 

2179 :param separator: separator string 

2180 

2181 

2182 """ # noqa: E501 

2183 

2184 type = sqltypes.String() 

2185 _has_args = True 

2186 inherit_cache = True 

2187 

2188 def __init__( 

2189 self, 

2190 clause: _ColumnExpressionArgument[Any], 

2191 separator: str, 

2192 ) -> None: 

2193 super().__init__(clause, separator)