operators.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. # sql/operators.py
  2. # Copyright (C) 2005-2017 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: http://www.opensource.org/licenses/mit-license.php
  7. # This module is part of SQLAlchemy and is released under
  8. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  9. """Defines operators used in SQL expressions."""
  10. from .. import util
  11. from operator import (
  12. and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg,
  13. getitem, lshift, rshift, contains
  14. )
  15. if util.py2k:
  16. from operator import div
  17. else:
  18. div = truediv
  19. class Operators(object):
  20. """Base of comparison and logical operators.
  21. Implements base methods
  22. :meth:`~sqlalchemy.sql.operators.Operators.operate` and
  23. :meth:`~sqlalchemy.sql.operators.Operators.reverse_operate`, as well as
  24. :meth:`~sqlalchemy.sql.operators.Operators.__and__`,
  25. :meth:`~sqlalchemy.sql.operators.Operators.__or__`,
  26. :meth:`~sqlalchemy.sql.operators.Operators.__invert__`.
  27. Usually is used via its most common subclass
  28. :class:`.ColumnOperators`.
  29. """
  30. __slots__ = ()
  31. def __and__(self, other):
  32. """Implement the ``&`` operator.
  33. When used with SQL expressions, results in an
  34. AND operation, equivalent to
  35. :func:`~.expression.and_`, that is::
  36. a & b
  37. is equivalent to::
  38. from sqlalchemy import and_
  39. and_(a, b)
  40. Care should be taken when using ``&`` regarding
  41. operator precedence; the ``&`` operator has the highest precedence.
  42. The operands should be enclosed in parenthesis if they contain
  43. further sub expressions::
  44. (a == 2) & (b == 4)
  45. """
  46. return self.operate(and_, other)
  47. def __or__(self, other):
  48. """Implement the ``|`` operator.
  49. When used with SQL expressions, results in an
  50. OR operation, equivalent to
  51. :func:`~.expression.or_`, that is::
  52. a | b
  53. is equivalent to::
  54. from sqlalchemy import or_
  55. or_(a, b)
  56. Care should be taken when using ``|`` regarding
  57. operator precedence; the ``|`` operator has the highest precedence.
  58. The operands should be enclosed in parenthesis if they contain
  59. further sub expressions::
  60. (a == 2) | (b == 4)
  61. """
  62. return self.operate(or_, other)
  63. def __invert__(self):
  64. """Implement the ``~`` operator.
  65. When used with SQL expressions, results in a
  66. NOT operation, equivalent to
  67. :func:`~.expression.not_`, that is::
  68. ~a
  69. is equivalent to::
  70. from sqlalchemy import not_
  71. not_(a)
  72. """
  73. return self.operate(inv)
  74. def op(self, opstring, precedence=0, is_comparison=False):
  75. """produce a generic operator function.
  76. e.g.::
  77. somecolumn.op("*")(5)
  78. produces::
  79. somecolumn * 5
  80. This function can also be used to make bitwise operators explicit. For
  81. example::
  82. somecolumn.op('&')(0xff)
  83. is a bitwise AND of the value in ``somecolumn``.
  84. :param operator: a string which will be output as the infix operator
  85. between this element and the expression passed to the
  86. generated function.
  87. :param precedence: precedence to apply to the operator, when
  88. parenthesizing expressions. A lower number will cause the expression
  89. to be parenthesized when applied against another operator with
  90. higher precedence. The default value of ``0`` is lower than all
  91. operators except for the comma (``,``) and ``AS`` operators.
  92. A value of 100 will be higher or equal to all operators, and -100
  93. will be lower than or equal to all operators.
  94. .. versionadded:: 0.8 - added the 'precedence' argument.
  95. :param is_comparison: if True, the operator will be considered as a
  96. "comparison" operator, that is which evaluates to a boolean
  97. true/false value, like ``==``, ``>``, etc. This flag should be set
  98. so that ORM relationships can establish that the operator is a
  99. comparison operator when used in a custom join condition.
  100. .. versionadded:: 0.9.2 - added the
  101. :paramref:`.Operators.op.is_comparison` flag.
  102. .. seealso::
  103. :ref:`types_operators`
  104. :ref:`relationship_custom_operator`
  105. """
  106. operator = custom_op(opstring, precedence, is_comparison)
  107. def against(other):
  108. return operator(self, other)
  109. return against
  110. def operate(self, op, *other, **kwargs):
  111. r"""Operate on an argument.
  112. This is the lowest level of operation, raises
  113. :class:`NotImplementedError` by default.
  114. Overriding this on a subclass can allow common
  115. behavior to be applied to all operations.
  116. For example, overriding :class:`.ColumnOperators`
  117. to apply ``func.lower()`` to the left and right
  118. side::
  119. class MyComparator(ColumnOperators):
  120. def operate(self, op, other):
  121. return op(func.lower(self), func.lower(other))
  122. :param op: Operator callable.
  123. :param \*other: the 'other' side of the operation. Will
  124. be a single scalar for most operations.
  125. :param \**kwargs: modifiers. These may be passed by special
  126. operators such as :meth:`ColumnOperators.contains`.
  127. """
  128. raise NotImplementedError(str(op))
  129. def reverse_operate(self, op, other, **kwargs):
  130. """Reverse operate on an argument.
  131. Usage is the same as :meth:`operate`.
  132. """
  133. raise NotImplementedError(str(op))
  134. class custom_op(object):
  135. """Represent a 'custom' operator.
  136. :class:`.custom_op` is normally instantitated when the
  137. :meth:`.ColumnOperators.op` method is used to create a
  138. custom operator callable. The class can also be used directly
  139. when programmatically constructing expressions. E.g.
  140. to represent the "factorial" operation::
  141. from sqlalchemy.sql import UnaryExpression
  142. from sqlalchemy.sql import operators
  143. from sqlalchemy import Numeric
  144. unary = UnaryExpression(table.c.somecolumn,
  145. modifier=operators.custom_op("!"),
  146. type_=Numeric)
  147. """
  148. __name__ = 'custom_op'
  149. def __init__(
  150. self, opstring, precedence=0, is_comparison=False,
  151. natural_self_precedent=False, eager_grouping=False):
  152. self.opstring = opstring
  153. self.precedence = precedence
  154. self.is_comparison = is_comparison
  155. self.natural_self_precedent = natural_self_precedent
  156. self.eager_grouping = eager_grouping
  157. def __eq__(self, other):
  158. return isinstance(other, custom_op) and \
  159. other.opstring == self.opstring
  160. def __hash__(self):
  161. return id(self)
  162. def __call__(self, left, right, **kw):
  163. return left.operate(self, right, **kw)
  164. class ColumnOperators(Operators):
  165. """Defines boolean, comparison, and other operators for
  166. :class:`.ColumnElement` expressions.
  167. By default, all methods call down to
  168. :meth:`.operate` or :meth:`.reverse_operate`,
  169. passing in the appropriate operator function from the
  170. Python builtin ``operator`` module or
  171. a SQLAlchemy-specific operator function from
  172. :mod:`sqlalchemy.expression.operators`. For example
  173. the ``__eq__`` function::
  174. def __eq__(self, other):
  175. return self.operate(operators.eq, other)
  176. Where ``operators.eq`` is essentially::
  177. def eq(a, b):
  178. return a == b
  179. The core column expression unit :class:`.ColumnElement`
  180. overrides :meth:`.Operators.operate` and others
  181. to return further :class:`.ColumnElement` constructs,
  182. so that the ``==`` operation above is replaced by a clause
  183. construct.
  184. See also:
  185. :ref:`types_operators`
  186. :attr:`.TypeEngine.comparator_factory`
  187. :class:`.ColumnOperators`
  188. :class:`.PropComparator`
  189. """
  190. __slots__ = ()
  191. timetuple = None
  192. """Hack, allows datetime objects to be compared on the LHS."""
  193. def __lt__(self, other):
  194. """Implement the ``<`` operator.
  195. In a column context, produces the clause ``a < b``.
  196. """
  197. return self.operate(lt, other)
  198. def __le__(self, other):
  199. """Implement the ``<=`` operator.
  200. In a column context, produces the clause ``a <= b``.
  201. """
  202. return self.operate(le, other)
  203. __hash__ = Operators.__hash__
  204. def __eq__(self, other):
  205. """Implement the ``==`` operator.
  206. In a column context, produces the clause ``a = b``.
  207. If the target is ``None``, produces ``a IS NULL``.
  208. """
  209. return self.operate(eq, other)
  210. def __ne__(self, other):
  211. """Implement the ``!=`` operator.
  212. In a column context, produces the clause ``a != b``.
  213. If the target is ``None``, produces ``a IS NOT NULL``.
  214. """
  215. return self.operate(ne, other)
  216. def is_distinct_from(self, other):
  217. """Implement the ``IS DISTINCT FROM`` operator.
  218. Renders "a IS DISTINCT FROM b" on most platforms;
  219. on some such as SQLite may render "a IS NOT b".
  220. .. versionadded:: 1.1
  221. """
  222. return self.operate(is_distinct_from, other)
  223. def isnot_distinct_from(self, other):
  224. """Implement the ``IS NOT DISTINCT FROM`` operator.
  225. Renders "a IS NOT DISTINCT FROM b" on most platforms;
  226. on some such as SQLite may render "a IS b".
  227. .. versionadded:: 1.1
  228. """
  229. return self.operate(isnot_distinct_from, other)
  230. def __gt__(self, other):
  231. """Implement the ``>`` operator.
  232. In a column context, produces the clause ``a > b``.
  233. """
  234. return self.operate(gt, other)
  235. def __ge__(self, other):
  236. """Implement the ``>=`` operator.
  237. In a column context, produces the clause ``a >= b``.
  238. """
  239. return self.operate(ge, other)
  240. def __neg__(self):
  241. """Implement the ``-`` operator.
  242. In a column context, produces the clause ``-a``.
  243. """
  244. return self.operate(neg)
  245. def __contains__(self, other):
  246. return self.operate(contains, other)
  247. def __getitem__(self, index):
  248. """Implement the [] operator.
  249. This can be used by some database-specific types
  250. such as PostgreSQL ARRAY and HSTORE.
  251. """
  252. return self.operate(getitem, index)
  253. def __lshift__(self, other):
  254. """implement the << operator.
  255. Not used by SQLAlchemy core, this is provided
  256. for custom operator systems which want to use
  257. << as an extension point.
  258. """
  259. return self.operate(lshift, other)
  260. def __rshift__(self, other):
  261. """implement the >> operator.
  262. Not used by SQLAlchemy core, this is provided
  263. for custom operator systems which want to use
  264. >> as an extension point.
  265. """
  266. return self.operate(rshift, other)
  267. def concat(self, other):
  268. """Implement the 'concat' operator.
  269. In a column context, produces the clause ``a || b``,
  270. or uses the ``concat()`` operator on MySQL.
  271. """
  272. return self.operate(concat_op, other)
  273. def like(self, other, escape=None):
  274. r"""Implement the ``like`` operator.
  275. In a column context, produces the expression::
  276. a LIKE other
  277. E.g.::
  278. stmt = select([sometable]).\
  279. where(sometable.c.column.like("%foobar%"))
  280. :param other: expression to be compared
  281. :param escape: optional escape character, renders the ``ESCAPE``
  282. keyword, e.g.::
  283. somecolumn.like("foo/%bar", escape="/")
  284. .. seealso::
  285. :meth:`.ColumnOperators.ilike`
  286. """
  287. return self.operate(like_op, other, escape=escape)
  288. def ilike(self, other, escape=None):
  289. r"""Implement the ``ilike`` operator, e.g. case insensitive LIKE.
  290. In a column context, produces an expression either of the form::
  291. lower(a) LIKE lower(other)
  292. Or on backends that support the ILIKE operator::
  293. a ILIKE other
  294. E.g.::
  295. stmt = select([sometable]).\
  296. where(sometable.c.column.ilike("%foobar%"))
  297. :param other: expression to be compared
  298. :param escape: optional escape character, renders the ``ESCAPE``
  299. keyword, e.g.::
  300. somecolumn.ilike("foo/%bar", escape="/")
  301. .. seealso::
  302. :meth:`.ColumnOperators.like`
  303. """
  304. return self.operate(ilike_op, other, escape=escape)
  305. def in_(self, other):
  306. """Implement the ``in`` operator.
  307. In a column context, produces the clause ``a IN other``.
  308. "other" may be a tuple/list of column expressions,
  309. or a :func:`~.expression.select` construct.
  310. """
  311. return self.operate(in_op, other)
  312. def notin_(self, other):
  313. """implement the ``NOT IN`` operator.
  314. This is equivalent to using negation with
  315. :meth:`.ColumnOperators.in_`, i.e. ``~x.in_(y)``.
  316. .. versionadded:: 0.8
  317. .. seealso::
  318. :meth:`.ColumnOperators.in_`
  319. """
  320. return self.operate(notin_op, other)
  321. def notlike(self, other, escape=None):
  322. """implement the ``NOT LIKE`` operator.
  323. This is equivalent to using negation with
  324. :meth:`.ColumnOperators.like`, i.e. ``~x.like(y)``.
  325. .. versionadded:: 0.8
  326. .. seealso::
  327. :meth:`.ColumnOperators.like`
  328. """
  329. return self.operate(notlike_op, other, escape=escape)
  330. def notilike(self, other, escape=None):
  331. """implement the ``NOT ILIKE`` operator.
  332. This is equivalent to using negation with
  333. :meth:`.ColumnOperators.ilike`, i.e. ``~x.ilike(y)``.
  334. .. versionadded:: 0.8
  335. .. seealso::
  336. :meth:`.ColumnOperators.ilike`
  337. """
  338. return self.operate(notilike_op, other, escape=escape)
  339. def is_(self, other):
  340. """Implement the ``IS`` operator.
  341. Normally, ``IS`` is generated automatically when comparing to a
  342. value of ``None``, which resolves to ``NULL``. However, explicit
  343. usage of ``IS`` may be desirable if comparing to boolean values
  344. on certain platforms.
  345. .. versionadded:: 0.7.9
  346. .. seealso:: :meth:`.ColumnOperators.isnot`
  347. """
  348. return self.operate(is_, other)
  349. def isnot(self, other):
  350. """Implement the ``IS NOT`` operator.
  351. Normally, ``IS NOT`` is generated automatically when comparing to a
  352. value of ``None``, which resolves to ``NULL``. However, explicit
  353. usage of ``IS NOT`` may be desirable if comparing to boolean values
  354. on certain platforms.
  355. .. versionadded:: 0.7.9
  356. .. seealso:: :meth:`.ColumnOperators.is_`
  357. """
  358. return self.operate(isnot, other)
  359. def startswith(self, other, **kwargs):
  360. """Implement the ``startwith`` operator.
  361. In a column context, produces the clause ``LIKE '<other>%'``
  362. """
  363. return self.operate(startswith_op, other, **kwargs)
  364. def endswith(self, other, **kwargs):
  365. """Implement the 'endswith' operator.
  366. In a column context, produces the clause ``LIKE '%<other>'``
  367. """
  368. return self.operate(endswith_op, other, **kwargs)
  369. def contains(self, other, **kwargs):
  370. """Implement the 'contains' operator.
  371. In a column context, produces the clause ``LIKE '%<other>%'``
  372. """
  373. return self.operate(contains_op, other, **kwargs)
  374. def match(self, other, **kwargs):
  375. """Implements a database-specific 'match' operator.
  376. :meth:`~.ColumnOperators.match` attempts to resolve to
  377. a MATCH-like function or operator provided by the backend.
  378. Examples include:
  379. * PostgreSQL - renders ``x @@ to_tsquery(y)``
  380. * MySQL - renders ``MATCH (x) AGAINST (y IN BOOLEAN MODE)``
  381. * Oracle - renders ``CONTAINS(x, y)``
  382. * other backends may provide special implementations.
  383. * Backends without any special implementation will emit
  384. the operator as "MATCH". This is compatible with SQlite, for
  385. example.
  386. """
  387. return self.operate(match_op, other, **kwargs)
  388. def desc(self):
  389. """Produce a :func:`~.expression.desc` clause against the
  390. parent object."""
  391. return self.operate(desc_op)
  392. def asc(self):
  393. """Produce a :func:`~.expression.asc` clause against the
  394. parent object."""
  395. return self.operate(asc_op)
  396. def nullsfirst(self):
  397. """Produce a :func:`~.expression.nullsfirst` clause against the
  398. parent object."""
  399. return self.operate(nullsfirst_op)
  400. def nullslast(self):
  401. """Produce a :func:`~.expression.nullslast` clause against the
  402. parent object."""
  403. return self.operate(nullslast_op)
  404. def collate(self, collation):
  405. """Produce a :func:`~.expression.collate` clause against
  406. the parent object, given the collation string."""
  407. return self.operate(collate, collation)
  408. def __radd__(self, other):
  409. """Implement the ``+`` operator in reverse.
  410. See :meth:`.ColumnOperators.__add__`.
  411. """
  412. return self.reverse_operate(add, other)
  413. def __rsub__(self, other):
  414. """Implement the ``-`` operator in reverse.
  415. See :meth:`.ColumnOperators.__sub__`.
  416. """
  417. return self.reverse_operate(sub, other)
  418. def __rmul__(self, other):
  419. """Implement the ``*`` operator in reverse.
  420. See :meth:`.ColumnOperators.__mul__`.
  421. """
  422. return self.reverse_operate(mul, other)
  423. def __rdiv__(self, other):
  424. """Implement the ``/`` operator in reverse.
  425. See :meth:`.ColumnOperators.__div__`.
  426. """
  427. return self.reverse_operate(div, other)
  428. def __rmod__(self, other):
  429. """Implement the ``%`` operator in reverse.
  430. See :meth:`.ColumnOperators.__mod__`.
  431. """
  432. return self.reverse_operate(mod, other)
  433. def between(self, cleft, cright, symmetric=False):
  434. """Produce a :func:`~.expression.between` clause against
  435. the parent object, given the lower and upper range.
  436. """
  437. return self.operate(between_op, cleft, cright, symmetric=symmetric)
  438. def distinct(self):
  439. """Produce a :func:`~.expression.distinct` clause against the
  440. parent object.
  441. """
  442. return self.operate(distinct_op)
  443. def any_(self):
  444. """Produce a :func:`~.expression.any_` clause against the
  445. parent object.
  446. .. versionadded:: 1.1
  447. """
  448. return self.operate(any_op)
  449. def all_(self):
  450. """Produce a :func:`~.expression.all_` clause against the
  451. parent object.
  452. .. versionadded:: 1.1
  453. """
  454. return self.operate(all_op)
  455. def __add__(self, other):
  456. """Implement the ``+`` operator.
  457. In a column context, produces the clause ``a + b``
  458. if the parent object has non-string affinity.
  459. If the parent object has a string affinity,
  460. produces the concatenation operator, ``a || b`` -
  461. see :meth:`.ColumnOperators.concat`.
  462. """
  463. return self.operate(add, other)
  464. def __sub__(self, other):
  465. """Implement the ``-`` operator.
  466. In a column context, produces the clause ``a - b``.
  467. """
  468. return self.operate(sub, other)
  469. def __mul__(self, other):
  470. """Implement the ``*`` operator.
  471. In a column context, produces the clause ``a * b``.
  472. """
  473. return self.operate(mul, other)
  474. def __div__(self, other):
  475. """Implement the ``/`` operator.
  476. In a column context, produces the clause ``a / b``.
  477. """
  478. return self.operate(div, other)
  479. def __mod__(self, other):
  480. """Implement the ``%`` operator.
  481. In a column context, produces the clause ``a % b``.
  482. """
  483. return self.operate(mod, other)
  484. def __truediv__(self, other):
  485. """Implement the ``//`` operator.
  486. In a column context, produces the clause ``a / b``.
  487. """
  488. return self.operate(truediv, other)
  489. def __rtruediv__(self, other):
  490. """Implement the ``//`` operator in reverse.
  491. See :meth:`.ColumnOperators.__truediv__`.
  492. """
  493. return self.reverse_operate(truediv, other)
  494. def from_():
  495. raise NotImplementedError()
  496. def as_():
  497. raise NotImplementedError()
  498. def exists():
  499. raise NotImplementedError()
  500. def istrue(a):
  501. raise NotImplementedError()
  502. def isfalse(a):
  503. raise NotImplementedError()
  504. def is_distinct_from(a, b):
  505. return a.is_distinct_from(b)
  506. def isnot_distinct_from(a, b):
  507. return a.isnot_distinct_from(b)
  508. def is_(a, b):
  509. return a.is_(b)
  510. def isnot(a, b):
  511. return a.isnot(b)
  512. def collate(a, b):
  513. return a.collate(b)
  514. def op(a, opstring, b):
  515. return a.op(opstring)(b)
  516. def like_op(a, b, escape=None):
  517. return a.like(b, escape=escape)
  518. def notlike_op(a, b, escape=None):
  519. return a.notlike(b, escape=escape)
  520. def ilike_op(a, b, escape=None):
  521. return a.ilike(b, escape=escape)
  522. def notilike_op(a, b, escape=None):
  523. return a.notilike(b, escape=escape)
  524. def between_op(a, b, c, symmetric=False):
  525. return a.between(b, c, symmetric=symmetric)
  526. def notbetween_op(a, b, c, symmetric=False):
  527. return a.notbetween(b, c, symmetric=symmetric)
  528. def in_op(a, b):
  529. return a.in_(b)
  530. def notin_op(a, b):
  531. return a.notin_(b)
  532. def distinct_op(a):
  533. return a.distinct()
  534. def any_op(a):
  535. return a.any_()
  536. def all_op(a):
  537. return a.all_()
  538. def startswith_op(a, b, escape=None):
  539. return a.startswith(b, escape=escape)
  540. def notstartswith_op(a, b, escape=None):
  541. return ~a.startswith(b, escape=escape)
  542. def endswith_op(a, b, escape=None):
  543. return a.endswith(b, escape=escape)
  544. def notendswith_op(a, b, escape=None):
  545. return ~a.endswith(b, escape=escape)
  546. def contains_op(a, b, escape=None):
  547. return a.contains(b, escape=escape)
  548. def notcontains_op(a, b, escape=None):
  549. return ~a.contains(b, escape=escape)
  550. def match_op(a, b, **kw):
  551. return a.match(b, **kw)
  552. def notmatch_op(a, b, **kw):
  553. return a.notmatch(b, **kw)
  554. def comma_op(a, b):
  555. raise NotImplementedError()
  556. def concat_op(a, b):
  557. return a.concat(b)
  558. def desc_op(a):
  559. return a.desc()
  560. def asc_op(a):
  561. return a.asc()
  562. def nullsfirst_op(a):
  563. return a.nullsfirst()
  564. def nullslast_op(a):
  565. return a.nullslast()
  566. def json_getitem_op(a, b):
  567. raise NotImplementedError()
  568. def json_path_getitem_op(a, b):
  569. raise NotImplementedError()
  570. _commutative = set([eq, ne, add, mul])
  571. _comparison = set([eq, ne, lt, gt, ge, le, between_op, like_op])
  572. def is_comparison(op):
  573. return op in _comparison or \
  574. isinstance(op, custom_op) and op.is_comparison
  575. def is_commutative(op):
  576. return op in _commutative
  577. def is_ordering_modifier(op):
  578. return op in (asc_op, desc_op,
  579. nullsfirst_op, nullslast_op)
  580. def is_natural_self_precedent(op):
  581. return op in _natural_self_precedent or \
  582. isinstance(op, custom_op) and op.natural_self_precedent
  583. _mirror = {
  584. gt: lt,
  585. ge: le,
  586. lt: gt,
  587. le: ge
  588. }
  589. def mirror(op):
  590. """rotate a comparison operator 180 degrees.
  591. Note this is not the same as negation.
  592. """
  593. return _mirror.get(op, op)
  594. _associative = _commutative.union([concat_op, and_, or_]).difference([eq, ne])
  595. _natural_self_precedent = _associative.union([
  596. getitem, json_getitem_op, json_path_getitem_op])
  597. """Operators where if we have (a op b) op c, we don't want to
  598. parenthesize (a op b).
  599. """
  600. _asbool = util.symbol('_asbool', canonical=-10)
  601. _smallest = util.symbol('_smallest', canonical=-100)
  602. _largest = util.symbol('_largest', canonical=100)
  603. _PRECEDENCE = {
  604. from_: 15,
  605. any_op: 15,
  606. all_op: 15,
  607. getitem: 15,
  608. json_getitem_op: 15,
  609. json_path_getitem_op: 15,
  610. mul: 8,
  611. truediv: 8,
  612. div: 8,
  613. mod: 8,
  614. neg: 8,
  615. add: 7,
  616. sub: 7,
  617. concat_op: 6,
  618. match_op: 6,
  619. notmatch_op: 6,
  620. ilike_op: 6,
  621. notilike_op: 6,
  622. like_op: 6,
  623. notlike_op: 6,
  624. in_op: 6,
  625. notin_op: 6,
  626. is_: 6,
  627. isnot: 6,
  628. eq: 5,
  629. ne: 5,
  630. is_distinct_from: 5,
  631. isnot_distinct_from: 5,
  632. gt: 5,
  633. lt: 5,
  634. ge: 5,
  635. le: 5,
  636. between_op: 5,
  637. notbetween_op: 5,
  638. distinct_op: 5,
  639. inv: 5,
  640. istrue: 5,
  641. isfalse: 5,
  642. and_: 3,
  643. or_: 2,
  644. comma_op: -1,
  645. desc_op: 3,
  646. asc_op: 3,
  647. collate: 4,
  648. as_: -1,
  649. exists: 0,
  650. _asbool: -10,
  651. _smallest: _smallest,
  652. _largest: _largest
  653. }
  654. def is_precedent(operator, against):
  655. if operator is against and is_natural_self_precedent(operator):
  656. return False
  657. else:
  658. return (_PRECEDENCE.get(operator,
  659. getattr(operator, 'precedence', _smallest)) <=
  660. _PRECEDENCE.get(against,
  661. getattr(against, 'precedence', _largest)))