codekingpro/portable-devtools
115k
1# sql/elements.py
2# Copyright (C) 2005-2024 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# mypy: allow-untyped-defs, allow-untyped-calls
8
9"""Core SQL expression elements, including :class:`_expression.ClauseElement`,
10:class:`_expression.ColumnElement`, and derived classes.
11
12"""
13
14from __future__ import annotations
15
16from decimal import Decimal
17from enum import IntEnum
18import itertools
19import operator
20import re
21import typing
22from typing import AbstractSet
23from typing import Any
24from typing import Callable
25from typing import cast
26from typing import Dict
27from typing import FrozenSet
28from typing import Generic
29from typing import Iterable
30from typing import Iterator
31from typing import List
32from typing import Mapping
33from typing import Optional
34from typing import overload
35from typing import Sequence
36from typing import Set
37from typing import Tuple as typing_Tuple
38from typing import Type
39from typing import TYPE_CHECKING
40from typing import TypeVar
41from typing import Union
42
43from . import coercions
44from . import operators
45from . import roles
46from . import traversals
47from . import type_api
48from ._typing import has_schema_attr
49from ._typing import is_named_from_clause
50from ._typing import is_quoted_name
51from ._typing import is_tuple_type
52from .annotation import Annotated
53from .annotation import SupportsWrappingAnnotations
54from .base import _clone
55from .base import _expand_cloned
56from .base import _generative
57from .base import _NoArg
58from .base import Executable
59from .base import Generative
60from .base import HasMemoized
61from .base import Immutable
62from .base import NO_ARG
63from .base import SingletonConstant
64from .cache_key import MemoizedHasCacheKey
65from .cache_key import NO_CACHE
66from .coercions import _document_text_coercion # noqa
67from .operators import ColumnOperators
68from .traversals import HasCopyInternals
69from .visitors import cloned_traverse
70from .visitors import ExternallyTraversible
71from .visitors import InternalTraversal
72from .visitors import traverse
73from .visitors import Visitable
74from .. import exc
75from .. import inspection
76from .. import util
77from ..util import HasMemoized_ro_memoized_attribute
78from ..util import TypingOnly
79from ..util.typing import Literal
80from ..util.typing import ParamSpec
81from ..util.typing import Self
82
83if typing.TYPE_CHECKING:
84 from ._typing import _ByArgument
85 from ._typing import _ColumnExpressionArgument
86 from ._typing import _ColumnExpressionOrStrLabelArgument
87 from ._typing import _HasDialect
88 from ._typing import _InfoType
89 from ._typing import _PropagateAttrsType
90 from ._typing import _TypeEngineArgument
91 from .cache_key import _CacheKeyTraversalType
92 from .cache_key import CacheKey
93 from .compiler import Compiled
94 from .compiler import SQLCompiler
95 from .functions import FunctionElement
96 from .operators import OperatorType
97 from .schema import Column
98 from .schema import DefaultGenerator
99 from .schema import FetchedValue
100 from .schema import ForeignKey
101 from .selectable import _SelectIterable
102 from .selectable import FromClause
103 from .selectable import NamedFromClause
104 from .selectable import TextualSelect
105 from .sqltypes import TupleType
106 from .type_api import TypeEngine
107 from .visitors import _CloneCallableType
108 from .visitors import _TraverseInternalsType
109 from .visitors import anon_map
110 from ..engine import Connection
111 from ..engine import Dialect
112 from ..engine.interfaces import _CoreMultiExecuteParams
113 from ..engine.interfaces import CacheStats
114 from ..engine.interfaces import CompiledCacheType
115 from ..engine.interfaces import CoreExecuteOptionsParameter
116 from ..engine.interfaces import SchemaTranslateMapType
117 from ..engine.result import Result
118
119_NUMERIC = Union[float, Decimal]
120_NUMBER = Union[float, int, Decimal]
121
122_T = TypeVar("_T", bound="Any")
123_T_co = TypeVar("_T_co", bound=Any, covariant=True)
124_OPT = TypeVar("_OPT", bound="Any")
125_NT = TypeVar("_NT", bound="_NUMERIC")
126
127_NMT = TypeVar("_NMT", bound="_NUMBER")
128
129
130@overload
131def literal(
132 value: Any,
133 type_: _TypeEngineArgument[_T],
134 literal_execute: bool = False,
135) -> BindParameter[_T]: ...
136
137
138@overload
139def literal(
140 value: _T,
141 type_: None = None,
142 literal_execute: bool = False,
143) -> BindParameter[_T]: ...
144
145
146@overload
147def literal(
148 value: Any,
149 type_: Optional[_TypeEngineArgument[Any]] = None,
150 literal_execute: bool = False,
151) -> BindParameter[Any]: ...
152
153
154def literal(
155 value: Any,
156 type_: Optional[_TypeEngineArgument[Any]] = None,
157 literal_execute: bool = False,
158) -> BindParameter[Any]:
159 r"""Return a literal clause, bound to a bind parameter.
160
161 Literal clauses are created automatically when non-
162 :class:`_expression.ClauseElement` objects (such as strings, ints, dates,
163 etc.) are
164 used in a comparison operation with a :class:`_expression.ColumnElement`
165 subclass,
166 such as a :class:`~sqlalchemy.schema.Column` object. Use this function
167 to force the generation of a literal clause, which will be created as a
168 :class:`BindParameter` with a bound value.
169
170 :param value: the value to be bound. Can be any Python object supported by
171 the underlying DB-API, or is translatable via the given type argument.
172
173 :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine` which will
174 provide bind-parameter translation for this literal.
175
176 :param literal_execute: optional bool, when True, the SQL engine will
177 attempt to render the bound value directly in the SQL statement at
178 execution time rather than providing as a parameter value.
179
180 .. versionadded:: 2.0
181
182 """
183 return coercions.expect(
184 roles.LiteralValueRole,
185 value,
186 type_=type_,
187 literal_execute=literal_execute,
188 )
189
190
191def literal_column(
192 text: str, type_: Optional[_TypeEngineArgument[_T]] = None
193) -> ColumnClause[_T]:
194 r"""Produce a :class:`.ColumnClause` object that has the
195 :paramref:`_expression.column.is_literal` flag set to True.
196
197 :func:`_expression.literal_column` is similar to
198 :func:`_expression.column`, except that
199 it is more often used as a "standalone" column expression that renders
200 exactly as stated; while :func:`_expression.column`
201 stores a string name that
202 will be assumed to be part of a table and may be quoted as such,
203 :func:`_expression.literal_column` can be that,
204 or any other arbitrary column-oriented
205 expression.
206
207 :param text: the text of the expression; can be any SQL expression.
208 Quoting rules will not be applied. To specify a column-name expression
209 which should be subject to quoting rules, use the :func:`column`
210 function.
211
212 :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine`
213 object which will
214 provide result-set translation and additional expression semantics for
215 this column. If left as ``None`` the type will be :class:`.NullType`.
216
217 .. seealso::
218
219 :func:`_expression.column`
220
221 :func:`_expression.text`
222
223 :ref:`tutorial_select_arbitrary_text`
224
225 """
226 return ColumnClause(text, type_=type_, is_literal=True)
227
228
229class CompilerElement(Visitable):
230 """base class for SQL elements that can be compiled to produce a
231 SQL string.
232
233 .. versionadded:: 2.0
234
235 """
236
237 __slots__ = ()
238 __visit_name__ = "compiler_element"
239
240 supports_execution = False
241
242 stringify_dialect = "default"
243
244 @util.preload_module("sqlalchemy.engine.default")
245 @util.preload_module("sqlalchemy.engine.url")
246 def compile(
247 self,
248 bind: Optional[_HasDialect] = None,
249 dialect: Optional[Dialect] = None,
250 **kw: Any,
251 ) -> Compiled:
252 """Compile this SQL expression.
253
254 The return value is a :class:`~.Compiled` object.
255 Calling ``str()`` or ``unicode()`` on the returned value will yield a
256 string representation of the result. The
257 :class:`~.Compiled` object also can return a
258 dictionary of bind parameter names and values
259 using the ``params`` accessor.
260
261 :param bind: An :class:`.Connection` or :class:`.Engine` which
262 can provide a :class:`.Dialect` in order to generate a
263 :class:`.Compiled` object. If the ``bind`` and
264 ``dialect`` parameters are both omitted, a default SQL compiler
265 is used.
266
267 :param column_keys: Used for INSERT and UPDATE statements, a list of
268 column names which should be present in the VALUES clause of the
269 compiled statement. If ``None``, all columns from the target table
270 object are rendered.
271
272 :param dialect: A :class:`.Dialect` instance which can generate
273 a :class:`.Compiled` object. This argument takes precedence over
274 the ``bind`` argument.
275
276 :param compile_kwargs: optional dictionary of additional parameters
277 that will be passed through to the compiler within all "visit"
278 methods. This allows any custom flag to be passed through to
279 a custom compilation construct, for example. It is also used
280 for the case of passing the ``literal_binds`` flag through::
281
282 from sqlalchemy.sql import table, column, select
283
284 t = table('t', column('x'))
285
286 s = select(t).where(t.c.x == 5)
287
288 print(s.compile(compile_kwargs={"literal_binds": True}))
289
290 .. seealso::
291
292 :ref:`faq_sql_expression_string`
293
294 """
295
296 if dialect is None:
297 if bind:
298 dialect = bind.dialect
299 elif self.stringify_dialect == "default":
300 default = util.preloaded.engine_default
301 dialect = default.StrCompileDialect()
302 else:
303 url = util.preloaded.engine_url
304 dialect = url.URL.create(
305 self.stringify_dialect
306 ).get_dialect()()
307
308 return self._compiler(dialect, **kw)
309
310 def _compiler(self, dialect: Dialect, **kw: Any) -> Compiled:
311 """Return a compiler appropriate for this ClauseElement, given a
312 Dialect."""
313
314 if TYPE_CHECKING:
315 assert isinstance(self, ClauseElement)
316 return dialect.statement_compiler(dialect, self, **kw)
317
318 def __str__(self) -> str:
319 return str(self.compile())
320
321
322@inspection._self_inspects
323class ClauseElement(
324 SupportsWrappingAnnotations,
325 MemoizedHasCacheKey,
326 HasCopyInternals,
327 ExternallyTraversible,
328 CompilerElement,
329):
330 """Base class for elements of a programmatically constructed SQL
331 expression.
332
333 """
334
335 __visit_name__ = "clause"
336
337 if TYPE_CHECKING:
338
339 @util.memoized_property
340 def _propagate_attrs(self) -> _PropagateAttrsType:
341 """like annotations, however these propagate outwards liberally
342 as SQL constructs are built, and are set up at construction time.
343
344 """
345 ...
346
347 else:
348 _propagate_attrs = util.EMPTY_DICT
349
350 @util.ro_memoized_property
351 def description(self) -> Optional[str]:
352 return None
353
354 _is_clone_of: Optional[Self] = None
355
356 is_clause_element = True
357 is_selectable = False
358 is_dml = False
359 _is_column_element = False
360 _is_keyed_column_element = False
361 _is_table = False
362 _gen_static_annotations_cache_key = False
363 _is_textual = False
364 _is_from_clause = False
365 _is_returns_rows = False
366 _is_text_clause = False
367 _is_from_container = False
368 _is_select_container = False
369 _is_select_base = False
370 _is_select_statement = False
371 _is_bind_parameter = False
372 _is_clause_list = False
373 _is_lambda_element = False
374 _is_singleton_constant = False
375 _is_immutable = False
376 _is_star = False
377
378 @property
379 def _order_by_label_element(self) -> Optional[Label[Any]]:
380 return None
381
382 _cache_key_traversal: _CacheKeyTraversalType = None
383
384 negation_clause: ColumnElement[bool]
385
386 if typing.TYPE_CHECKING:
387
388 def get_children(
389 self, *, omit_attrs: typing_Tuple[str, ...] = ..., **kw: Any
390 ) -> Iterable[ClauseElement]: ...
391
392 @util.ro_non_memoized_property
393 def _from_objects(self) -> List[FromClause]:
394 return []
395
396 def _set_propagate_attrs(self, values: Mapping[str, Any]) -> Self:
397 # usually, self._propagate_attrs is empty here. one case where it's
398 # not is a subquery against ORM select, that is then pulled as a
399 # property of an aliased class. should all be good
400
401 # assert not self._propagate_attrs
402
403 self._propagate_attrs = util.immutabledict(values)
404 return self
405
406 def _clone(self, **kw: Any) -> Self:
407 """Create a shallow copy of this ClauseElement.
408
409 This method may be used by a generative API. Its also used as
410 part of the "deep" copy afforded by a traversal that combines
411 the _copy_internals() method.
412
413 """
414
415 skip = self._memoized_keys
416 c = self.__class__.__new__(self.__class__)
417
418 if skip:
419 # ensure this iteration remains atomic
420 c.__dict__ = {
421 k: v for k, v in self.__dict__.copy().items() if k not in skip
422 }
423 else:
424 c.__dict__ = self.__dict__.copy()
425
426 # this is a marker that helps to "equate" clauses to each other
427 # when a Select returns its list of FROM clauses. the cloning
428 # process leaves around a lot of remnants of the previous clause
429 # typically in the form of column expressions still attached to the
430 # old table.
431 cc = self._is_clone_of
432 c._is_clone_of = cc if cc is not None else self
433 return c
434
435 def _negate_in_binary(self, negated_op, original_op):
436 """a hook to allow the right side of a binary expression to respond
437 to a negation of the binary expression.
438
439 Used for the special case of expanding bind parameter with IN.
440
441 """
442 return self
443
444 def _with_binary_element_type(self, type_):
445 """in the context of binary expression, convert the type of this
446 object to the one given.
447
448 applies only to :class:`_expression.ColumnElement` classes.
449
450 """
451 return self
452
453 @property
454 def _constructor(self):
455 """return the 'constructor' for this ClauseElement.
456
457 This is for the purposes for creating a new object of
458 this type. Usually, its just the element's __class__.
459 However, the "Annotated" version of the object overrides
460 to return the class of its proxied element.
461
462 """
463 return self.__class__
464
465 @HasMemoized.memoized_attribute
466 def _cloned_set(self):
467 """Return the set consisting all cloned ancestors of this
468 ClauseElement.
469
470 Includes this ClauseElement. This accessor tends to be used for
471 FromClause objects to identify 'equivalent' FROM clauses, regardless
472 of transformative operations.
473
474 """
475 s = util.column_set()
476 f: Optional[ClauseElement] = self
477
478 # note this creates a cycle, asserted in test_memusage. however,
479 # turning this into a plain @property adds tends of thousands of method
480 # calls to Core / ORM performance tests, so the small overhead
481 # introduced by the relatively small amount of short term cycles
482 # produced here is preferable
483 while f is not None:
484 s.add(f)
485 f = f._is_clone_of
486 return s
487
488 def _de_clone(self):
489 while self._is_clone_of is not None:
490 self = self._is_clone_of
491 return self
492
493 @property
494 def entity_namespace(self):
495 raise AttributeError(
496 "This SQL expression has no entity namespace "
497 "with which to filter from."
498 )
499
500 def __getstate__(self):
501 d = self.__dict__.copy()
502 d.pop("_is_clone_of", None)
503 d.pop("_generate_cache_key", None)
504 return d
505
506 def _execute_on_connection(
507 self,
508 connection: Connection,
509 distilled_params: _CoreMultiExecuteParams,
510 execution_options: CoreExecuteOptionsParameter,
511 ) -> Result[Any]:
512 if self.supports_execution:
513 if TYPE_CHECKING:
514 assert isinstance(self, Executable)
515 return connection._execute_clauseelement(
516 self, distilled_params, execution_options
517 )
518 else:
519 raise exc.ObjectNotExecutableError(self)
520
521 def _execute_on_scalar(
522 self,
523 connection: Connection,
524 distilled_params: _CoreMultiExecuteParams,
525 execution_options: CoreExecuteOptionsParameter,
526 ) -> Any:
527 """an additional hook for subclasses to provide a different
528 implementation for connection.scalar() vs. connection.execute().
529
530 .. versionadded:: 2.0
531
532 """
533 return self._execute_on_connection(
534 connection, distilled_params, execution_options
535 ).scalar()
536
537 def _get_embedded_bindparams(self) -> Sequence[BindParameter[Any]]:
538 """Return the list of :class:`.BindParameter` objects embedded in the
539 object.
540
541 This accomplishes the same purpose as ``visitors.traverse()`` or
542 similar would provide, however by making use of the cache key
543 it takes advantage of memoization of the key to result in fewer
544 net method calls, assuming the statement is also going to be
545 executed.
546
547 """
548
549 key = self._generate_cache_key()
550 if key is None:
551 bindparams: List[BindParameter[Any]] = []
552
553 traverse(self, {}, {"bindparam": bindparams.append})
554 return bindparams
555
556 else:
557 return key.bindparams
558
559 def unique_params(
560 self,
561 __optionaldict: Optional[Dict[str, Any]] = None,
562 **kwargs: Any,
563 ) -> Self:
564 """Return a copy with :func:`_expression.bindparam` elements
565 replaced.
566
567 Same functionality as :meth:`_expression.ClauseElement.params`,
568 except adds `unique=True`
569 to affected bind parameters so that multiple statements can be
570 used.
571
572 """
573 return self._replace_params(True, __optionaldict, kwargs)
574
575 def params(
576 self,
577 __optionaldict: Optional[Mapping[str, Any]] = None,
578 **kwargs: Any,
579 ) -> Self:
580 """Return a copy with :func:`_expression.bindparam` elements
581 replaced.
582
583 Returns a copy of this ClauseElement with
584 :func:`_expression.bindparam`
585 elements replaced with values taken from the given dictionary::
586
587 >>> clause = column('x') + bindparam('foo')
588 >>> print(clause.compile().params)
589 {'foo':None}
590 >>> print(clause.params({'foo':7}).compile().params)
591 {'foo':7}
592
593 """
594 return self._replace_params(False, __optionaldict, kwargs)
595
596 def _replace_params(
597 self,
598 unique: bool,
599 optionaldict: Optional[Mapping[str, Any]],
600 kwargs: Dict[str, Any],
601 ) -> Self:
602 if optionaldict:
603 kwargs.update(optionaldict)
604
605 def visit_bindparam(bind: BindParameter[Any]) -> None:
606 if bind.key in kwargs:
607 bind.value = kwargs[bind.key]
608 bind.required = False
609 if unique:
610 bind._convert_to_unique()
611
612 return cloned_traverse(
613 self,
614 {"maintain_key": True, "detect_subquery_cols": True},
615 {"bindparam": visit_bindparam},
616 )
617
618 def compare(self, other: ClauseElement, **kw: Any) -> bool:
619 r"""Compare this :class:`_expression.ClauseElement` to
620 the given :class:`_expression.ClauseElement`.
621
622 Subclasses should override the default behavior, which is a
623 straight identity comparison.
624
625 \**kw are arguments consumed by subclass ``compare()`` methods and
626 may be used to modify the criteria for comparison
627 (see :class:`_expression.ColumnElement`).
628
629 """
630 return traversals.compare(self, other, **kw)
631
632 def self_group(
633 self, against: Optional[OperatorType] = None
634 ) -> ClauseElement:
635 """Apply a 'grouping' to this :class:`_expression.ClauseElement`.
636
637 This method is overridden by subclasses to return a "grouping"
638 construct, i.e. parenthesis. In particular it's used by "binary"
639 expressions to provide a grouping around themselves when placed into a
640 larger expression, as well as by :func:`_expression.select`
641 constructs when placed into the FROM clause of another
642 :func:`_expression.select`. (Note that subqueries should be
643 normally created using the :meth:`_expression.Select.alias` method,
644 as many
645 platforms require nested SELECT statements to be named).
646
647 As expressions are composed together, the application of
648 :meth:`self_group` is automatic - end-user code should never
649 need to use this method directly. Note that SQLAlchemy's
650 clause constructs take operator precedence into account -
651 so parenthesis might not be needed, for example, in
652 an expression like ``x OR (y AND z)`` - AND takes precedence
653 over OR.
654
655 The base :meth:`self_group` method of
656 :class:`_expression.ClauseElement`
657 just returns self.
658 """
659 return self
660
661 def _ungroup(self) -> ClauseElement:
662 """Return this :class:`_expression.ClauseElement`
663 without any groupings.
664 """
665
666 return self
667
668 def _compile_w_cache(
669 self,
670 dialect: Dialect,
671 *,
672 compiled_cache: Optional[CompiledCacheType],
673 column_keys: List[str],
674 for_executemany: bool = False,
675 schema_translate_map: Optional[SchemaTranslateMapType] = None,
676 **kw: Any,
677 ) -> typing_Tuple[
678 Compiled, Optional[Sequence[BindParameter[Any]]], CacheStats
679 ]:
680 elem_cache_key: Optional[CacheKey]
681
682 if compiled_cache is not None and dialect._supports_statement_cache:
683 elem_cache_key = self._generate_cache_key()
684 else:
685 elem_cache_key = None
686
687 if elem_cache_key is not None:
688 if TYPE_CHECKING:
689 assert compiled_cache is not None
690
691 cache_key, extracted_params = elem_cache_key
692 key = (
693 dialect,
694 cache_key,
695 tuple(column_keys),
696 bool(schema_translate_map),
697 for_executemany,
698 )
699 compiled_sql = compiled_cache.get(key)
700
701 if compiled_sql is None:
702 cache_hit = dialect.CACHE_MISS
703 compiled_sql = self._compiler(
704 dialect,
705 cache_key=elem_cache_key,
706 column_keys=column_keys,
707 for_executemany=for_executemany,
708 schema_translate_map=schema_translate_map,
709 **kw,
710 )
711 compiled_cache[key] = compiled_sql
712 else:
713 cache_hit = dialect.CACHE_HIT
714 else:
715 extracted_params = None
716 compiled_sql = self._compiler(
717 dialect,
718 cache_key=elem_cache_key,
719 column_keys=column_keys,
720 for_executemany=for_executemany,
721 schema_translate_map=schema_translate_map,
722 **kw,
723 )
724
725 if not dialect._supports_statement_cache:
726 cache_hit = dialect.NO_DIALECT_SUPPORT
727 elif compiled_cache is None:
728 cache_hit = dialect.CACHING_DISABLED
729 else:
730 cache_hit = dialect.NO_CACHE_KEY
731
732 return compiled_sql, extracted_params, cache_hit
733
734 def __invert__(self):
735 # undocumented element currently used by the ORM for
736 # relationship.contains()
737 if hasattr(self, "negation_clause"):
738 return self.negation_clause
739 else:
740 return self._negate()
741
742 def _negate(self) -> ClauseElement:
743 grouped = self.self_group(against=operators.inv)
744 assert isinstance(grouped, ColumnElement)
745 return UnaryExpression(grouped, operator=operators.inv)
746
747 def __bool__(self):
748 raise TypeError("Boolean value of this clause is not defined")
749
750 def __repr__(self):
751 friendly = self.description
752 if friendly is None:
753 return object.__repr__(self)
754 else:
755 return "<%s.%s at 0x%x; %s>" % (
756 self.__module__,
757 self.__class__.__name__,
758 id(self),
759 friendly,
760 )
761
762
763class DQLDMLClauseElement(ClauseElement):
764 """represents a :class:`.ClauseElement` that compiles to a DQL or DML
765 expression, not DDL.
766
767 .. versionadded:: 2.0
768
769 """
770
771 if typing.TYPE_CHECKING:
772
773 def _compiler(self, dialect: Dialect, **kw: Any) -> SQLCompiler:
774 """Return a compiler appropriate for this ClauseElement, given a
775 Dialect."""
776 ...
777
778 def compile( # noqa: A001
779 self,
780 bind: Optional[_HasDialect] = None,
781 dialect: Optional[Dialect] = None,
782 **kw: Any,
783 ) -> SQLCompiler: ...
784
785
786class CompilerColumnElement(
787 roles.DMLColumnRole,
788 roles.DDLConstraintColumnRole,
789 roles.ColumnsClauseRole,
790 CompilerElement,
791):
792 """A compiler-only column element used for ad-hoc string compilations.
793
794 .. versionadded:: 2.0
795
796 """
797
798 __slots__ = ()
799
800 _propagate_attrs = util.EMPTY_DICT
801 _is_collection_aggregate = False
802
803
804# SQLCoreOperations should be suiting the ExpressionElementRole
805# and ColumnsClauseRole. however the MRO issues become too elaborate
806# at the moment.
807class SQLCoreOperations(Generic[_T_co], ColumnOperators, TypingOnly):
808 __slots__ = ()
809
810 # annotations for comparison methods
811 # these are from operators->Operators / ColumnOperators,
812 # redefined with the specific types returned by ColumnElement hierarchies
813 if typing.TYPE_CHECKING:
814
815 @util.non_memoized_property
816 def _propagate_attrs(self) -> _PropagateAttrsType: ...
817
818 def operate(
819 self, op: OperatorType, *other: Any, **kwargs: Any
820 ) -> ColumnElement[Any]: ...
821
822 def reverse_operate(
823 self, op: OperatorType, other: Any, **kwargs: Any
824 ) -> ColumnElement[Any]: ...
825
826 @overload
827 def op(
828 self,
829 opstring: str,
830 precedence: int = ...,
831 is_comparison: bool = ...,
832 *,
833 return_type: _TypeEngineArgument[_OPT],
834 python_impl: Optional[Callable[..., Any]] = None,
835 ) -> Callable[[Any], BinaryExpression[_OPT]]: ...
836
837 @overload
838 def op(
839 self,
840 opstring: str,
841 precedence: int = ...,
842 is_comparison: bool = ...,
843 return_type: Optional[_TypeEngineArgument[Any]] = ...,
844 python_impl: Optional[Callable[..., Any]] = ...,
845 ) -> Callable[[Any], BinaryExpression[Any]]: ...
846
847 def op(
848 self,
849 opstring: str,
850 precedence: int = 0,
851 is_comparison: bool = False,
852 return_type: Optional[_TypeEngineArgument[Any]] = None,
853 python_impl: Optional[Callable[..., Any]] = None,
854 ) -> Callable[[Any], BinaryExpression[Any]]: ...
855
856 def bool_op(
857 self,
858 opstring: str,
859 precedence: int = 0,
860 python_impl: Optional[Callable[..., Any]] = None,
861 ) -> Callable[[Any], BinaryExpression[bool]]: ...
862
863 def __and__(self, other: Any) -> BooleanClauseList: ...
864
865 def __or__(self, other: Any) -> BooleanClauseList: ...
866
867 def __invert__(self) -> ColumnElement[_T_co]: ...
868
869 def __lt__(self, other: Any) -> ColumnElement[bool]: ...
870
871 def __le__(self, other: Any) -> ColumnElement[bool]: ...
872
873 # declare also that this class has an hash method otherwise
874 # it may be assumed to be None by type checkers since the
875 # object defines __eq__ and python sets it to None in that case:
876 # https://docs.python.org/3/reference/datamodel.html#object.__hash__
877 def __hash__(self) -> int: ...
878
879 def __eq__(self, other: Any) -> ColumnElement[bool]: # type: ignore[override] # noqa: E501
880 ...
881
882 def __ne__(self, other: Any) -> ColumnElement[bool]: # type: ignore[override] # noqa: E501
883 ...
884
885 def is_distinct_from(self, other: Any) -> ColumnElement[bool]: ...
886
887 def is_not_distinct_from(self, other: Any) -> ColumnElement[bool]: ...
888
889 def __gt__(self, other: Any) -> ColumnElement[bool]: ...
890
891 def __ge__(self, other: Any) -> ColumnElement[bool]: ...
892
893 def __neg__(self) -> UnaryExpression[_T_co]: ...
894
895 def __contains__(self, other: Any) -> ColumnElement[bool]: ...
896
897 def __getitem__(self, index: Any) -> ColumnElement[Any]: ...
898
899 @overload
900 def __lshift__(self: _SQO[int], other: Any) -> ColumnElement[int]: ...
901
902 @overload
903 def __lshift__(self, other: Any) -> ColumnElement[Any]: ...
904
905 def __lshift__(self, other: Any) -> ColumnElement[Any]: ...
906
907 @overload
908 def __rshift__(self: _SQO[int], other: Any) -> ColumnElement[int]: ...
909
910 @overload
911 def __rshift__(self, other: Any) -> ColumnElement[Any]: ...
912
913 def __rshift__(self, other: Any) -> ColumnElement[Any]: ...
914
915 @overload
916 def concat(self: _SQO[str], other: Any) -> ColumnElement[str]: ...
917
918 @overload
919 def concat(self, other: Any) -> ColumnElement[Any]: ...
920
921 def concat(self, other: Any) -> ColumnElement[Any]: ...
922
923 def like(
924 self, other: Any, escape: Optional[str] = None
925 ) -> BinaryExpression[bool]: ...
926
927 def ilike(
928 self, other: Any, escape: Optional[str] = None
929 ) -> BinaryExpression[bool]: ...
930
931 def bitwise_xor(self, other: Any) -> BinaryExpression[Any]: ...
932
933 def bitwise_or(self, other: Any) -> BinaryExpression[Any]: ...
934
935 def bitwise_and(self, other: Any) -> BinaryExpression[Any]: ...
936
937 def bitwise_not(self) -> UnaryExpression[_T_co]: ...
938
939 def bitwise_lshift(self, other: Any) -> BinaryExpression[Any]: ...
940
941 def bitwise_rshift(self, other: Any) -> BinaryExpression[Any]: ...
942
943 def in_(
944 self,
945 other: Union[
946 Iterable[Any], BindParameter[Any], roles.InElementRole
947 ],
948 ) -> BinaryExpression[bool]: ...
949
950 def not_in(
951 self,
952 other: Union[
953 Iterable[Any], BindParameter[Any], roles.InElementRole
954 ],
955 ) -> BinaryExpression[bool]: ...
956
957 def notin_(
958 self,
959 other: Union[
960 Iterable[Any], BindParameter[Any], roles.InElementRole
961 ],
962 ) -> BinaryExpression[bool]: ...
963
964 def not_like(
965 self, other: Any, escape: Optional[str] = None
966 ) -> BinaryExpression[bool]: ...
967
968 def notlike(
969 self, other: Any, escape: Optional[str] = None
970 ) -> BinaryExpression[bool]: ...
971
972 def not_ilike(
973 self, other: Any, escape: Optional[str] = None
974 ) -> BinaryExpression[bool]: ...
975
976 def notilike(
977 self, other: Any, escape: Optional[str] = None
978 ) -> BinaryExpression[bool]: ...
979
980 def is_(self, other: Any) -> BinaryExpression[bool]: ...
981
982 def is_not(self, other: Any) -> BinaryExpression[bool]: ...
983
984 def isnot(self, other: Any) -> BinaryExpression[bool]: ...
985
986 def startswith(
987 self,
988 other: Any,
989 escape: Optional[str] = None,
990 autoescape: bool = False,
991 ) -> ColumnElement[bool]: ...
992
993 def istartswith(
994 self,
995 other: Any,
996 escape: Optional[str] = None,
997 autoescape: bool = False,
998 ) -> ColumnElement[bool]: ...
999
1000 def endswith(
1001 self,
1002 other: Any,
1003 escape: Optional[str] = None,
1004 autoescape: bool = False,
1005 ) -> ColumnElement[bool]: ...
1006
1007 def iendswith(
1008 self,
1009 other: Any,
1010 escape: Optional[str] = None,
1011 autoescape: bool = False,
1012 ) -> ColumnElement[bool]: ...
1013
1014 def contains(self, other: Any, **kw: Any) -> ColumnElement[bool]: ...
1015
1016 def icontains(self, other: Any, **kw: Any) -> ColumnElement[bool]: ...
1017
1018 def match(self, other: Any, **kwargs: Any) -> ColumnElement[bool]: ...
1019
1020 def regexp_match(
1021 self, pattern: Any, flags: Optional[str] = None
1022 ) -> ColumnElement[bool]: ...
1023
1024 def regexp_replace(
1025 self, pattern: Any, replacement: Any, flags: Optional[str] = None
1026 ) -> ColumnElement[str]: ...
1027
1028 def desc(self) -> UnaryExpression[_T_co]: ...
1029
1030 def asc(self) -> UnaryExpression[_T_co]: ...
1031
1032 def nulls_first(self) -> UnaryExpression[_T_co]: ...
1033
1034 def nullsfirst(self) -> UnaryExpression[_T_co]: ...
1035
1036 def nulls_last(self) -> UnaryExpression[_T_co]: ...
1037
1038 def nullslast(self) -> UnaryExpression[_T_co]: ...
1039
1040 def collate(self, collation: str) -> CollationClause: ...
1041
1042 def between(
1043 self, cleft: Any, cright: Any, symmetric: bool = False
1044 ) -> BinaryExpression[bool]: ...
1045
1046 def distinct(self: _SQO[_T_co]) -> UnaryExpression[_T_co]: ...
1047
1048 def any_(self) -> CollectionAggregate[Any]: ...
1049
1050 def all_(self) -> CollectionAggregate[Any]: ...
1051
1052 # numeric overloads. These need more tweaking
1053 # in particular they all need to have a variant for Optiona[_T]
1054 # because Optional only applies to the data side, not the expression
1055 # side
1056
1057 @overload
1058 def __add__(
1059 self: _SQO[_NMT],
1060 other: Any,
1061 ) -> ColumnElement[_NMT]: ...
1062
1063 @overload
1064 def __add__(
1065 self: _SQO[str],
1066 other: Any,
1067 ) -> ColumnElement[str]: ...
1068
1069 @overload
1070 def __add__(self, other: Any) -> ColumnElement[Any]: ...
1071
1072 def __add__(self, other: Any) -> ColumnElement[Any]: ...
1073
1074 @overload
1075 def __radd__(self: _SQO[_NMT], other: Any) -> ColumnElement[_NMT]: ...
1076
1077 @overload
1078 def __radd__(self: _SQO[str], other: Any) -> ColumnElement[str]: ...
1079
1080 def __radd__(self, other: Any) -> ColumnElement[Any]: ...
1081
1082 @overload
1083 def __sub__(
1084 self: _SQO[_NMT],
1085 other: Any,
1086 ) -> ColumnElement[_NMT]: ...
1087
1088 @overload
1089 def __sub__(self, other: Any) -> ColumnElement[Any]: ...
1090
1091 def __sub__(self, other: Any) -> ColumnElement[Any]: ...
1092
1093 @overload
1094 def __rsub__(
1095 self: _SQO[_NMT],
1096 other: Any,
1097 ) -> ColumnElement[_NMT]: ...
1098
1099 @overload
1100 def __rsub__(self, other: Any) -> ColumnElement[Any]: ...
1101
1102 def __rsub__(self, other: Any) -> ColumnElement[Any]: ...
1103
1104 @overload
1105 def __mul__(
1106 self: _SQO[_NMT],
1107 other: Any,
1108 ) -> ColumnElement[_NMT]: ...
1109
1110 @overload
1111 def __mul__(self, other: Any) -> ColumnElement[Any]: ...
1112
1113 def __mul__(self, other: Any) -> ColumnElement[Any]: ...
1114
1115 @overload
1116 def __rmul__(
1117 self: _SQO[_NMT],
1118 other: Any,
1119 ) -> ColumnElement[_NMT]: ...
1120
1121 @overload
1122 def __rmul__(self, other: Any) -> ColumnElement[Any]: ...
1123
1124 def __rmul__(self, other: Any) -> ColumnElement[Any]: ...
1125
1126 @overload
1127 def __mod__(self: _SQO[_NMT], other: Any) -> ColumnElement[_NMT]: ...
1128
1129 @overload
1130 def __mod__(self, other: Any) -> ColumnElement[Any]: ...
1131
1132 def __mod__(self, other: Any) -> ColumnElement[Any]: ...
1133
1134 @overload
1135 def __rmod__(self: _SQO[_NMT], other: Any) -> ColumnElement[_NMT]: ...
1136
1137 @overload
1138 def __rmod__(self, other: Any) -> ColumnElement[Any]: ...
1139
1140 def __rmod__(self, other: Any) -> ColumnElement[Any]: ...
1141
1142 @overload
1143 def __truediv__(
1144 self: _SQO[int], other: Any
1145 ) -> ColumnElement[_NUMERIC]: ...
1146
1147 @overload
1148 def __truediv__(self: _SQO[_NT], other: Any) -> ColumnElement[_NT]: ...
1149
1150 @overload
1151 def __truediv__(self, other: Any) -> ColumnElement[Any]: ...
1152
1153 def __truediv__(self, other: Any) -> ColumnElement[Any]: ...
1154
1155 @overload
1156 def __rtruediv__(
1157 self: _SQO[_NMT], other: Any
1158 ) -> ColumnElement[_NUMERIC]: ...
1159
1160 @overload
1161 def __rtruediv__(self, other: Any) -> ColumnElement[Any]: ...
1162
1163 def __rtruediv__(self, other: Any) -> ColumnElement[Any]: ...
1164
1165 @overload
1166 def __floordiv__(
1167 self: _SQO[_NMT], other: Any
1168 ) -> ColumnElement[_NMT]: ...
1169
1170 @overload
1171 def __floordiv__(self, other: Any) -> ColumnElement[Any]: ...
1172
1173 def __floordiv__(self, other: Any) -> ColumnElement[Any]: ...
1174
1175 @overload
1176 def __rfloordiv__(
1177 self: _SQO[_NMT], other: Any
1178 ) -> ColumnElement[_NMT]: ...
1179
1180 @overload
1181 def __rfloordiv__(self, other: Any) -> ColumnElement[Any]: ...
1182
1183 def __rfloordiv__(self, other: Any) -> ColumnElement[Any]: ...
1184
1185
1186class SQLColumnExpression(
1187 SQLCoreOperations[_T_co], roles.ExpressionElementRole[_T_co], TypingOnly
1188):
1189 """A type that may be used to indicate any SQL column element or object
1190 that acts in place of one.
1191
1192 :class:`.SQLColumnExpression` is a base of
1193 :class:`.ColumnElement`, as well as within the bases of ORM elements
1194 such as :class:`.InstrumentedAttribute`, and may be used in :pep:`484`
1195 typing to indicate arguments or return values that should behave
1196 as column expressions.
1197
1198 .. versionadded:: 2.0.0b4
1199
1200
