Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlalchemy/sql/roles.py: 93%
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
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
1# sql/roles.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
7from __future__ import annotations
9from typing import Any
10from typing import Generic
11from typing import Literal
12from typing import Optional
13from typing import TYPE_CHECKING
14from typing import TypeVar
16from .. import util
18if TYPE_CHECKING:
19 from ._typing import _PropagateAttrsType
20 from .elements import Label
21 from .selectable import _SelectIterable
22 from .selectable import FromClause
23 from .selectable import Subquery
25_T = TypeVar("_T", bound=Any)
26_T_co = TypeVar("_T_co", bound=Any, covariant=True)
29class SQLRole:
30 """Define a "role" within a SQL statement structure.
32 Classes within SQL Core participate within SQLRole hierarchies in order
33 to more accurately indicate where they may be used within SQL statements
34 of all types.
36 .. versionadded:: 1.4
38 """
40 __slots__ = ()
41 allows_lambda = False
42 uses_inspection = False
45class SyntaxExtensionRole(SQLRole):
46 __slots__ = ()
47 _role_name = "Syntax extension construct"
50class UsesInspection:
51 __slots__ = ()
52 _post_inspect: Literal[None] = None
53 uses_inspection = True
56class AllowsLambdaRole:
57 __slots__ = ()
58 allows_lambda = True
61class HasCacheKeyRole(SQLRole):
62 __slots__ = ()
63 _role_name = "Cacheable Core or ORM object"
66class ExecutableOptionRole(SQLRole):
67 __slots__ = ()
68 _role_name = "ExecutionOption Core or ORM object"
71class LiteralValueRole(SQLRole):
72 __slots__ = ()
73 _role_name = "Literal Python value"
76class ColumnArgumentRole(SQLRole):
77 __slots__ = ()
78 _role_name = "Column expression"
81class ColumnArgumentOrKeyRole(ColumnArgumentRole):
82 __slots__ = ()
83 _role_name = "Column expression or string key"
86class StrAsPlainColumnRole(ColumnArgumentRole):
87 __slots__ = ()
88 _role_name = "Column expression or string key"
91class ColumnListRole(SQLRole):
92 """Elements suitable for forming comma separated lists of expressions."""
94 __slots__ = ()
97class StringRole(SQLRole):
98 """mixin indicating a role that results in strings"""
100 __slots__ = ()
103class TruncatedLabelRole(StringRole, SQLRole):
104 __slots__ = ()
105 _role_name = "String SQL identifier"
108class TStringElementRole(UsesInspection, SQLRole):
109 """Role for elements that can be interpolated into a TString."""
111 __slots__ = ()
112 _role_name = "TString interpolatable element"
115class ColumnsClauseRole(
116 TStringElementRole, AllowsLambdaRole, UsesInspection, ColumnListRole
117):
118 __slots__ = ()
119 _role_name = (
120 "Column expression, FROM clause, or other columns clause element"
121 )
123 @property
124 def _select_iterable(self) -> _SelectIterable:
125 raise NotImplementedError()
128class TypedColumnsClauseRole(Generic[_T_co], SQLRole):
129 """element-typed form of ColumnsClauseRole"""
131 __slots__ = ()
134class LimitOffsetRole(SQLRole):
135 __slots__ = ()
136 _role_name = "LIMIT / OFFSET expression"
139class ByOfRole(ColumnListRole):
140 __slots__ = ()
141 _role_name = "GROUP BY / OF / etc. expression"
144class GroupByRole(AllowsLambdaRole, UsesInspection, ByOfRole):
145 __slots__ = ()
146 # note there's a special case right now where you can pass a whole
147 # ORM entity to group_by() and it splits out. we may not want to keep
148 # this around
150 _role_name = "GROUP BY expression"
153class OrderByRole(AllowsLambdaRole, ByOfRole):
154 __slots__ = ()
155 _role_name = "ORDER BY expression"
158class StructuralRole(SQLRole):
159 __slots__ = ()
162class StatementOptionRole(StructuralRole):
163 __slots__ = ()
164 _role_name = "statement sub-expression element"
167class OnClauseRole(AllowsLambdaRole, StructuralRole):
168 __slots__ = ()
169 _role_name = (
170 "ON clause, typically a SQL expression or "
171 "ORM relationship attribute"
172 )
175class WhereHavingRole(OnClauseRole):
176 __slots__ = ()
177 _role_name = "SQL expression for WHERE/HAVING role"
180class ExpressionElementRole(TypedColumnsClauseRole[_T_co]):
181 # note when using generics for ExpressionElementRole,
182 # the generic type needs to be in
183 # sqlalchemy.sql.coercions._impl_lookup mapping also.
184 # these are set up for basic types like int, bool, str, float
185 # right now
187 __slots__ = ()
188 _role_name = "SQL expression element"
190 def label(self, name: Optional[str]) -> Label[_T]:
191 raise NotImplementedError()
194class ConstExprRole(ExpressionElementRole[_T]):
195 __slots__ = ()
196 _role_name = "Constant True/False/None expression"
199class LabeledColumnExprRole(ExpressionElementRole[_T]):
200 __slots__ = ()
203class BinaryElementRole(ExpressionElementRole[_T]):
204 __slots__ = ()
205 _role_name = "SQL expression element or literal value"
208class InElementRole(SQLRole):
209 __slots__ = ()
210 _role_name = (
211 "IN expression list, SELECT construct, or bound parameter object"
212 )
215class JoinTargetRole(AllowsLambdaRole, UsesInspection, StructuralRole):
216 __slots__ = ()
217 _role_name = (
218 "Join target, typically a FROM expression, or ORM "
219 "relationship attribute"
220 )
223class FromClauseRole(ColumnsClauseRole, JoinTargetRole):
224 __slots__ = ()
225 _role_name = "FROM expression, such as a Table or alias() object"
227 _is_subquery = False
229 named_with_column: bool
232class AnonymizedFromClauseRole(FromClauseRole):
233 __slots__ = ()
235 if TYPE_CHECKING:
237 def _anonymous_fromclause(
238 self, *, name: Optional[str] = None, flat: bool = False
239 ) -> FromClause: ...
242class ReturnsRowsRole(SQLRole):
243 __slots__ = ()
244 _role_name = (
245 "Row returning expression such as a SELECT, a FROM clause, or an "
246 "INSERT/UPDATE/DELETE with RETURNING"
247 )
250class StatementRole(SQLRole):
251 __slots__ = ()
252 _role_name = "Executable SQL or text() construct"
254 if TYPE_CHECKING:
256 @util.memoized_property
257 def _propagate_attrs(self) -> _PropagateAttrsType: ...
259 else:
260 _propagate_attrs = util.EMPTY_DICT
263class SelectStatementRole(StatementRole, ReturnsRowsRole):
264 __slots__ = ()
265 _role_name = "SELECT construct or equivalent text() construct"
267 def subquery(self) -> Subquery:
268 raise NotImplementedError(
269 "All SelectStatementRole objects should implement a "
270 ".subquery() method."
271 )
274class HasCTERole(ReturnsRowsRole):
275 __slots__ = ()
278class IsCTERole(SQLRole):
279 __slots__ = ()
280 _role_name = "CTE object"
283class CompoundElementRole(AllowsLambdaRole, SQLRole):
284 """SELECT statements inside a CompoundSelect, e.g. UNION, EXTRACT, etc."""
286 __slots__ = ()
287 _role_name = (
288 "SELECT construct for inclusion in a UNION or other set construct"
289 )
292# TODO: are we using this?
293class DMLRole(StatementRole):
294 __slots__ = ()
297class DMLTableRole(FromClauseRole):
298 __slots__ = ()
299 _role_name = "subject table for an INSERT, UPDATE or DELETE"
302class DMLColumnRole(SQLRole):
303 __slots__ = ()
304 _role_name = "SET/VALUES column expression or string key"
307class DMLSelectRole(SQLRole):
308 """A SELECT statement embedded in DML, typically INSERT from SELECT"""
310 __slots__ = ()
311 _role_name = "SELECT statement or equivalent textual object"
314class DDLRole(StatementRole):
315 __slots__ = ()
318class DDLExpressionRole(StructuralRole):
319 __slots__ = ()
320 _role_name = "SQL expression element for DDL constraint"
323class DDLConstraintColumnRole(SQLRole):
324 __slots__ = ()
325 _role_name = "String column name or column expression for DDL constraint"
328class DDLReferredColumnRole(DDLConstraintColumnRole):
329 __slots__ = ()
330 _role_name = (
331 "String column name or Column object for DDL foreign key constraint"
332 )