operators.py 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623
  1. # sql/operators.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. # This module is part of SQLAlchemy and is released under
  8. # the MIT License: https://www.opensource.org/licenses/mit-license.php
  9. """Defines operators used in SQL expressions."""
  10. from __future__ import annotations
  11. from enum import IntEnum
  12. from operator import add as _uncast_add
  13. from operator import and_ as _uncast_and_
  14. from operator import contains as _uncast_contains
  15. from operator import eq as _uncast_eq
  16. from operator import floordiv as _uncast_floordiv
  17. from operator import ge as _uncast_ge
  18. from operator import getitem as _uncast_getitem
  19. from operator import gt as _uncast_gt
  20. from operator import inv as _uncast_inv
  21. from operator import le as _uncast_le
  22. from operator import lshift as _uncast_lshift
  23. from operator import lt as _uncast_lt
  24. from operator import mod as _uncast_mod
  25. from operator import mul as _uncast_mul
  26. from operator import ne as _uncast_ne
  27. from operator import neg as _uncast_neg
  28. from operator import or_ as _uncast_or_
  29. from operator import rshift as _uncast_rshift
  30. from operator import sub as _uncast_sub
  31. from operator import truediv as _uncast_truediv
  32. import typing
  33. from typing import Any
  34. from typing import Callable
  35. from typing import cast
  36. from typing import Dict
  37. from typing import Generic
  38. from typing import Optional
  39. from typing import overload
  40. from typing import Set
  41. from typing import Tuple
  42. from typing import Type
  43. from typing import TYPE_CHECKING
  44. from typing import TypeVar
  45. from typing import Union
  46. from .. import exc
  47. from .. import util
  48. from ..util.typing import Literal
  49. from ..util.typing import Protocol
  50. if typing.TYPE_CHECKING:
  51. from ._typing import ColumnExpressionArgument
  52. from .cache_key import CacheConst
  53. from .elements import ColumnElement
  54. from .type_api import TypeEngine
  55. _T = TypeVar("_T", bound=Any)
  56. _FN = TypeVar("_FN", bound=Callable[..., Any])
  57. class OperatorType(Protocol):
  58. """describe an op() function."""
  59. __slots__ = ()
  60. __name__: str
  61. @overload
  62. def __call__(
  63. self,
  64. left: ColumnExpressionArgument[Any],
  65. right: Optional[Any] = None,
  66. *other: Any,
  67. **kwargs: Any,
  68. ) -> ColumnElement[Any]: ...
  69. @overload
  70. def __call__(
  71. self,
  72. left: Operators,
  73. right: Optional[Any] = None,
  74. *other: Any,
  75. **kwargs: Any,
  76. ) -> Operators: ...
  77. def __call__(
  78. self,
  79. left: Any,
  80. right: Optional[Any] = None,
  81. *other: Any,
  82. **kwargs: Any,
  83. ) -> Operators: ...
  84. add = cast(OperatorType, _uncast_add)
  85. and_ = cast(OperatorType, _uncast_and_)
  86. contains = cast(OperatorType, _uncast_contains)
  87. eq = cast(OperatorType, _uncast_eq)
  88. floordiv = cast(OperatorType, _uncast_floordiv)
  89. ge = cast(OperatorType, _uncast_ge)
  90. getitem = cast(OperatorType, _uncast_getitem)
  91. gt = cast(OperatorType, _uncast_gt)
  92. inv = cast(OperatorType, _uncast_inv)
  93. le = cast(OperatorType, _uncast_le)
  94. lshift = cast(OperatorType, _uncast_lshift)
  95. lt = cast(OperatorType, _uncast_lt)
  96. mod = cast(OperatorType, _uncast_mod)
  97. mul = cast(OperatorType, _uncast_mul)
  98. ne = cast(OperatorType, _uncast_ne)
  99. neg = cast(OperatorType, _uncast_neg)
  100. or_ = cast(OperatorType, _uncast_or_)
  101. rshift = cast(OperatorType, _uncast_rshift)
  102. sub = cast(OperatorType, _uncast_sub)
  103. truediv = cast(OperatorType, _uncast_truediv)
  104. class Operators:
  105. """Base of comparison and logical operators.
  106. Implements base methods
  107. :meth:`~sqlalchemy.sql.operators.Operators.operate` and
  108. :meth:`~sqlalchemy.sql.operators.Operators.reverse_operate`, as well as
  109. :meth:`~sqlalchemy.sql.operators.Operators.__and__`,
  110. :meth:`~sqlalchemy.sql.operators.Operators.__or__`,
  111. :meth:`~sqlalchemy.sql.operators.Operators.__invert__`.
  112. Usually is used via its most common subclass
  113. :class:`.ColumnOperators`.
  114. """
  115. __slots__ = ()
  116. def __and__(self, other: Any) -> Operators:
  117. """Implement the ``&`` operator.
  118. When used with SQL expressions, results in an
  119. AND operation, equivalent to
  120. :func:`_expression.and_`, that is::
  121. a & b
  122. is equivalent to::
  123. from sqlalchemy import and_
  124. and_(a, b)
  125. Care should be taken when using ``&`` regarding
  126. operator precedence; the ``&`` operator has the highest precedence.
  127. The operands should be enclosed in parenthesis if they contain
  128. further sub expressions::
  129. (a == 2) & (b == 4)
  130. """
  131. return self.operate(and_, other)
  132. def __or__(self, other: Any) -> Operators:
  133. """Implement the ``|`` operator.
  134. When used with SQL expressions, results in an
  135. OR operation, equivalent to
  136. :func:`_expression.or_`, that is::
  137. a | b
  138. is equivalent to::
  139. from sqlalchemy import or_
  140. or_(a, b)
  141. Care should be taken when using ``|`` regarding
  142. operator precedence; the ``|`` operator has the highest precedence.
  143. The operands should be enclosed in parenthesis if they contain
  144. further sub expressions::
  145. (a == 2) | (b == 4)
  146. """
  147. return self.operate(or_, other)
  148. def __invert__(self) -> Operators:
  149. """Implement the ``~`` operator.
  150. When used with SQL expressions, results in a
  151. NOT operation, equivalent to
  152. :func:`_expression.not_`, that is::
  153. ~a
  154. is equivalent to::
  155. from sqlalchemy import not_
  156. not_(a)
  157. """
  158. return self.operate(inv)
  159. def op(
  160. self,
  161. opstring: str,
  162. precedence: int = 0,
  163. is_comparison: bool = False,
  164. return_type: Optional[
  165. Union[Type[TypeEngine[Any]], TypeEngine[Any]]
  166. ] = None,
  167. python_impl: Optional[Callable[..., Any]] = None,
  168. ) -> Callable[[Any], Operators]:
  169. """Produce a generic operator function.
  170. e.g.::
  171. somecolumn.op("*")(5)
  172. produces::
  173. somecolumn * 5
  174. This function can also be used to make bitwise operators explicit. For
  175. example::
  176. somecolumn.op("&")(0xFF)
  177. is a bitwise AND of the value in ``somecolumn``.
  178. :param opstring: a string which will be output as the infix operator
  179. between this element and the expression passed to the
  180. generated function.
  181. :param precedence: precedence which the database is expected to apply
  182. to the operator in SQL expressions. This integer value acts as a hint
  183. for the SQL compiler to know when explicit parenthesis should be
  184. rendered around a particular operation. A lower number will cause the
  185. expression to be parenthesized when applied against another operator
  186. with higher precedence. The default value of ``0`` is lower than all
  187. operators except for the comma (``,``) and ``AS`` operators. A value
  188. of 100 will be higher or equal to all operators, and -100 will be
  189. lower than or equal to all operators.
  190. .. seealso::
  191. :ref:`faq_sql_expression_op_parenthesis` - detailed description
  192. of how the SQLAlchemy SQL compiler renders parenthesis
  193. :param is_comparison: legacy; if True, the operator will be considered
  194. as a "comparison" operator, that is which evaluates to a boolean
  195. true/false value, like ``==``, ``>``, etc. This flag is provided
  196. so that ORM relationships can establish that the operator is a
  197. comparison operator when used in a custom join condition.
  198. Using the ``is_comparison`` parameter is superseded by using the
  199. :meth:`.Operators.bool_op` method instead; this more succinct
  200. operator sets this parameter automatically, but also provides
  201. correct :pep:`484` typing support as the returned object will
  202. express a "boolean" datatype, i.e. ``BinaryExpression[bool]``.
  203. :param return_type: a :class:`.TypeEngine` class or object that will
  204. force the return type of an expression produced by this operator
  205. to be of that type. By default, operators that specify
  206. :paramref:`.Operators.op.is_comparison` will resolve to
  207. :class:`.Boolean`, and those that do not will be of the same
  208. type as the left-hand operand.
  209. :param python_impl: an optional Python function that can evaluate
  210. two Python values in the same way as this operator works when
  211. run on the database server. Useful for in-Python SQL expression
  212. evaluation functions, such as for ORM hybrid attributes, and the
  213. ORM "evaluator" used to match objects in a session after a multi-row
  214. update or delete.
  215. e.g.::
  216. >>> expr = column("x").op("+", python_impl=lambda a, b: a + b)("y")
  217. The operator for the above expression will also work for non-SQL
  218. left and right objects::
  219. >>> expr.operator(5, 10)
  220. 15
  221. .. versionadded:: 2.0
  222. .. seealso::
  223. :meth:`.Operators.bool_op`
  224. :ref:`types_operators`
  225. :ref:`relationship_custom_operator`
  226. """
  227. operator = custom_op(
  228. opstring,
  229. precedence,
  230. is_comparison,
  231. return_type,
  232. python_impl=python_impl,
  233. )
  234. def against(other: Any) -> Operators:
  235. return operator(self, other)
  236. return against
  237. def bool_op(
  238. self,
  239. opstring: str,
  240. precedence: int = 0,
  241. python_impl: Optional[Callable[..., Any]] = None,
  242. ) -> Callable[[Any], Operators]:
  243. """Return a custom boolean operator.
  244. This method is shorthand for calling
  245. :meth:`.Operators.op` and passing the
  246. :paramref:`.Operators.op.is_comparison`
  247. flag with True. A key advantage to using :meth:`.Operators.bool_op`
  248. is that when using column constructs, the "boolean" nature of the
  249. returned expression will be present for :pep:`484` purposes.
  250. .. seealso::
  251. :meth:`.Operators.op`
  252. """
  253. return self.op(
  254. opstring,
  255. precedence=precedence,
  256. is_comparison=True,
  257. python_impl=python_impl,
  258. )
  259. def operate(
  260. self, op: OperatorType, *other: Any, **kwargs: Any
  261. ) -> Operators:
  262. r"""Operate on an argument.
  263. This is the lowest level of operation, raises
  264. :class:`NotImplementedError` by default.
  265. Overriding this on a subclass can allow common
  266. behavior to be applied to all operations.
  267. For example, overriding :class:`.ColumnOperators`
  268. to apply ``func.lower()`` to the left and right
  269. side::
  270. class MyComparator(ColumnOperators):
  271. def operate(self, op, other, **kwargs):
  272. return op(func.lower(self), func.lower(other), **kwargs)
  273. :param op: Operator callable.
  274. :param \*other: the 'other' side of the operation. Will
  275. be a single scalar for most operations.
  276. :param \**kwargs: modifiers. These may be passed by special
  277. operators such as :meth:`ColumnOperators.contains`.
  278. """
  279. raise NotImplementedError(str(op))
  280. __sa_operate__ = operate
  281. def reverse_operate(
  282. self, op: OperatorType, other: Any, **kwargs: Any
  283. ) -> Operators:
  284. """Reverse operate on an argument.
  285. Usage is the same as :meth:`operate`.
  286. """
  287. raise NotImplementedError(str(op))
  288. class custom_op(OperatorType, Generic[_T]):
  289. """Represent a 'custom' operator.
  290. :class:`.custom_op` is normally instantiated when the
  291. :meth:`.Operators.op` or :meth:`.Operators.bool_op` methods
  292. are used to create a custom operator callable. The class can also be
  293. used directly when programmatically constructing expressions. E.g.
  294. to represent the "factorial" operation::
  295. from sqlalchemy.sql import UnaryExpression
  296. from sqlalchemy.sql import operators
  297. from sqlalchemy import Numeric
  298. unary = UnaryExpression(
  299. table.c.somecolumn, modifier=operators.custom_op("!"), type_=Numeric
  300. )
  301. .. seealso::
  302. :meth:`.Operators.op`
  303. :meth:`.Operators.bool_op`
  304. """ # noqa: E501
  305. __name__ = "custom_op"
  306. __slots__ = (
  307. "opstring",
  308. "precedence",
  309. "is_comparison",
  310. "natural_self_precedent",
  311. "eager_grouping",
  312. "return_type",
  313. "python_impl",
  314. )
  315. def __init__(
  316. self,
  317. opstring: str,
  318. precedence: int = 0,
  319. is_comparison: bool = False,
  320. return_type: Optional[
  321. Union[Type[TypeEngine[_T]], TypeEngine[_T]]
  322. ] = None,
  323. natural_self_precedent: bool = False,
  324. eager_grouping: bool = False,
  325. python_impl: Optional[Callable[..., Any]] = None,
  326. ):
  327. self.opstring = opstring
  328. self.precedence = precedence
  329. self.is_comparison = is_comparison
  330. self.natural_self_precedent = natural_self_precedent
  331. self.eager_grouping = eager_grouping
  332. self.return_type = (
  333. return_type._to_instance(return_type) if return_type else None
  334. )
  335. self.python_impl = python_impl
  336. def __eq__(self, other: Any) -> bool:
  337. return (
  338. isinstance(other, custom_op)
  339. and other._hash_key() == self._hash_key()
  340. )
  341. def __hash__(self) -> int:
  342. return hash(self._hash_key())
  343. def _hash_key(self) -> Union[CacheConst, Tuple[Any, ...]]:
  344. return (
  345. self.__class__,
  346. self.opstring,
  347. self.precedence,
  348. self.is_comparison,
  349. self.natural_self_precedent,
  350. self.eager_grouping,
  351. self.return_type._static_cache_key if self.return_type else None,
  352. )
  353. @overload
  354. def __call__(
  355. self,
  356. left: ColumnExpressionArgument[Any],
  357. right: Optional[Any] = None,
  358. *other: Any,
  359. **kwargs: Any,
  360. ) -> ColumnElement[Any]: ...
  361. @overload
  362. def __call__(
  363. self,
  364. left: Operators,
  365. right: Optional[Any] = None,
  366. *other: Any,
  367. **kwargs: Any,
  368. ) -> Operators: ...
  369. def __call__(
  370. self,
  371. left: Any,
  372. right: Optional[Any] = None,
  373. *other: Any,
  374. **kwargs: Any,
  375. ) -> Operators:
  376. if hasattr(left, "__sa_operate__"):
  377. return left.operate(self, right, *other, **kwargs) # type: ignore
  378. elif self.python_impl:
  379. return self.python_impl(left, right, *other, **kwargs) # type: ignore # noqa: E501
  380. else:
  381. raise exc.InvalidRequestError(
  382. f"Custom operator {self.opstring!r} can't be used with "
  383. "plain Python objects unless it includes the "
  384. "'python_impl' parameter."
  385. )
  386. class ColumnOperators(Operators):
  387. """Defines boolean, comparison, and other operators for
  388. :class:`_expression.ColumnElement` expressions.
  389. By default, all methods call down to
  390. :meth:`.operate` or :meth:`.reverse_operate`,
  391. passing in the appropriate operator function from the
  392. Python builtin ``operator`` module or
  393. a SQLAlchemy-specific operator function from
  394. :mod:`sqlalchemy.expression.operators`. For example
  395. the ``__eq__`` function::
  396. def __eq__(self, other):
  397. return self.operate(operators.eq, other)
  398. Where ``operators.eq`` is essentially::
  399. def eq(a, b):
  400. return a == b
  401. The core column expression unit :class:`_expression.ColumnElement`
  402. overrides :meth:`.Operators.operate` and others
  403. to return further :class:`_expression.ColumnElement` constructs,
  404. so that the ``==`` operation above is replaced by a clause
  405. construct.
  406. .. seealso::
  407. :ref:`types_operators`
  408. :attr:`.TypeEngine.comparator_factory`
  409. :class:`.ColumnOperators`
  410. :class:`.PropComparator`
  411. """
  412. __slots__ = ()
  413. timetuple: Literal[None] = None
  414. """Hack, allows datetime objects to be compared on the LHS."""
  415. if typing.TYPE_CHECKING:
  416. def operate(
  417. self, op: OperatorType, *other: Any, **kwargs: Any
  418. ) -> ColumnOperators: ...
  419. def reverse_operate(
  420. self, op: OperatorType, other: Any, **kwargs: Any
  421. ) -> ColumnOperators: ...
  422. def __lt__(self, other: Any) -> ColumnOperators:
  423. """Implement the ``<`` operator.
  424. In a column context, produces the clause ``a < b``.
  425. """
  426. return self.operate(lt, other)
  427. def __le__(self, other: Any) -> ColumnOperators:
  428. """Implement the ``<=`` operator.
  429. In a column context, produces the clause ``a <= b``.
  430. """
  431. return self.operate(le, other)
  432. # ColumnOperators defines an __eq__ so it must explicitly declare also
  433. # an hash or it's set to None by python:
  434. # https://docs.python.org/3/reference/datamodel.html#object.__hash__
  435. if TYPE_CHECKING:
  436. def __hash__(self) -> int: ...
  437. else:
  438. __hash__ = Operators.__hash__
  439. def __eq__(self, other: Any) -> ColumnOperators: # type: ignore[override]
  440. """Implement the ``==`` operator.
  441. In a column context, produces the clause ``a = b``.
  442. If the target is ``None``, produces ``a IS NULL``.
  443. """
  444. return self.operate(eq, other)
  445. def __ne__(self, other: Any) -> ColumnOperators: # type: ignore[override]
  446. """Implement the ``!=`` operator.
  447. In a column context, produces the clause ``a != b``.
  448. If the target is ``None``, produces ``a IS NOT NULL``.
  449. """
  450. return self.operate(ne, other)
  451. def is_distinct_from(self, other: Any) -> ColumnOperators:
  452. """Implement the ``IS DISTINCT FROM`` operator.
  453. Renders "a IS DISTINCT FROM b" on most platforms;
  454. on some such as SQLite may render "a IS NOT b".
  455. """
  456. return self.operate(is_distinct_from, other)
  457. def is_not_distinct_from(self, other: Any) -> ColumnOperators:
  458. """Implement the ``IS NOT DISTINCT FROM`` operator.
  459. Renders "a IS NOT DISTINCT FROM b" on most platforms;
  460. on some such as SQLite may render "a IS b".
  461. .. versionchanged:: 1.4 The ``is_not_distinct_from()`` operator is
  462. renamed from ``isnot_distinct_from()`` in previous releases.
  463. The previous name remains available for backwards compatibility.
  464. """
  465. return self.operate(is_not_distinct_from, other)
  466. # deprecated 1.4; see #5435
  467. if TYPE_CHECKING:
  468. def isnot_distinct_from(self, other: Any) -> ColumnOperators: ...
  469. else:
  470. isnot_distinct_from = is_not_distinct_from
  471. def __gt__(self, other: Any) -> ColumnOperators:
  472. """Implement the ``>`` operator.
  473. In a column context, produces the clause ``a > b``.
  474. """
  475. return self.operate(gt, other)
  476. def __ge__(self, other: Any) -> ColumnOperators:
  477. """Implement the ``>=`` operator.
  478. In a column context, produces the clause ``a >= b``.
  479. """
  480. return self.operate(ge, other)
  481. def __neg__(self) -> ColumnOperators:
  482. """Implement the ``-`` operator.
  483. In a column context, produces the clause ``-a``.
  484. """
  485. return self.operate(neg)
  486. def __contains__(self, other: Any) -> ColumnOperators:
  487. return self.operate(contains, other)
  488. def __getitem__(self, index: Any) -> ColumnOperators:
  489. """Implement the [] operator.
  490. This can be used by some database-specific types
  491. such as PostgreSQL ARRAY and HSTORE.
  492. """
  493. return self.operate(getitem, index)
  494. def __lshift__(self, other: Any) -> ColumnOperators:
  495. """implement the << operator.
  496. Not used by SQLAlchemy core, this is provided
  497. for custom operator systems which want to use
  498. << as an extension point.
  499. """
  500. return self.operate(lshift, other)
  501. def __rshift__(self, other: Any) -> ColumnOperators:
  502. """implement the >> operator.
  503. Not used by SQLAlchemy core, this is provided
  504. for custom operator systems which want to use
  505. >> as an extension point.
  506. """
  507. return self.operate(rshift, other)
  508. def concat(self, other: Any) -> ColumnOperators:
  509. """Implement the 'concat' operator.
  510. In a column context, produces the clause ``a || b``,
  511. or uses the ``concat()`` operator on MySQL.
  512. """
  513. return self.operate(concat_op, other)
  514. def _rconcat(self, other: Any) -> ColumnOperators:
  515. """Implement an 'rconcat' operator.
  516. this is for internal use at the moment
  517. .. versionadded:: 1.4.40
  518. """
  519. return self.reverse_operate(concat_op, other)
  520. def like(
  521. self, other: Any, escape: Optional[str] = None
  522. ) -> ColumnOperators:
  523. r"""Implement the ``like`` operator.
  524. In a column context, produces the expression:
  525. .. sourcecode:: sql
  526. a LIKE other
  527. E.g.::
  528. stmt = select(sometable).where(sometable.c.column.like("%foobar%"))
  529. :param other: expression to be compared
  530. :param escape: optional escape character, renders the ``ESCAPE``
  531. keyword, e.g.::
  532. somecolumn.like("foo/%bar", escape="/")
  533. .. seealso::
  534. :meth:`.ColumnOperators.ilike`
  535. """
  536. return self.operate(like_op, other, escape=escape)
  537. def ilike(
  538. self, other: Any, escape: Optional[str] = None
  539. ) -> ColumnOperators:
  540. r"""Implement the ``ilike`` operator, e.g. case insensitive LIKE.
  541. In a column context, produces an expression either of the form:
  542. .. sourcecode:: sql
  543. lower(a) LIKE lower(other)
  544. Or on backends that support the ILIKE operator:
  545. .. sourcecode:: sql
  546. a ILIKE other
  547. E.g.::
  548. stmt = select(sometable).where(sometable.c.column.ilike("%foobar%"))
  549. :param other: expression to be compared
  550. :param escape: optional escape character, renders the ``ESCAPE``
  551. keyword, e.g.::
  552. somecolumn.ilike("foo/%bar", escape="/")
  553. .. seealso::
  554. :meth:`.ColumnOperators.like`
  555. """ # noqa: E501
  556. return self.operate(ilike_op, other, escape=escape)
  557. def bitwise_xor(self, other: Any) -> ColumnOperators:
  558. """Produce a bitwise XOR operation, typically via the ``^``
  559. operator, or ``#`` for PostgreSQL.
  560. .. versionadded:: 2.0.2
  561. .. seealso::
  562. :ref:`operators_bitwise`
  563. """
  564. return self.operate(bitwise_xor_op, other)
  565. def bitwise_or(self, other: Any) -> ColumnOperators:
  566. """Produce a bitwise OR operation, typically via the ``|``
  567. operator.
  568. .. versionadded:: 2.0.2
  569. .. seealso::
  570. :ref:`operators_bitwise`
  571. """
  572. return self.operate(bitwise_or_op, other)
  573. def bitwise_and(self, other: Any) -> ColumnOperators:
  574. """Produce a bitwise AND operation, typically via the ``&``
  575. operator.
  576. .. versionadded:: 2.0.2
  577. .. seealso::
  578. :ref:`operators_bitwise`
  579. """
  580. return self.operate(bitwise_and_op, other)
  581. def bitwise_not(self) -> ColumnOperators:
  582. """Produce a bitwise NOT operation, typically via the ``~``
  583. operator.
  584. .. versionadded:: 2.0.2
  585. .. seealso::
  586. :ref:`operators_bitwise`
  587. """
  588. return self.operate(bitwise_not_op)
  589. def bitwise_lshift(self, other: Any) -> ColumnOperators:
  590. """Produce a bitwise LSHIFT operation, typically via the ``<<``
  591. operator.
  592. .. versionadded:: 2.0.2
  593. .. seealso::
  594. :ref:`operators_bitwise`
  595. """
  596. return self.operate(bitwise_lshift_op, other)
  597. def bitwise_rshift(self, other: Any) -> ColumnOperators:
  598. """Produce a bitwise RSHIFT operation, typically via the ``>>``
  599. operator.
  600. .. versionadded:: 2.0.2
  601. .. seealso::
  602. :ref:`operators_bitwise`
  603. """
  604. return self.operate(bitwise_rshift_op, other)
  605. def in_(self, other: Any) -> ColumnOperators:
  606. """Implement the ``in`` operator.
  607. In a column context, produces the clause ``column IN <other>``.
  608. The given parameter ``other`` may be:
  609. * A list of literal values,
  610. e.g.::
  611. stmt.where(column.in_([1, 2, 3]))
  612. In this calling form, the list of items is converted to a set of
  613. bound parameters the same length as the list given:
  614. .. sourcecode:: sql
  615. WHERE COL IN (?, ?, ?)
  616. * A list of tuples may be provided if the comparison is against a
  617. :func:`.tuple_` containing multiple expressions::
  618. from sqlalchemy import tuple_
  619. stmt.where(tuple_(col1, col2).in_([(1, 10), (2, 20), (3, 30)]))
  620. * An empty list,
  621. e.g.::
  622. stmt.where(column.in_([]))
  623. In this calling form, the expression renders an "empty set"
  624. expression. These expressions are tailored to individual backends
  625. and are generally trying to get an empty SELECT statement as a
  626. subquery. Such as on SQLite, the expression is:
  627. .. sourcecode:: sql
  628. WHERE col IN (SELECT 1 FROM (SELECT 1) WHERE 1!=1)
  629. .. versionchanged:: 1.4 empty IN expressions now use an
  630. execution-time generated SELECT subquery in all cases.
  631. * A bound parameter, e.g. :func:`.bindparam`, may be used if it
  632. includes the :paramref:`.bindparam.expanding` flag::
  633. stmt.where(column.in_(bindparam("value", expanding=True)))
  634. In this calling form, the expression renders a special non-SQL
  635. placeholder expression that looks like:
  636. .. sourcecode:: sql
  637. WHERE COL IN ([EXPANDING_value])
  638. This placeholder expression is intercepted at statement execution
  639. time to be converted into the variable number of bound parameter
  640. form illustrated earlier. If the statement were executed as::
  641. connection.execute(stmt, {"value": [1, 2, 3]})
  642. The database would be passed a bound parameter for each value:
  643. .. sourcecode:: sql
  644. WHERE COL IN (?, ?, ?)
  645. .. versionadded:: 1.2 added "expanding" bound parameters
  646. If an empty list is passed, a special "empty list" expression,
  647. which is specific to the database in use, is rendered. On
  648. SQLite this would be:
  649. .. sourcecode:: sql
  650. WHERE COL IN (SELECT 1 FROM (SELECT 1) WHERE 1!=1)
  651. .. versionadded:: 1.3 "expanding" bound parameters now support
  652. empty lists
  653. * a :func:`_expression.select` construct, which is usually a
  654. correlated scalar select::
  655. stmt.where(
  656. column.in_(select(othertable.c.y).where(table.c.x == othertable.c.x))
  657. )
  658. In this calling form, :meth:`.ColumnOperators.in_` renders as given:
  659. .. sourcecode:: sql
  660. WHERE COL IN (SELECT othertable.y
  661. FROM othertable WHERE othertable.x = table.x)
  662. :param other: a list of literals, a :func:`_expression.select`
  663. construct, or a :func:`.bindparam` construct that includes the
  664. :paramref:`.bindparam.expanding` flag set to True.
  665. """ # noqa: E501
  666. return self.operate(in_op, other)
  667. def not_in(self, other: Any) -> ColumnOperators:
  668. """implement the ``NOT IN`` operator.
  669. This is equivalent to using negation with
  670. :meth:`.ColumnOperators.in_`, i.e. ``~x.in_(y)``.
  671. In the case that ``other`` is an empty sequence, the compiler
  672. produces an "empty not in" expression. This defaults to the
  673. expression "1 = 1" to produce true in all cases. The
  674. :paramref:`_sa.create_engine.empty_in_strategy` may be used to
  675. alter this behavior.
  676. .. versionchanged:: 1.4 The ``not_in()`` operator is renamed from
  677. ``notin_()`` in previous releases. The previous name remains
  678. available for backwards compatibility.
  679. .. versionchanged:: 1.2 The :meth:`.ColumnOperators.in_` and
  680. :meth:`.ColumnOperators.not_in` operators
  681. now produce a "static" expression for an empty IN sequence
  682. by default.
  683. .. seealso::
  684. :meth:`.ColumnOperators.in_`
  685. """
  686. return self.operate(not_in_op, other)
  687. # deprecated 1.4; see #5429
  688. if TYPE_CHECKING:
  689. def notin_(self, other: Any) -> ColumnOperators: ...
  690. else:
  691. notin_ = not_in
  692. def not_like(
  693. self, other: Any, escape: Optional[str] = None
  694. ) -> ColumnOperators:
  695. """implement the ``NOT LIKE`` operator.
  696. This is equivalent to using negation with
  697. :meth:`.ColumnOperators.like`, i.e. ``~x.like(y)``.
  698. .. versionchanged:: 1.4 The ``not_like()`` operator is renamed from
  699. ``notlike()`` in previous releases. The previous name remains
  700. available for backwards compatibility.
  701. .. seealso::
  702. :meth:`.ColumnOperators.like`
  703. """
  704. return self.operate(not_like_op, other, escape=escape)
  705. # deprecated 1.4; see #5435
  706. if TYPE_CHECKING:
  707. def notlike(
  708. self, other: Any, escape: Optional[str] = None
  709. ) -> ColumnOperators: ...
  710. else:
  711. notlike = not_like
  712. def not_ilike(
  713. self, other: Any, escape: Optional[str] = None
  714. ) -> ColumnOperators:
  715. """implement the ``NOT ILIKE`` operator.
  716. This is equivalent to using negation with
  717. :meth:`.ColumnOperators.ilike`, i.e. ``~x.ilike(y)``.
  718. .. versionchanged:: 1.4 The ``not_ilike()`` operator is renamed from
  719. ``notilike()`` in previous releases. The previous name remains
  720. available for backwards compatibility.
  721. .. seealso::
  722. :meth:`.ColumnOperators.ilike`
  723. """
  724. return self.operate(not_ilike_op, other, escape=escape)
  725. # deprecated 1.4; see #5435
  726. if TYPE_CHECKING:
  727. def notilike(
  728. self, other: Any, escape: Optional[str] = None
  729. ) -> ColumnOperators: ...
  730. else:
  731. notilike = not_ilike
  732. def is_(self, other: Any) -> ColumnOperators:
  733. """Implement the ``IS`` operator.
  734. Normally, ``IS`` is generated automatically when comparing to a
  735. value of ``None``, which resolves to ``NULL``. However, explicit
  736. usage of ``IS`` may be desirable if comparing to boolean values
  737. on certain platforms.
  738. .. seealso:: :meth:`.ColumnOperators.is_not`
  739. """
  740. return self.operate(is_, other)
  741. def is_not(self, other: Any) -> ColumnOperators:
  742. """Implement the ``IS NOT`` operator.
  743. Normally, ``IS NOT`` is generated automatically when comparing to a
  744. value of ``None``, which resolves to ``NULL``. However, explicit
  745. usage of ``IS NOT`` may be desirable if comparing to boolean values
  746. on certain platforms.
  747. .. versionchanged:: 1.4 The ``is_not()`` operator is renamed from
  748. ``isnot()`` in previous releases. The previous name remains
  749. available for backwards compatibility.
  750. .. seealso:: :meth:`.ColumnOperators.is_`
  751. """
  752. return self.operate(is_not, other)
  753. # deprecated 1.4; see #5429
  754. if TYPE_CHECKING:
  755. def isnot(self, other: Any) -> ColumnOperators: ...
  756. else:
  757. isnot = is_not
  758. def startswith(
  759. self,
  760. other: Any,
  761. escape: Optional[str] = None,
  762. autoescape: bool = False,
  763. ) -> ColumnOperators:
  764. r"""Implement the ``startswith`` operator.
  765. Produces a LIKE expression that tests against a match for the start
  766. of a string value:
  767. .. sourcecode:: sql
  768. column LIKE <other> || '%'
  769. E.g.::
  770. stmt = select(sometable).where(sometable.c.column.startswith("foobar"))
  771. Since the operator uses ``LIKE``, wildcard characters
  772. ``"%"`` and ``"_"`` that are present inside the <other> expression
  773. will behave like wildcards as well. For literal string
  774. values, the :paramref:`.ColumnOperators.startswith.autoescape` flag
  775. may be set to ``True`` to apply escaping to occurrences of these
  776. characters within the string value so that they match as themselves
  777. and not as wildcard characters. Alternatively, the
  778. :paramref:`.ColumnOperators.startswith.escape` parameter will establish
  779. a given character as an escape character which can be of use when
  780. the target expression is not a literal string.
  781. :param other: expression to be compared. This is usually a plain
  782. string value, but can also be an arbitrary SQL expression. LIKE
  783. wildcard characters ``%`` and ``_`` are not escaped by default unless
  784. the :paramref:`.ColumnOperators.startswith.autoescape` flag is
  785. set to True.
  786. :param autoescape: boolean; when True, establishes an escape character
  787. within the LIKE expression, then applies it to all occurrences of
  788. ``"%"``, ``"_"`` and the escape character itself within the
  789. comparison value, which is assumed to be a literal string and not a
  790. SQL expression.
  791. An expression such as::
  792. somecolumn.startswith("foo%bar", autoescape=True)
  793. Will render as:
  794. .. sourcecode:: sql
  795. somecolumn LIKE :param || '%' ESCAPE '/'
  796. With the value of ``:param`` as ``"foo/%bar"``.
  797. :param escape: a character which when given will render with the
  798. ``ESCAPE`` keyword to establish that character as the escape
  799. character. This character can then be placed preceding occurrences
  800. of ``%`` and ``_`` to allow them to act as themselves and not
  801. wildcard characters.
  802. An expression such as::
  803. somecolumn.startswith("foo/%bar", escape="^")
  804. Will render as:
  805. .. sourcecode:: sql
  806. somecolumn LIKE :param || '%' ESCAPE '^'
  807. The parameter may also be combined with
  808. :paramref:`.ColumnOperators.startswith.autoescape`::
  809. somecolumn.startswith("foo%bar^bat", escape="^", autoescape=True)
  810. Where above, the given literal parameter will be converted to
  811. ``"foo^%bar^^bat"`` before being passed to the database.
  812. .. seealso::
  813. :meth:`.ColumnOperators.endswith`
  814. :meth:`.ColumnOperators.contains`
  815. :meth:`.ColumnOperators.like`
  816. """ # noqa: E501
  817. return self.operate(
  818. startswith_op, other, escape=escape, autoescape=autoescape
  819. )
  820. def istartswith(
  821. self,
  822. other: Any,
  823. escape: Optional[str] = None,
  824. autoescape: bool = False,
  825. ) -> ColumnOperators:
  826. r"""Implement the ``istartswith`` operator, e.g. case insensitive
  827. version of :meth:`.ColumnOperators.startswith`.
  828. Produces a LIKE expression that tests against an insensitive
  829. match for the start of a string value:
  830. .. sourcecode:: sql
  831. lower(column) LIKE lower(<other>) || '%'
  832. E.g.::
  833. stmt = select(sometable).where(sometable.c.column.istartswith("foobar"))
  834. Since the operator uses ``LIKE``, wildcard characters
  835. ``"%"`` and ``"_"`` that are present inside the <other> expression
  836. will behave like wildcards as well. For literal string
  837. values, the :paramref:`.ColumnOperators.istartswith.autoescape` flag
  838. may be set to ``True`` to apply escaping to occurrences of these
  839. characters within the string value so that they match as themselves
  840. and not as wildcard characters. Alternatively, the
  841. :paramref:`.ColumnOperators.istartswith.escape` parameter will
  842. establish a given character as an escape character which can be of
  843. use when the target expression is not a literal string.
  844. :param other: expression to be compared. This is usually a plain
  845. string value, but can also be an arbitrary SQL expression. LIKE
  846. wildcard characters ``%`` and ``_`` are not escaped by default unless
  847. the :paramref:`.ColumnOperators.istartswith.autoescape` flag is
  848. set to True.
  849. :param autoescape: boolean; when True, establishes an escape character
  850. within the LIKE expression, then applies it to all occurrences of
  851. ``"%"``, ``"_"`` and the escape character itself within the
  852. comparison value, which is assumed to be a literal string and not a
  853. SQL expression.
  854. An expression such as::
  855. somecolumn.istartswith("foo%bar", autoescape=True)
  856. Will render as:
  857. .. sourcecode:: sql
  858. lower(somecolumn) LIKE lower(:param) || '%' ESCAPE '/'
  859. With the value of ``:param`` as ``"foo/%bar"``.
  860. :param escape: a character which when given will render with the
  861. ``ESCAPE`` keyword to establish that character as the escape
  862. character. This character can then be placed preceding occurrences
  863. of ``%`` and ``_`` to allow them to act as themselves and not
  864. wildcard characters.
  865. An expression such as::
  866. somecolumn.istartswith("foo/%bar", escape="^")
  867. Will render as:
  868. .. sourcecode:: sql
  869. lower(somecolumn) LIKE lower(:param) || '%' ESCAPE '^'
  870. The parameter may also be combined with
  871. :paramref:`.ColumnOperators.istartswith.autoescape`::
  872. somecolumn.istartswith("foo%bar^bat", escape="^", autoescape=True)
  873. Where above, the given literal parameter will be converted to
  874. ``"foo^%bar^^bat"`` before being passed to the database.
  875. .. seealso::
  876. :meth:`.ColumnOperators.startswith`
  877. """ # noqa: E501
  878. return self.operate(
  879. istartswith_op, other, escape=escape, autoescape=autoescape
  880. )
  881. def endswith(
  882. self,
  883. other: Any,
  884. escape: Optional[str] = None,
  885. autoescape: bool = False,
  886. ) -> ColumnOperators:
  887. r"""Implement the 'endswith' operator.
  888. Produces a LIKE expression that tests against a match for the end
  889. of a string value:
  890. .. sourcecode:: sql
  891. column LIKE '%' || <other>
  892. E.g.::
  893. stmt = select(sometable).where(sometable.c.column.endswith("foobar"))
  894. Since the operator uses ``LIKE``, wildcard characters
  895. ``"%"`` and ``"_"`` that are present inside the <other> expression
  896. will behave like wildcards as well. For literal string
  897. values, the :paramref:`.ColumnOperators.endswith.autoescape` flag
  898. may be set to ``True`` to apply escaping to occurrences of these
  899. characters within the string value so that they match as themselves
  900. and not as wildcard characters. Alternatively, the
  901. :paramref:`.ColumnOperators.endswith.escape` parameter will establish
  902. a given character as an escape character which can be of use when
  903. the target expression is not a literal string.
  904. :param other: expression to be compared. This is usually a plain
  905. string value, but can also be an arbitrary SQL expression. LIKE
  906. wildcard characters ``%`` and ``_`` are not escaped by default unless
  907. the :paramref:`.ColumnOperators.endswith.autoescape` flag is
  908. set to True.
  909. :param autoescape: boolean; when True, establishes an escape character
  910. within the LIKE expression, then applies it to all occurrences of
  911. ``"%"``, ``"_"`` and the escape character itself within the
  912. comparison value, which is assumed to be a literal string and not a
  913. SQL expression.
  914. An expression such as::
  915. somecolumn.endswith("foo%bar", autoescape=True)
  916. Will render as:
  917. .. sourcecode:: sql
  918. somecolumn LIKE '%' || :param ESCAPE '/'
  919. With the value of ``:param`` as ``"foo/%bar"``.
  920. :param escape: a character which when given will render with the
  921. ``ESCAPE`` keyword to establish that character as the escape
  922. character. This character can then be placed preceding occurrences
  923. of ``%`` and ``_`` to allow them to act as themselves and not
  924. wildcard characters.
  925. An expression such as::
  926. somecolumn.endswith("foo/%bar", escape="^")
  927. Will render as:
  928. .. sourcecode:: sql
  929. somecolumn LIKE '%' || :param ESCAPE '^'
  930. The parameter may also be combined with
  931. :paramref:`.ColumnOperators.endswith.autoescape`::
  932. somecolumn.endswith("foo%bar^bat", escape="^", autoescape=True)
  933. Where above, the given literal parameter will be converted to
  934. ``"foo^%bar^^bat"`` before being passed to the database.
  935. .. seealso::
  936. :meth:`.ColumnOperators.startswith`
  937. :meth:`.ColumnOperators.contains`
  938. :meth:`.ColumnOperators.like`
  939. """ # noqa: E501
  940. return self.operate(
  941. endswith_op, other, escape=escape, autoescape=autoescape
  942. )
  943. def iendswith(
  944. self,
  945. other: Any,
  946. escape: Optional[str] = None,
  947. autoescape: bool = False,
  948. ) -> ColumnOperators:
  949. r"""Implement the ``iendswith`` operator, e.g. case insensitive
  950. version of :meth:`.ColumnOperators.endswith`.
  951. Produces a LIKE expression that tests against an insensitive match
  952. for the end of a string value:
  953. .. sourcecode:: sql
  954. lower(column) LIKE '%' || lower(<other>)
  955. E.g.::
  956. stmt = select(sometable).where(sometable.c.column.iendswith("foobar"))
  957. Since the operator uses ``LIKE``, wildcard characters
  958. ``"%"`` and ``"_"`` that are present inside the <other> expression
  959. will behave like wildcards as well. For literal string
  960. values, the :paramref:`.ColumnOperators.iendswith.autoescape` flag
  961. may be set to ``True`` to apply escaping to occurrences of these
  962. characters within the string value so that they match as themselves
  963. and not as wildcard characters. Alternatively, the
  964. :paramref:`.ColumnOperators.iendswith.escape` parameter will establish
  965. a given character as an escape character which can be of use when
  966. the target expression is not a literal string.
  967. :param other: expression to be compared. This is usually a plain
  968. string value, but can also be an arbitrary SQL expression. LIKE
  969. wildcard characters ``%`` and ``_`` are not escaped by default unless
  970. the :paramref:`.ColumnOperators.iendswith.autoescape` flag is
  971. set to True.
  972. :param autoescape: boolean; when True, establishes an escape character
  973. within the LIKE expression, then applies it to all occurrences of
  974. ``"%"``, ``"_"`` and the escape character itself within the
  975. comparison value, which is assumed to be a literal string and not a
  976. SQL expression.
  977. An expression such as::
  978. somecolumn.iendswith("foo%bar", autoescape=True)
  979. Will render as:
  980. .. sourcecode:: sql
  981. lower(somecolumn) LIKE '%' || lower(:param) ESCAPE '/'
  982. With the value of ``:param`` as ``"foo/%bar"``.
  983. :param escape: a character which when given will render with the
  984. ``ESCAPE`` keyword to establish that character as the escape
  985. character. This character can then be placed preceding occurrences
  986. of ``%`` and ``_`` to allow them to act as themselves and not
  987. wildcard characters.
  988. An expression such as::
  989. somecolumn.iendswith("foo/%bar", escape="^")
  990. Will render as:
  991. .. sourcecode:: sql
  992. lower(somecolumn) LIKE '%' || lower(:param) ESCAPE '^'
  993. The parameter may also be combined with
  994. :paramref:`.ColumnOperators.iendswith.autoescape`::
  995. somecolumn.endswith("foo%bar^bat", escape="^", autoescape=True)
  996. Where above, the given literal parameter will be converted to
  997. ``"foo^%bar^^bat"`` before being passed to the database.
  998. .. seealso::
  999. :meth:`.ColumnOperators.endswith`
  1000. """ # noqa: E501
  1001. return self.operate(
  1002. iendswith_op, other, escape=escape, autoescape=autoescape
  1003. )
  1004. def contains(self, other: Any, **kw: Any) -> ColumnOperators:
  1005. r"""Implement the 'contains' operator.
  1006. Produces a LIKE expression that tests against a match for the middle
  1007. of a string value:
  1008. .. sourcecode:: sql
  1009. column LIKE '%' || <other> || '%'
  1010. E.g.::
  1011. stmt = select(sometable).where(sometable.c.column.contains("foobar"))
  1012. Since the operator uses ``LIKE``, wildcard characters
  1013. ``"%"`` and ``"_"`` that are present inside the <other> expression
  1014. will behave like wildcards as well. For literal string
  1015. values, the :paramref:`.ColumnOperators.contains.autoescape` flag
  1016. may be set to ``True`` to apply escaping to occurrences of these
  1017. characters within the string value so that they match as themselves
  1018. and not as wildcard characters. Alternatively, the
  1019. :paramref:`.ColumnOperators.contains.escape` parameter will establish
  1020. a given character as an escape character which can be of use when
  1021. the target expression is not a literal string.
  1022. :param other: expression to be compared. This is usually a plain
  1023. string value, but can also be an arbitrary SQL expression. LIKE
  1024. wildcard characters ``%`` and ``_`` are not escaped by default unless
  1025. the :paramref:`.ColumnOperators.contains.autoescape` flag is
  1026. set to True.
  1027. :param autoescape: boolean; when True, establishes an escape character
  1028. within the LIKE expression, then applies it to all occurrences of
  1029. ``"%"``, ``"_"`` and the escape character itself within the
  1030. comparison value, which is assumed to be a literal string and not a
  1031. SQL expression.
  1032. An expression such as::
  1033. somecolumn.contains("foo%bar", autoescape=True)
  1034. Will render as:
  1035. .. sourcecode:: sql
  1036. somecolumn LIKE '%' || :param || '%' ESCAPE '/'
  1037. With the value of ``:param`` as ``"foo/%bar"``.
  1038. :param escape: a character which when given will render with the
  1039. ``ESCAPE`` keyword to establish that character as the escape
  1040. character. This character can then be placed preceding occurrences
  1041. of ``%`` and ``_`` to allow them to act as themselves and not
  1042. wildcard characters.
  1043. An expression such as::
  1044. somecolumn.contains("foo/%bar", escape="^")
  1045. Will render as:
  1046. .. sourcecode:: sql
  1047. somecolumn LIKE '%' || :param || '%' ESCAPE '^'
  1048. The parameter may also be combined with
  1049. :paramref:`.ColumnOperators.contains.autoescape`::
  1050. somecolumn.contains("foo%bar^bat", escape="^", autoescape=True)
  1051. Where above, the given literal parameter will be converted to
  1052. ``"foo^%bar^^bat"`` before being passed to the database.
  1053. .. seealso::
  1054. :meth:`.ColumnOperators.startswith`
  1055. :meth:`.ColumnOperators.endswith`
  1056. :meth:`.ColumnOperators.like`
  1057. """ # noqa: E501
  1058. return self.operate(contains_op, other, **kw)
  1059. def icontains(self, other: Any, **kw: Any) -> ColumnOperators:
  1060. r"""Implement the ``icontains`` operator, e.g. case insensitive
  1061. version of :meth:`.ColumnOperators.contains`.
  1062. Produces a LIKE expression that tests against an insensitive match
  1063. for the middle of a string value:
  1064. .. sourcecode:: sql
  1065. lower(column) LIKE '%' || lower(<other>) || '%'
  1066. E.g.::
  1067. stmt = select(sometable).where(sometable.c.column.icontains("foobar"))
  1068. Since the operator uses ``LIKE``, wildcard characters
  1069. ``"%"`` and ``"_"`` that are present inside the <other> expression
  1070. will behave like wildcards as well. For literal string
  1071. values, the :paramref:`.ColumnOperators.icontains.autoescape` flag
  1072. may be set to ``True`` to apply escaping to occurrences of these
  1073. characters within the string value so that they match as themselves
  1074. and not as wildcard characters. Alternatively, the
  1075. :paramref:`.ColumnOperators.icontains.escape` parameter will establish
  1076. a given character as an escape character which can be of use when
  1077. the target expression is not a literal string.
  1078. :param other: expression to be compared. This is usually a plain
  1079. string value, but can also be an arbitrary SQL expression. LIKE
  1080. wildcard characters ``%`` and ``_`` are not escaped by default unless
  1081. the :paramref:`.ColumnOperators.icontains.autoescape` flag is
  1082. set to True.
  1083. :param autoescape: boolean; when True, establishes an escape character
  1084. within the LIKE expression, then applies it to all occurrences of
  1085. ``"%"``, ``"_"`` and the escape character itself within the
  1086. comparison value, which is assumed to be a literal string and not a
  1087. SQL expression.
  1088. An expression such as::
  1089. somecolumn.icontains("foo%bar", autoescape=True)
  1090. Will render as:
  1091. .. sourcecode:: sql
  1092. lower(somecolumn) LIKE '%' || lower(:param) || '%' ESCAPE '/'
  1093. With the value of ``:param`` as ``"foo/%bar"``.
  1094. :param escape: a character which when given will render with the
  1095. ``ESCAPE`` keyword to establish that character as the escape
  1096. character. This character can then be placed preceding occurrences
  1097. of ``%`` and ``_`` to allow them to act as themselves and not
  1098. wildcard characters.
  1099. An expression such as::
  1100. somecolumn.icontains("foo/%bar", escape="^")
  1101. Will render as:
  1102. .. sourcecode:: sql
  1103. lower(somecolumn) LIKE '%' || lower(:param) || '%' ESCAPE '^'
  1104. The parameter may also be combined with
  1105. :paramref:`.ColumnOperators.contains.autoescape`::
  1106. somecolumn.icontains("foo%bar^bat", escape="^", autoescape=True)
  1107. Where above, the given literal parameter will be converted to
  1108. ``"foo^%bar^^bat"`` before being passed to the database.
  1109. .. seealso::
  1110. :meth:`.ColumnOperators.contains`
  1111. """ # noqa: E501
  1112. return self.operate(icontains_op, other, **kw)
  1113. def match(self, other: Any, **kwargs: Any) -> ColumnOperators:
  1114. """Implements a database-specific 'match' operator.
  1115. :meth:`_sql.ColumnOperators.match` attempts to resolve to
  1116. a MATCH-like function or operator provided by the backend.
  1117. Examples include:
  1118. * PostgreSQL - renders ``x @@ plainto_tsquery(y)``
  1119. .. versionchanged:: 2.0 ``plainto_tsquery()`` is used instead
  1120. of ``to_tsquery()`` for PostgreSQL now; for compatibility with
  1121. other forms, see :ref:`postgresql_match`.
  1122. * MySQL - renders ``MATCH (x) AGAINST (y IN BOOLEAN MODE)``
  1123. .. seealso::
  1124. :class:`_mysql.match` - MySQL specific construct with
  1125. additional features.
  1126. * Oracle Database - renders ``CONTAINS(x, y)``
  1127. * other backends may provide special implementations.
  1128. * Backends without any special implementation will emit
  1129. the operator as "MATCH". This is compatible with SQLite, for
  1130. example.
  1131. """
  1132. return self.operate(match_op, other, **kwargs)
  1133. def regexp_match(
  1134. self, pattern: Any, flags: Optional[str] = None
  1135. ) -> ColumnOperators:
  1136. """Implements a database-specific 'regexp match' operator.
  1137. E.g.::
  1138. stmt = select(table.c.some_column).where(
  1139. table.c.some_column.regexp_match("^(b|c)")
  1140. )
  1141. :meth:`_sql.ColumnOperators.regexp_match` attempts to resolve to
  1142. a REGEXP-like function or operator provided by the backend, however
  1143. the specific regular expression syntax and flags available are
  1144. **not backend agnostic**.
  1145. Examples include:
  1146. * PostgreSQL - renders ``x ~ y`` or ``x !~ y`` when negated.
  1147. * Oracle Database - renders ``REGEXP_LIKE(x, y)``
  1148. * SQLite - uses SQLite's ``REGEXP`` placeholder operator and calls into
  1149. the Python ``re.match()`` builtin.
  1150. * other backends may provide special implementations.
  1151. * Backends without any special implementation will emit
  1152. the operator as "REGEXP" or "NOT REGEXP". This is compatible with
  1153. SQLite and MySQL, for example.
  1154. Regular expression support is currently implemented for Oracle
  1155. Database, PostgreSQL, MySQL and MariaDB. Partial support is available
  1156. for SQLite. Support among third-party dialects may vary.
  1157. :param pattern: The regular expression pattern string or column
  1158. clause.
  1159. :param flags: Any regular expression string flags to apply, passed as
  1160. plain Python string only. These flags are backend specific.
  1161. Some backends, like PostgreSQL and MariaDB, may alternatively
  1162. specify the flags as part of the pattern.
  1163. When using the ignore case flag 'i' in PostgreSQL, the ignore case
  1164. regexp match operator ``~*`` or ``!~*`` will be used.
  1165. .. versionadded:: 1.4
  1166. .. versionchanged:: 1.4.48, 2.0.18 Note that due to an implementation
  1167. error, the "flags" parameter previously accepted SQL expression
  1168. objects such as column expressions in addition to plain Python
  1169. strings. This implementation did not work correctly with caching
  1170. and was removed; strings only should be passed for the "flags"
  1171. parameter, as these flags are rendered as literal inline values
  1172. within SQL expressions.
  1173. .. seealso::
  1174. :meth:`_sql.ColumnOperators.regexp_replace`
  1175. """
  1176. return self.operate(regexp_match_op, pattern, flags=flags)
  1177. def regexp_replace(
  1178. self, pattern: Any, replacement: Any, flags: Optional[str] = None
  1179. ) -> ColumnOperators:
  1180. """Implements a database-specific 'regexp replace' operator.
  1181. E.g.::
  1182. stmt = select(
  1183. table.c.some_column.regexp_replace("b(..)", "X\1Y", flags="g")
  1184. )
  1185. :meth:`_sql.ColumnOperators.regexp_replace` attempts to resolve to
  1186. a REGEXP_REPLACE-like function provided by the backend, that
  1187. usually emit the function ``REGEXP_REPLACE()``. However,
  1188. the specific regular expression syntax and flags available are
  1189. **not backend agnostic**.
  1190. Regular expression replacement support is currently implemented for
  1191. Oracle Database, PostgreSQL, MySQL 8 or greater and MariaDB. Support
  1192. among third-party dialects may vary.
  1193. :param pattern: The regular expression pattern string or column
  1194. clause.
  1195. :param pattern: The replacement string or column clause.
  1196. :param flags: Any regular expression string flags to apply, passed as
  1197. plain Python string only. These flags are backend specific.
  1198. Some backends, like PostgreSQL and MariaDB, may alternatively
  1199. specify the flags as part of the pattern.
  1200. .. versionadded:: 1.4
  1201. .. versionchanged:: 1.4.48, 2.0.18 Note that due to an implementation
  1202. error, the "flags" parameter previously accepted SQL expression
  1203. objects such as column expressions in addition to plain Python
  1204. strings. This implementation did not work correctly with caching
  1205. and was removed; strings only should be passed for the "flags"
  1206. parameter, as these flags are rendered as literal inline values
  1207. within SQL expressions.
  1208. .. seealso::
  1209. :meth:`_sql.ColumnOperators.regexp_match`
  1210. """
  1211. return self.operate(
  1212. regexp_replace_op,
  1213. pattern,
  1214. replacement=replacement,
  1215. flags=flags,
  1216. )
  1217. def desc(self) -> ColumnOperators:
  1218. """Produce a :func:`_expression.desc` clause against the
  1219. parent object."""
  1220. return self.operate(desc_op)
  1221. def asc(self) -> ColumnOperators:
  1222. """Produce a :func:`_expression.asc` clause against the
  1223. parent object."""
  1224. return self.operate(asc_op)
  1225. def nulls_first(self) -> ColumnOperators:
  1226. """Produce a :func:`_expression.nulls_first` clause against the
  1227. parent object.
  1228. .. versionchanged:: 1.4 The ``nulls_first()`` operator is
  1229. renamed from ``nullsfirst()`` in previous releases.
  1230. The previous name remains available for backwards compatibility.
  1231. """
  1232. return self.operate(nulls_first_op)
  1233. # deprecated 1.4; see #5435
  1234. if TYPE_CHECKING:
  1235. def nullsfirst(self) -> ColumnOperators: ...
  1236. else:
  1237. nullsfirst = nulls_first
  1238. def nulls_last(self) -> ColumnOperators:
  1239. """Produce a :func:`_expression.nulls_last` clause against the
  1240. parent object.
  1241. .. versionchanged:: 1.4 The ``nulls_last()`` operator is
  1242. renamed from ``nullslast()`` in previous releases.
  1243. The previous name remains available for backwards compatibility.
  1244. """
  1245. return self.operate(nulls_last_op)
  1246. # deprecated 1.4; see #5429
  1247. if TYPE_CHECKING:
  1248. def nullslast(self) -> ColumnOperators: ...
  1249. else:
  1250. nullslast = nulls_last
  1251. def collate(self, collation: str) -> ColumnOperators:
  1252. """Produce a :func:`_expression.collate` clause against
  1253. the parent object, given the collation string.
  1254. .. seealso::
  1255. :func:`_expression.collate`
  1256. """
  1257. return self.operate(collate, collation)
  1258. def __radd__(self, other: Any) -> ColumnOperators:
  1259. """Implement the ``+`` operator in reverse.
  1260. See :meth:`.ColumnOperators.__add__`.
  1261. """
  1262. return self.reverse_operate(add, other)
  1263. def __rsub__(self, other: Any) -> ColumnOperators:
  1264. """Implement the ``-`` operator in reverse.
  1265. See :meth:`.ColumnOperators.__sub__`.
  1266. """
  1267. return self.reverse_operate(sub, other)
  1268. def __rmul__(self, other: Any) -> ColumnOperators:
  1269. """Implement the ``*`` operator in reverse.
  1270. See :meth:`.ColumnOperators.__mul__`.
  1271. """
  1272. return self.reverse_operate(mul, other)
  1273. def __rmod__(self, other: Any) -> ColumnOperators:
  1274. """Implement the ``%`` operator in reverse.
  1275. See :meth:`.ColumnOperators.__mod__`.
  1276. """
  1277. return self.reverse_operate(mod, other)
  1278. def between(
  1279. self, cleft: Any, cright: Any, symmetric: bool = False
  1280. ) -> ColumnOperators:
  1281. """Produce a :func:`_expression.between` clause against
  1282. the parent object, given the lower and upper range.
  1283. """
  1284. return self.operate(between_op, cleft, cright, symmetric=symmetric)
  1285. def distinct(self) -> ColumnOperators:
  1286. """Produce a :func:`_expression.distinct` clause against the
  1287. parent object.
  1288. """
  1289. return self.operate(distinct_op)
  1290. def any_(self) -> ColumnOperators:
  1291. """Produce an :func:`_expression.any_` clause against the
  1292. parent object.
  1293. See the documentation for :func:`_sql.any_` for examples.
  1294. .. note:: be sure to not confuse the newer
  1295. :meth:`_sql.ColumnOperators.any_` method with the **legacy**
  1296. version of this method, the :meth:`_types.ARRAY.Comparator.any`
  1297. method that's specific to :class:`_types.ARRAY`, which uses a
  1298. different calling style.
  1299. """
  1300. return self.operate(any_op)
  1301. def all_(self) -> ColumnOperators:
  1302. """Produce an :func:`_expression.all_` clause against the
  1303. parent object.
  1304. See the documentation for :func:`_sql.all_` for examples.
  1305. .. note:: be sure to not confuse the newer
  1306. :meth:`_sql.ColumnOperators.all_` method with the **legacy**
  1307. version of this method, the :meth:`_types.ARRAY.Comparator.all`
  1308. method that's specific to :class:`_types.ARRAY`, which uses a
  1309. different calling style.
  1310. """
  1311. return self.operate(all_op)
  1312. def __add__(self, other: Any) -> ColumnOperators:
  1313. """Implement the ``+`` operator.
  1314. In a column context, produces the clause ``a + b``
  1315. if the parent object has non-string affinity.
  1316. If the parent object has a string affinity,
  1317. produces the concatenation operator, ``a || b`` -
  1318. see :meth:`.ColumnOperators.concat`.
  1319. """
  1320. return self.operate(add, other)
  1321. def __sub__(self, other: Any) -> ColumnOperators:
  1322. """Implement the ``-`` operator.
  1323. In a column context, produces the clause ``a - b``.
  1324. """
  1325. return self.operate(sub, other)
  1326. def __mul__(self, other: Any) -> ColumnOperators:
  1327. """Implement the ``*`` operator.
  1328. In a column context, produces the clause ``a * b``.
  1329. """
  1330. return self.operate(mul, other)
  1331. def __mod__(self, other: Any) -> ColumnOperators:
  1332. """Implement the ``%`` operator.
  1333. In a column context, produces the clause ``a % b``.
  1334. """
  1335. return self.operate(mod, other)
  1336. def __truediv__(self, other: Any) -> ColumnOperators:
  1337. """Implement the ``/`` operator.
  1338. In a column context, produces the clause ``a / b``, and
  1339. considers the result type to be numeric.
  1340. .. versionchanged:: 2.0 The truediv operator against two integers
  1341. is now considered to return a numeric value. Behavior on specific
  1342. backends may vary.
  1343. """
  1344. return self.operate(truediv, other)
  1345. def __rtruediv__(self, other: Any) -> ColumnOperators:
  1346. """Implement the ``/`` operator in reverse.
  1347. See :meth:`.ColumnOperators.__truediv__`.
  1348. """
  1349. return self.reverse_operate(truediv, other)
  1350. def __floordiv__(self, other: Any) -> ColumnOperators:
  1351. """Implement the ``//`` operator.
  1352. In a column context, produces the clause ``a / b``,
  1353. which is the same as "truediv", but considers the result
  1354. type to be integer.
  1355. .. versionadded:: 2.0
  1356. """
  1357. return self.operate(floordiv, other)
  1358. def __rfloordiv__(self, other: Any) -> ColumnOperators:
  1359. """Implement the ``//`` operator in reverse.
  1360. See :meth:`.ColumnOperators.__floordiv__`.
  1361. """
  1362. return self.reverse_operate(floordiv, other)
  1363. _commutative: Set[Any] = {eq, ne, add, mul}
  1364. _comparison: Set[Any] = {eq, ne, lt, gt, ge, le}
  1365. def _operator_fn(fn: Callable[..., Any]) -> OperatorType:
  1366. return cast(OperatorType, fn)
  1367. def commutative_op(fn: _FN) -> _FN:
  1368. _commutative.add(fn)
  1369. return fn
  1370. def comparison_op(fn: _FN) -> _FN:
  1371. _comparison.add(fn)
  1372. return fn
  1373. @_operator_fn
  1374. def from_() -> Any:
  1375. raise NotImplementedError()
  1376. @_operator_fn
  1377. @comparison_op
  1378. def function_as_comparison_op() -> Any:
  1379. raise NotImplementedError()
  1380. @_operator_fn
  1381. def as_() -> Any:
  1382. raise NotImplementedError()
  1383. @_operator_fn
  1384. def exists() -> Any:
  1385. raise NotImplementedError()
  1386. @_operator_fn
  1387. def is_true(a: Any) -> Any:
  1388. raise NotImplementedError()
  1389. # 1.4 deprecated; see #5435
  1390. if TYPE_CHECKING:
  1391. @_operator_fn
  1392. def istrue(a: Any) -> Any: ...
  1393. else:
  1394. istrue = is_true
  1395. @_operator_fn
  1396. def is_false(a: Any) -> Any:
  1397. raise NotImplementedError()
  1398. # 1.4 deprecated; see #5435
  1399. if TYPE_CHECKING:
  1400. @_operator_fn
  1401. def isfalse(a: Any) -> Any: ...
  1402. else:
  1403. isfalse = is_false
  1404. @comparison_op
  1405. @_operator_fn
  1406. def is_distinct_from(a: Any, b: Any) -> Any:
  1407. return a.is_distinct_from(b)
  1408. @comparison_op
  1409. @_operator_fn
  1410. def is_not_distinct_from(a: Any, b: Any) -> Any:
  1411. return a.is_not_distinct_from(b)
  1412. # deprecated 1.4; see #5435
  1413. if TYPE_CHECKING:
  1414. @_operator_fn
  1415. def isnot_distinct_from(a: Any, b: Any) -> Any: ...
  1416. else:
  1417. isnot_distinct_from = is_not_distinct_from
  1418. @comparison_op
  1419. @_operator_fn
  1420. def is_(a: Any, b: Any) -> Any:
  1421. return a.is_(b)
  1422. @comparison_op
  1423. @_operator_fn
  1424. def is_not(a: Any, b: Any) -> Any:
  1425. return a.is_not(b)
  1426. # 1.4 deprecated; see #5429
  1427. if TYPE_CHECKING:
  1428. @_operator_fn
  1429. def isnot(a: Any, b: Any) -> Any: ...
  1430. else:
  1431. isnot = is_not
  1432. @_operator_fn
  1433. def collate(a: Any, b: Any) -> Any:
  1434. return a.collate(b)
  1435. @_operator_fn
  1436. def op(a: Any, opstring: str, b: Any) -> Any:
  1437. return a.op(opstring)(b)
  1438. @comparison_op
  1439. @_operator_fn
  1440. def like_op(a: Any, b: Any, escape: Optional[str] = None) -> Any:
  1441. return a.like(b, escape=escape)
  1442. @comparison_op
  1443. @_operator_fn
  1444. def not_like_op(a: Any, b: Any, escape: Optional[str] = None) -> Any:
  1445. return a.notlike(b, escape=escape)
  1446. # 1.4 deprecated; see #5435
  1447. if TYPE_CHECKING:
  1448. @_operator_fn
  1449. def notlike_op(a: Any, b: Any, escape: Optional[str] = None) -> Any: ...
  1450. else:
  1451. notlike_op = not_like_op
  1452. @comparison_op
  1453. @_operator_fn
  1454. def ilike_op(a: Any, b: Any, escape: Optional[str] = None) -> Any:
  1455. return a.ilike(b, escape=escape)
  1456. @comparison_op
  1457. @_operator_fn
  1458. def not_ilike_op(a: Any, b: Any, escape: Optional[str] = None) -> Any:
  1459. return a.not_ilike(b, escape=escape)
  1460. # 1.4 deprecated; see #5435
  1461. if TYPE_CHECKING:
  1462. @_operator_fn
  1463. def notilike_op(a: Any, b: Any, escape: Optional[str] = None) -> Any: ...
  1464. else:
  1465. notilike_op = not_ilike_op
  1466. @comparison_op
  1467. @_operator_fn
  1468. def between_op(a: Any, b: Any, c: Any, symmetric: bool = False) -> Any:
  1469. return a.between(b, c, symmetric=symmetric)
  1470. @comparison_op
  1471. @_operator_fn
  1472. def not_between_op(a: Any, b: Any, c: Any, symmetric: bool = False) -> Any:
  1473. return ~a.between(b, c, symmetric=symmetric)
  1474. # 1.4 deprecated; see #5435
  1475. if TYPE_CHECKING:
  1476. @_operator_fn
  1477. def notbetween_op(
  1478. a: Any, b: Any, c: Any, symmetric: bool = False
  1479. ) -> Any: ...
  1480. else:
  1481. notbetween_op = not_between_op
  1482. @comparison_op
  1483. @_operator_fn
  1484. def in_op(a: Any, b: Any) -> Any:
  1485. return a.in_(b)
  1486. @comparison_op
  1487. @_operator_fn
  1488. def not_in_op(a: Any, b: Any) -> Any:
  1489. return a.not_in(b)
  1490. # 1.4 deprecated; see #5429
  1491. if TYPE_CHECKING:
  1492. @_operator_fn
  1493. def notin_op(a: Any, b: Any) -> Any: ...
  1494. else:
  1495. notin_op = not_in_op
  1496. @_operator_fn
  1497. def distinct_op(a: Any) -> Any:
  1498. return a.distinct()
  1499. @_operator_fn
  1500. def any_op(a: Any) -> Any:
  1501. return a.any_()
  1502. @_operator_fn
  1503. def all_op(a: Any) -> Any:
  1504. return a.all_()
  1505. def _escaped_like_impl(
  1506. fn: Callable[..., Any], other: Any, escape: Optional[str], autoescape: bool
  1507. ) -> Any:
  1508. if autoescape:
  1509. if autoescape is not True:
  1510. util.warn(
  1511. "The autoescape parameter is now a simple boolean True/False"
  1512. )
  1513. if escape is None:
  1514. escape = "/"
  1515. if not isinstance(other, str):
  1516. raise TypeError("String value expected when autoescape=True")
  1517. if escape not in ("%", "_"):
  1518. other = other.replace(escape, escape + escape)
  1519. other = other.replace("%", escape + "%").replace("_", escape + "_")
  1520. return fn(other, escape=escape)
  1521. @comparison_op
  1522. @_operator_fn
  1523. def startswith_op(
  1524. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1525. ) -> Any:
  1526. return _escaped_like_impl(a.startswith, b, escape, autoescape)
  1527. @comparison_op
  1528. @_operator_fn
  1529. def not_startswith_op(
  1530. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1531. ) -> Any:
  1532. return ~_escaped_like_impl(a.startswith, b, escape, autoescape)
  1533. # 1.4 deprecated; see #5435
  1534. if TYPE_CHECKING:
  1535. @_operator_fn
  1536. def notstartswith_op(
  1537. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1538. ) -> Any: ...
  1539. else:
  1540. notstartswith_op = not_startswith_op
  1541. @comparison_op
  1542. @_operator_fn
  1543. def istartswith_op(
  1544. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1545. ) -> Any:
  1546. return _escaped_like_impl(a.istartswith, b, escape, autoescape)
  1547. @comparison_op
  1548. @_operator_fn
  1549. def not_istartswith_op(
  1550. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1551. ) -> Any:
  1552. return ~_escaped_like_impl(a.istartswith, b, escape, autoescape)
  1553. @comparison_op
  1554. @_operator_fn
  1555. def endswith_op(
  1556. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1557. ) -> Any:
  1558. return _escaped_like_impl(a.endswith, b, escape, autoescape)
  1559. @comparison_op
  1560. @_operator_fn
  1561. def not_endswith_op(
  1562. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1563. ) -> Any:
  1564. return ~_escaped_like_impl(a.endswith, b, escape, autoescape)
  1565. # 1.4 deprecated; see #5435
  1566. if TYPE_CHECKING:
  1567. @_operator_fn
  1568. def notendswith_op(
  1569. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1570. ) -> Any: ...
  1571. else:
  1572. notendswith_op = not_endswith_op
  1573. @comparison_op
  1574. @_operator_fn
  1575. def iendswith_op(
  1576. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1577. ) -> Any:
  1578. return _escaped_like_impl(a.iendswith, b, escape, autoescape)
  1579. @comparison_op
  1580. @_operator_fn
  1581. def not_iendswith_op(
  1582. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1583. ) -> Any:
  1584. return ~_escaped_like_impl(a.iendswith, b, escape, autoescape)
  1585. @comparison_op
  1586. @_operator_fn
  1587. def contains_op(
  1588. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1589. ) -> Any:
  1590. return _escaped_like_impl(a.contains, b, escape, autoescape)
  1591. @comparison_op
  1592. @_operator_fn
  1593. def not_contains_op(
  1594. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1595. ) -> Any:
  1596. return ~_escaped_like_impl(a.contains, b, escape, autoescape)
  1597. # 1.4 deprecated; see #5435
  1598. if TYPE_CHECKING:
  1599. @_operator_fn
  1600. def notcontains_op(
  1601. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1602. ) -> Any: ...
  1603. else:
  1604. notcontains_op = not_contains_op
  1605. @comparison_op
  1606. @_operator_fn
  1607. def icontains_op(
  1608. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1609. ) -> Any:
  1610. return _escaped_like_impl(a.icontains, b, escape, autoescape)
  1611. @comparison_op
  1612. @_operator_fn
  1613. def not_icontains_op(
  1614. a: Any, b: Any, escape: Optional[str] = None, autoescape: bool = False
  1615. ) -> Any:
  1616. return ~_escaped_like_impl(a.icontains, b, escape, autoescape)
  1617. @comparison_op
  1618. @_operator_fn
  1619. def match_op(a: Any, b: Any, **kw: Any) -> Any:
  1620. return a.match(b, **kw)
  1621. @comparison_op
  1622. @_operator_fn
  1623. def regexp_match_op(a: Any, b: Any, flags: Optional[str] = None) -> Any:
  1624. return a.regexp_match(b, flags=flags)
  1625. @comparison_op
  1626. @_operator_fn
  1627. def not_regexp_match_op(a: Any, b: Any, flags: Optional[str] = None) -> Any:
  1628. return ~a.regexp_match(b, flags=flags)
  1629. @_operator_fn
  1630. def regexp_replace_op(
  1631. a: Any, b: Any, replacement: Any, flags: Optional[str] = None
  1632. ) -> Any:
  1633. return a.regexp_replace(b, replacement=replacement, flags=flags)
  1634. @comparison_op
  1635. @_operator_fn
  1636. def not_match_op(a: Any, b: Any, **kw: Any) -> Any:
  1637. return ~a.match(b, **kw)
  1638. # 1.4 deprecated; see #5429
  1639. if TYPE_CHECKING:
  1640. @_operator_fn
  1641. def notmatch_op(a: Any, b: Any, **kw: Any) -> Any: ...
  1642. else:
  1643. notmatch_op = not_match_op
  1644. @_operator_fn
  1645. def comma_op(a: Any, b: Any) -> Any:
  1646. raise NotImplementedError()
  1647. @_operator_fn
  1648. def filter_op(a: Any, b: Any) -> Any:
  1649. raise NotImplementedError()
  1650. @_operator_fn
  1651. def concat_op(a: Any, b: Any) -> Any:
  1652. try:
  1653. concat = a.concat
  1654. except AttributeError:
  1655. return b._rconcat(a)
  1656. else:
  1657. return concat(b)
  1658. @_operator_fn
  1659. def desc_op(a: Any) -> Any:
  1660. return a.desc()
  1661. @_operator_fn
  1662. def asc_op(a: Any) -> Any:
  1663. return a.asc()
  1664. @_operator_fn
  1665. def nulls_first_op(a: Any) -> Any:
  1666. return a.nulls_first()
  1667. # 1.4 deprecated; see #5435
  1668. if TYPE_CHECKING:
  1669. @_operator_fn
  1670. def nullsfirst_op(a: Any) -> Any: ...
  1671. else:
  1672. nullsfirst_op = nulls_first_op
  1673. @_operator_fn
  1674. def nulls_last_op(a: Any) -> Any:
  1675. return a.nulls_last()
  1676. # 1.4 deprecated; see #5435
  1677. if TYPE_CHECKING:
  1678. @_operator_fn
  1679. def nullslast_op(a: Any) -> Any: ...
  1680. else:
  1681. nullslast_op = nulls_last_op
  1682. @_operator_fn
  1683. def json_getitem_op(a: Any, b: Any) -> Any:
  1684. raise NotImplementedError()
  1685. @_operator_fn
  1686. def json_path_getitem_op(a: Any, b: Any) -> Any:
  1687. raise NotImplementedError()
  1688. @_operator_fn
  1689. def bitwise_xor_op(a: Any, b: Any) -> Any:
  1690. return a.bitwise_xor(b)
  1691. @_operator_fn
  1692. def bitwise_or_op(a: Any, b: Any) -> Any:
  1693. return a.bitwise_or(b)
  1694. @_operator_fn
  1695. def bitwise_and_op(a: Any, b: Any) -> Any:
  1696. return a.bitwise_and(b)
  1697. @_operator_fn
  1698. def bitwise_not_op(a: Any) -> Any:
  1699. return a.bitwise_not()
  1700. @_operator_fn
  1701. def bitwise_lshift_op(a: Any, b: Any) -> Any:
  1702. return a.bitwise_lshift(b)
  1703. @_operator_fn
  1704. def bitwise_rshift_op(a: Any, b: Any) -> Any:
  1705. return a.bitwise_rshift(b)
  1706. def is_comparison(op: OperatorType) -> bool:
  1707. return op in _comparison or isinstance(op, custom_op) and op.is_comparison
  1708. def is_commutative(op: OperatorType) -> bool:
  1709. return op in _commutative
  1710. def is_ordering_modifier(op: OperatorType) -> bool:
  1711. return op in (asc_op, desc_op, nulls_first_op, nulls_last_op)
  1712. def is_natural_self_precedent(op: OperatorType) -> bool:
  1713. return (
  1714. op in _natural_self_precedent
  1715. or isinstance(op, custom_op)
  1716. and op.natural_self_precedent
  1717. )
  1718. _booleans = (inv, is_true, is_false, and_, or_)
  1719. def is_boolean(op: OperatorType) -> bool:
  1720. return is_comparison(op) or op in _booleans
  1721. _mirror = {gt: lt, ge: le, lt: gt, le: ge}
  1722. def mirror(op: OperatorType) -> OperatorType:
  1723. """rotate a comparison operator 180 degrees.
  1724. Note this is not the same as negation.
  1725. """
  1726. return _mirror.get(op, op)
  1727. _associative = _commutative.union([concat_op, and_, or_]).difference([eq, ne])
  1728. def is_associative(op: OperatorType) -> bool:
  1729. return op in _associative
  1730. def is_order_by_modifier(op: Optional[OperatorType]) -> bool:
  1731. return op in _order_by_modifier
  1732. _order_by_modifier = {desc_op, asc_op, nulls_first_op, nulls_last_op}
  1733. _natural_self_precedent = _associative.union(
  1734. [getitem, json_getitem_op, json_path_getitem_op]
  1735. )
  1736. """Operators where if we have (a op b) op c, we don't want to
  1737. parenthesize (a op b).
  1738. """
  1739. @_operator_fn
  1740. def _asbool(a: Any) -> Any:
  1741. raise NotImplementedError()
  1742. class _OpLimit(IntEnum):
  1743. _smallest = -100
  1744. _largest = 100
  1745. _PRECEDENCE: Dict[OperatorType, int] = {
  1746. from_: 15,
  1747. function_as_comparison_op: 15,
  1748. any_op: 15,
  1749. all_op: 15,
  1750. getitem: 15,
  1751. json_getitem_op: 15,
  1752. json_path_getitem_op: 15,
  1753. mul: 8,
  1754. truediv: 8,
  1755. floordiv: 8,
  1756. mod: 8,
  1757. neg: 8,
  1758. bitwise_not_op: 8,
  1759. add: 7,
  1760. sub: 7,
  1761. bitwise_xor_op: 7,
  1762. bitwise_or_op: 7,
  1763. bitwise_and_op: 7,
  1764. bitwise_lshift_op: 7,
  1765. bitwise_rshift_op: 7,
  1766. filter_op: 6,
  1767. concat_op: 5,
  1768. match_op: 5,
  1769. not_match_op: 5,
  1770. regexp_match_op: 5,
  1771. not_regexp_match_op: 5,
  1772. regexp_replace_op: 5,
  1773. ilike_op: 5,
  1774. not_ilike_op: 5,
  1775. like_op: 5,
  1776. not_like_op: 5,
  1777. in_op: 5,
  1778. not_in_op: 5,
  1779. is_: 5,
  1780. is_not: 5,
  1781. eq: 5,
  1782. ne: 5,
  1783. is_distinct_from: 5,
  1784. is_not_distinct_from: 5,
  1785. gt: 5,
  1786. lt: 5,
  1787. ge: 5,
  1788. le: 5,
  1789. between_op: 5,
  1790. not_between_op: 5,
  1791. distinct_op: 5,
  1792. inv: 5,
  1793. is_true: 5,
  1794. is_false: 5,
  1795. and_: 3,
  1796. or_: 2,
  1797. comma_op: -1,
  1798. desc_op: 3,
  1799. asc_op: 3,
  1800. collate: 4,
  1801. as_: -1,
  1802. exists: 0,
  1803. _asbool: -10,
  1804. }
  1805. def is_precedent(
  1806. operator: OperatorType, against: Optional[OperatorType]
  1807. ) -> bool:
  1808. if operator is against and is_natural_self_precedent(operator):
  1809. return False
  1810. elif against is None:
  1811. return True
  1812. else:
  1813. return bool(
  1814. _PRECEDENCE.get(
  1815. operator, getattr(operator, "precedence", _OpLimit._smallest)
  1816. )
  1817. <= _PRECEDENCE.get(
  1818. against, getattr(against, "precedence", _OpLimit._largest)
  1819. )
  1820. )