summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
authormike bayer <mike_mp@zzzcomputing.com>2016-06-06 15:57:06 -0400
committerGerrit Code Review <gerrit2@ln3.zzzcomputing.com>2016-06-06 15:57:06 -0400
commit2860ae6c4927dbbca9316c81ce15cbbb7df49750 (patch)
tree1a4125880b200c9b4fe2ce2d5d3f6a5332f4c7b6 /lib/sqlalchemy/sql
parentbc4c6c44af6681ade49892d46dadb04f141f5450 (diff)
parent3351f5f93ca1968653becbed7f1ddef7afb96077 (diff)
downloadsqlalchemy-2860ae6c4927dbbca9316c81ce15cbbb7df49750.tar.gz
Merge "Add IS (NOT) DISTINCT FROM operators"
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/compiler.py2
-rw-r--r--lib/sqlalchemy/sql/default_comparator.py13
-rw-r--r--lib/sqlalchemy/sql/operators.py33
3 files changed, 46 insertions, 2 deletions
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 3d2f02006..144f2aa47 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -81,6 +81,8 @@ OPERATORS = {
operators.gt: ' > ',
operators.ge: ' >= ',
operators.eq: ' = ',
+ operators.is_distinct_from: ' IS DISTINCT FROM ',
+ operators.isnot_distinct_from: ' IS NOT DISTINCT FROM ',
operators.concat_op: ' || ',
operators.match_op: ' MATCH ',
operators.notmatch_op: ' NOT MATCH ',
diff --git a/lib/sqlalchemy/sql/default_comparator.py b/lib/sqlalchemy/sql/default_comparator.py
index 1bb1c344c..7630a9821 100644
--- a/lib/sqlalchemy/sql/default_comparator.py
+++ b/lib/sqlalchemy/sql/default_comparator.py
@@ -39,6 +39,12 @@ def _boolean_compare(expr, op, obj, negate=None, reverse=False,
op,
type_=result_type,
negate=negate, modifiers=kwargs)
+ elif op in (operators.is_distinct_from, operators.isnot_distinct_from):
+ return BinaryExpression(expr,
+ _literal_as_text(obj),
+ op,
+ type_=result_type,
+ negate=negate, modifiers=kwargs)
else:
# all other None/True/False uses IS, IS NOT
if op in (operators.eq, operators.is_):
@@ -51,8 +57,9 @@ def _boolean_compare(expr, op, obj, negate=None, reverse=False,
negate=operators.is_)
else:
raise exc.ArgumentError(
- "Only '=', '!=', 'is_()', 'isnot()' operators can "
- "be used with None/True/False")
+ "Only '=', '!=', 'is_()', 'isnot()', "
+ "'is_distinct_from()', 'isnot_distinct_from()' "
+ "operators can be used with None/True/False")
else:
obj = _check_literal(expr, op, obj)
@@ -249,6 +256,8 @@ operator_lookup = {
"gt": (_boolean_compare, operators.le),
"ge": (_boolean_compare, operators.lt),
"eq": (_boolean_compare, operators.ne),
+ "is_distinct_from": (_boolean_compare, operators.isnot_distinct_from),
+ "isnot_distinct_from": (_boolean_compare, operators.is_distinct_from),
"like_op": (_boolean_compare, operators.notlike_op),
"ilike_op": (_boolean_compare, operators.notilike_op),
"notlike_op": (_boolean_compare, operators.like_op),
diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py
index 80f08a97c..bf470710d 100644
--- a/lib/sqlalchemy/sql/operators.py
+++ b/lib/sqlalchemy/sql/operators.py
@@ -311,6 +311,28 @@ class ColumnOperators(Operators):
"""
return self.operate(ne, other)
+ def is_distinct_from(self, other):
+ """Implement the ``IS DISTINCT FROM`` operator.
+
+ Renders "a IS DISTINCT FROM b" on most platforms;
+ on some such as SQLite may render "a IS NOT b".
+
+ .. versionadded:: 1.1
+
+ """
+ return self.operate(is_distinct_from, other)
+
+ def isnot_distinct_from(self, other):
+ """Implement the ``IS NOT DISTINCT FROM`` operator.
+
+ Renders "a IS NOT DISTINCT FROM b" on most platforms;
+ on some such as SQLite may render "a IS b".
+
+ .. versionadded:: 1.1
+
+ """
+ return self.operate(isnot_distinct_from, other)
+
def __gt__(self, other):
"""Implement the ``>`` operator.
@@ -722,6 +744,15 @@ def istrue(a):
def isfalse(a):
raise NotImplementedError()
+
+def is_distinct_from(a, b):
+ return a.is_distinct_from(b)
+
+
+def isnot_distinct_from(a, b):
+ return a.isnot_distinct_from(b)
+
+
def is_(a, b):
return a.is_(b)
@@ -931,6 +962,8 @@ _PRECEDENCE = {
eq: 5,
ne: 5,
+ is_distinct_from: 5,
+ isnot_distinct_from: 5,
gt: 5,
lt: 5,
ge: 5,