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