/lib/sqlalchemy/sql/operators.py

https://bitbucket.org/sqlalchemy/sqlalchemy/ · Python · 582 lines · 477 code · 10 blank · 95 comment · 0 complexity · 346752cdd4e371eb89fa83b652cebb43 MD5 · raw file

  1. # sql/operators.py
  2. # Copyright (C) 2005-2012 the SQLAlchemy authors and contributors <see AUTHORS file>
  3. #
  4. # This module is part of SQLAlchemy and is released under
  5. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  6. # This module is part of SQLAlchemy and is released under
  7. # the MIT License: http://www.opensource.org/licenses/mit-license.php
  8. """Defines operators used in SQL expressions."""
  9. from operator import (
  10. and_, or_, inv, add, mul, sub, mod, truediv, lt, le, ne, gt, ge, eq, neg
  11. )
  12. # Py2K
  13. from operator import (div,)
  14. # end Py2K
  15. from sqlalchemy.util import symbol
  16. class Operators(object):
  17. """Base of comparison and logical operators.
  18. Implements base methods :meth:`operate` and :meth:`reverse_operate`,
  19. as well as :meth:`__and__`, :meth:`__or__`, :meth:`__invert__`.
  20. Usually is used via its most common subclass
  21. :class:`.ColumnOperators`.
  22. """
  23. def __and__(self, other):
  24. """Implement the ``&`` operator.
  25. When used with SQL expressions, results in an
  26. AND operation, equivalent to
  27. :func:`~.expression.and_`, that is::
  28. a & b
  29. is equivalent to::
  30. from sqlalchemy import and_
  31. and_(a, b)
  32. Care should be taken when using ``&`` regarding
  33. operator precedence; the ``&`` operator has the highest precedence.
  34. The operands should be enclosed in parenthesis if they contain
  35. further sub expressions::
  36. (a == 2) & (b == 4)
  37. """
  38. return self.operate(and_, other)
  39. def __or__(self, other):
  40. """Implement the ``|`` operator.
  41. When used with SQL expressions, results in an
  42. OR operation, equivalent to
  43. :func:`~.expression.or_`, that is::
  44. a | b
  45. is equivalent to::
  46. from sqlalchemy import or_
  47. or_(a, b)
  48. Care should be taken when using ``|`` regarding
  49. operator precedence; the ``|`` operator has the highest precedence.
  50. The operands should be enclosed in parenthesis if they contain
  51. further sub expressions::
  52. (a == 2) | (b == 4)
  53. """
  54. return self.operate(or_, other)
  55. def __invert__(self):
  56. """Implement the ``~`` operator.
  57. When used with SQL expressions, results in a
  58. NOT operation, equivalent to
  59. :func:`~.expression.not_`, that is::
  60. ~a
  61. is equivalent to::
  62. from sqlalchemy import not_
  63. not_(a)
  64. """
  65. return self.operate(inv)
  66. def op(self, opstring):
  67. """produce a generic operator function.
  68. e.g.::
  69. somecolumn.op("*")(5)
  70. produces::
  71. somecolumn * 5
  72. :param operator: a string which will be output as the infix operator
  73. between this :class:`.ClauseElement` and the expression passed to the
  74. generated function.
  75. This function can also be used to make bitwise operators explicit. For
  76. example::
  77. somecolumn.op('&')(0xff)
  78. is a bitwise AND of the value in somecolumn.
  79. """
  80. def _op(b):
  81. return self.operate(op, opstring, b)
  82. return _op
  83. def operate(self, op, *other, **kwargs):
  84. """Operate on an argument.
  85. This is the lowest level of operation, raises
  86. :class:`NotImplementedError` by default.
  87. Overriding this on a subclass can allow common
  88. behavior to be applied to all operations.
  89. For example, overriding :class:`.ColumnOperators`
  90. to apply ``func.lower()`` to the left and right
  91. side::
  92. class MyComparator(ColumnOperators):
  93. def operate(self, op, other):
  94. return op(func.lower(self), func.lower(other))
  95. :param op: Operator callable.
  96. :param \*other: the 'other' side of the operation. Will
  97. be a single scalar for most operations.
  98. :param \**kwargs: modifiers. These may be passed by special
  99. operators such as :meth:`ColumnOperators.contains`.
  100. """
  101. raise NotImplementedError(str(op))
  102. def reverse_operate(self, op, other, **kwargs):
  103. """Reverse operate on an argument.
  104. Usage is the same as :meth:`operate`.
  105. """
  106. raise NotImplementedError(str(op))
  107. class ColumnOperators(Operators):
  108. """Defines comparison and math operations.
  109. By default all methods call down to
  110. :meth:`Operators.operate` or :meth:`Operators.reverse_operate`
  111. passing in the appropriate operator function from the
  112. Python builtin ``operator`` module or
  113. a SQLAlchemy-specific operator function from
  114. :mod:`sqlalchemy.expression.operators`. For example
  115. the ``__eq__`` function::
  116. def __eq__(self, other):
  117. return self.operate(operators.eq, other)
  118. Where ``operators.eq`` is essentially::
  119. def eq(a, b):
  120. return a == b
  121. A SQLAlchemy construct like :class:`.ColumnElement` ultimately
  122. overrides :meth:`.Operators.operate` and others
  123. to return further :class:`.ClauseElement` constructs,
  124. so that the ``==`` operation above is replaced by a clause
  125. construct.
  126. The docstrings here will describe column-oriented
  127. behavior of each operator. For ORM-based operators
  128. on related objects and collections, see :class:`.RelationshipProperty.Comparator`.
  129. """
  130. timetuple = None
  131. """Hack, allows datetime objects to be compared on the LHS."""
  132. def __lt__(self, other):
  133. """Implement the ``<`` operator.
  134. In a column context, produces the clause ``a < b``.
  135. """
  136. return self.operate(lt, other)
  137. def __le__(self, other):
  138. """Implement the ``<=`` operator.
  139. In a column context, produces the clause ``a <= b``.
  140. """
  141. return self.operate(le, other)
  142. __hash__ = Operators.__hash__
  143. def __eq__(self, other):
  144. """Implement the ``==`` operator.
  145. In a column context, produces the clause ``a = b``.
  146. If the target is ``None``, produces ``a IS NULL``.
  147. """
  148. return self.operate(eq, other)
  149. def __ne__(self, other):
  150. """Implement the ``!=`` operator.
  151. In a column context, produces the clause ``a != b``.
  152. If the target is ``None``, produces ``a IS NOT NULL``.
  153. """
  154. return self.operate(ne, other)
  155. def __gt__(self, other):
  156. """Implement the ``>`` operator.
  157. In a column context, produces the clause ``a > b``.
  158. """
  159. return self.operate(gt, other)
  160. def __ge__(self, other):
  161. """Implement the ``>=`` operator.
  162. In a column context, produces the clause ``a >= b``.
  163. """
  164. return self.operate(ge, other)
  165. def __neg__(self):
  166. """Implement the ``-`` operator.
  167. In a column context, produces the clause ``-a``.
  168. """
  169. return self.operate(neg)
  170. def concat(self, other):
  171. """Implement the 'concat' operator.
  172. In a column context, produces the clause ``a || b``,
  173. or uses the ``concat()`` operator on MySQL.
  174. """
  175. return self.operate(concat_op, other)
  176. def like(self, other, escape=None):
  177. """Implement the ``like`` operator.
  178. In a column context, produces the clause ``a LIKE other``.
  179. """
  180. return self.operate(like_op, other, escape=escape)
  181. def ilike(self, other, escape=None):
  182. """Implement the ``ilike`` operator.
  183. In a column context, produces the clause ``a ILIKE other``.
  184. """
  185. return self.operate(ilike_op, other, escape=escape)
  186. def in_(self, other):
  187. """Implement the ``in`` operator.
  188. In a column context, produces the clause ``a IN other``.
  189. "other" may be a tuple/list of column expressions,
  190. or a :func:`~.expression.select` construct.
  191. """
  192. return self.operate(in_op, other)
  193. def startswith(self, other, **kwargs):
  194. """Implement the ``startwith`` operator.
  195. In a column context, produces the clause ``LIKE '<other>%'``
  196. """
  197. return self.operate(startswith_op, other, **kwargs)
  198. def endswith(self, other, **kwargs):
  199. """Implement the 'endswith' operator.
  200. In a column context, produces the clause ``LIKE '%<other>'``
  201. """
  202. return self.operate(endswith_op, other, **kwargs)
  203. def contains(self, other, **kwargs):
  204. """Implement the 'contains' operator.
  205. In a column context, produces the clause ``LIKE '%<other>%'``
  206. """
  207. return self.operate(contains_op, other, **kwargs)
  208. def match(self, other, **kwargs):
  209. """Implements the 'match' operator.
  210. In a column context, this produces a MATCH clause, i.e.
  211. ``MATCH '<other>'``. The allowed contents of ``other``
  212. are database backend specific.
  213. """
  214. return self.operate(match_op, other, **kwargs)
  215. def desc(self):
  216. """Produce a :func:`~.expression.desc` clause against the
  217. parent object."""
  218. return self.operate(desc_op)
  219. def asc(self):
  220. """Produce a :func:`~.expression.asc` clause against the
  221. parent object."""
  222. return self.operate(asc_op)
  223. def nullsfirst(self):
  224. """Produce a :func:`~.expression.nullsfirst` clause against the
  225. parent object."""
  226. return self.operate(nullsfirst_op)
  227. def nullslast(self):
  228. """Produce a :func:`~.expression.nullslast` clause against the
  229. parent object."""
  230. return self.operate(nullslast_op)
  231. def collate(self, collation):
  232. """Produce a :func:`~.expression.collate` clause against
  233. the parent object, given the collation string."""
  234. return self.operate(collate, collation)
  235. def __radd__(self, other):
  236. """Implement the ``+`` operator in reverse.
  237. See :meth:`__add__`.
  238. """
  239. return self.reverse_operate(add, other)
  240. def __rsub__(self, other):
  241. """Implement the ``-`` operator in reverse.
  242. See :meth:`__sub__`.
  243. """
  244. return self.reverse_operate(sub, other)
  245. def __rmul__(self, other):
  246. """Implement the ``*`` operator in reverse.
  247. See :meth:`__mul__`.
  248. """
  249. return self.reverse_operate(mul, other)
  250. def __rdiv__(self, other):
  251. """Implement the ``/`` operator in reverse.
  252. See :meth:`__div__`.
  253. """
  254. return self.reverse_operate(div, other)
  255. def between(self, cleft, cright):
  256. """Produce a :func:`~.expression.between` clause against
  257. the parent object, given the lower and upper range."""
  258. return self.operate(between_op, cleft, cright)
  259. def distinct(self):
  260. """Produce a :func:`~.expression.distinct` clause against the parent object."""
  261. return self.operate(distinct_op)
  262. def __add__(self, other):
  263. """Implement the ``+`` operator.
  264. In a column context, produces the clause ``a + b``
  265. if the parent object has non-string affinity.
  266. If the parent object has a string affinity,
  267. produces the concatenation operator, ``a || b`` -
  268. see :meth:`concat`.
  269. """
  270. return self.operate(add, other)
  271. def __sub__(self, other):
  272. """Implement the ``-`` operator.
  273. In a column context, produces the clause ``a - b``.
  274. """
  275. return self.operate(sub, other)
  276. def __mul__(self, other):
  277. """Implement the ``*`` operator.
  278. In a column context, produces the clause ``a * b``.
  279. """
  280. return self.operate(mul, other)
  281. def __div__(self, other):
  282. """Implement the ``/`` operator.
  283. In a column context, produces the clause ``a / b``.
  284. """
  285. return self.operate(div, other)
  286. def __mod__(self, other):
  287. """Implement the ``%`` operator.
  288. In a column context, produces the clause ``a % b``.
  289. """
  290. return self.operate(mod, other)
  291. def __truediv__(self, other):
  292. """Implement the ``//`` operator.
  293. In a column context, produces the clause ``a / b``.
  294. """
  295. return self.operate(truediv, other)
  296. def __rtruediv__(self, other):
  297. """Implement the ``//`` operator in reverse.
  298. See :meth:`__truediv__`.
  299. """
  300. return self.reverse_operate(truediv, other)
  301. def from_():
  302. raise NotImplementedError()
  303. def as_():
  304. raise NotImplementedError()
  305. def exists():
  306. raise NotImplementedError()
  307. def is_(a, b):
  308. return a.is_(b)
  309. def isnot(a, b):
  310. return a.isnot(b)
  311. def collate(a, b):
  312. return a.collate(b)
  313. def op(a, opstring, b):
  314. return a.op(opstring)(b)
  315. def like_op(a, b, escape=None):
  316. return a.like(b, escape=escape)
  317. def notlike_op(a, b, escape=None):
  318. raise NotImplementedError()
  319. def ilike_op(a, b, escape=None):
  320. return a.ilike(b, escape=escape)
  321. def notilike_op(a, b, escape=None):
  322. raise NotImplementedError()
  323. def between_op(a, b, c):
  324. return a.between(b, c)
  325. def in_op(a, b):
  326. return a.in_(b)
  327. def notin_op(a, b):
  328. raise NotImplementedError()
  329. def distinct_op(a):
  330. return a.distinct()
  331. def startswith_op(a, b, escape=None):
  332. return a.startswith(b, escape=escape)
  333. def endswith_op(a, b, escape=None):
  334. return a.endswith(b, escape=escape)
  335. def contains_op(a, b, escape=None):
  336. return a.contains(b, escape=escape)
  337. def match_op(a, b):
  338. return a.match(b)
  339. def comma_op(a, b):
  340. raise NotImplementedError()
  341. def concat_op(a, b):
  342. return a.concat(b)
  343. def desc_op(a):
  344. return a.desc()
  345. def asc_op(a):
  346. return a.asc()
  347. def nullsfirst_op(a):
  348. return a.nullsfirst()
  349. def nullslast_op(a):
  350. return a.nullslast()
  351. _commutative = set([eq, ne, add, mul])
  352. def is_commutative(op):
  353. return op in _commutative
  354. def is_ordering_modifier(op):
  355. return op in (asc_op, desc_op,
  356. nullsfirst_op, nullslast_op)
  357. _associative = _commutative.union([concat_op, and_, or_])
  358. _smallest = symbol('_smallest')
  359. _largest = symbol('_largest')
  360. _PRECEDENCE = {
  361. from_: 15,
  362. mul: 7,
  363. truediv: 7,
  364. # Py2K
  365. div: 7,
  366. # end Py2K
  367. mod: 7,
  368. neg: 7,
  369. add: 6,
  370. sub: 6,
  371. concat_op: 6,
  372. match_op: 6,
  373. ilike_op: 5,
  374. notilike_op: 5,
  375. like_op: 5,
  376. notlike_op: 5,
  377. in_op: 5,
  378. notin_op: 5,
  379. is_: 5,
  380. isnot: 5,
  381. eq: 5,
  382. ne: 5,
  383. gt: 5,
  384. lt: 5,
  385. ge: 5,
  386. le: 5,
  387. between_op: 5,
  388. distinct_op: 5,
  389. inv: 5,
  390. and_: 3,
  391. or_: 2,
  392. comma_op: -1,
  393. collate: 7,
  394. as_: -1,
  395. exists: 0,
  396. _smallest: -1000,
  397. _largest: 1000
  398. }
  399. def is_precedent(operator, against):
  400. if operator is against and operator in _associative:
  401. return False
  402. else:
  403. return (_PRECEDENCE.get(operator, _PRECEDENCE[_smallest]) <=
  404. _PRECEDENCE.get(against, _PRECEDENCE[_largest]))