diff options
| author | Hannes Ljungberg <hannes@5monkeys.se> | 2020-03-20 23:08:32 +0100 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-03-25 10:16:30 +0100 |
| commit | f3da09df0f4147223ab76a00a841586ccf11005d (patch) | |
| tree | e36e8116a5b7abaa453791545a65e3febe3adc87 /django/db | |
| parent | 39e1c88de67ea2035d5ad89cfe00bcd892c0d163 (diff) | |
Fixed #31396 -- Added binary XOR operator to F expressions.
Diffstat (limited to 'django/db')
| -rw-r--r-- | django/db/backends/mysql/operations.py | 3 | ||||
| -rw-r--r-- | django/db/backends/oracle/operations.py | 4 | ||||
| -rw-r--r-- | django/db/backends/sqlite3/base.py | 1 | ||||
| -rw-r--r-- | django/db/backends/sqlite3/operations.py | 2 | ||||
| -rw-r--r-- | django/db/models/expressions.py | 4 |
5 files changed, 12 insertions, 2 deletions
diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index 6aaf5c6295..e9306f03fc 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -240,7 +240,8 @@ class DatabaseOperations(BaseDatabaseOperations): return 'POW(%s)' % ','.join(sub_expressions) # Convert the result to a signed integer since MySQL's binary operators # return an unsigned integer. - elif connector in ('&', '|', '<<'): + elif connector in ('&', '|', '<<', '#'): + connector = '^' if connector == '#' else connector return 'CONVERT(%s, SIGNED)' % connector.join(sub_expressions) elif connector == '>>': lhs, rhs = sub_expressions diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py index 1e59323655..b0b50f7868 100644 --- a/django/db/backends/oracle/operations.py +++ b/django/db/backends/oracle/operations.py @@ -3,7 +3,7 @@ import uuid from functools import lru_cache from django.conf import settings -from django.db import DatabaseError +from django.db import DatabaseError, NotSupportedError from django.db.backends.base.operations import BaseDatabaseOperations from django.db.backends.utils import strip_quotes, truncate_name from django.db.models import AutoField, Exists, ExpressionWrapper @@ -575,6 +575,8 @@ END; return 'FLOOR(%(lhs)s / POWER(2, %(rhs)s))' % {'lhs': lhs, 'rhs': rhs} elif connector == '^': return 'POWER(%s)' % ','.join(sub_expressions) + elif connector == '#': + raise NotSupportedError('Bitwise XOR is not supported in Oracle.') return super().combine_expression(connector, sub_expressions) def _get_no_autofield_sequence_name(self, table): diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index 7b3f90a2fd..fcc9d31b37 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -218,6 +218,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): conn.create_function('ASIN', 1, none_guard(math.asin)) conn.create_function('ATAN', 1, none_guard(math.atan)) conn.create_function('ATAN2', 2, none_guard(math.atan2)) + conn.create_function('BITXOR', 2, none_guard(operator.xor)) conn.create_function('CEILING', 1, none_guard(math.ceil)) conn.create_function('COS', 1, none_guard(math.cos)) conn.create_function('COT', 1, none_guard(lambda x: 1 / math.tan(x))) diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py index 80c32f6fcd..fcc2a06d7a 100644 --- a/django/db/backends/sqlite3/operations.py +++ b/django/db/backends/sqlite3/operations.py @@ -312,6 +312,8 @@ class DatabaseOperations(BaseDatabaseOperations): # function that's registered in connect(). if connector == '^': return 'POWER(%s)' % ','.join(sub_expressions) + elif connector == '#': + return 'BITXOR(%s)' % ','.join(sub_expressions) return super().combine_expression(connector, sub_expressions) def combine_duration_expression(self, connector, sub_expressions): diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 84960d77e1..4753a258f9 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -51,6 +51,7 @@ class Combinable: BITOR = '|' BITLEFTSHIFT = '<<' BITRIGHTSHIFT = '>>' + BITXOR = '#' def _combine(self, other, connector, reversed): if not hasattr(other, 'resolve_expression'): @@ -105,6 +106,9 @@ class Combinable: def bitrightshift(self, other): return self._combine(other, self.BITRIGHTSHIFT, False) + def bitxor(self, other): + return self._combine(other, self.BITXOR, False) + def __or__(self, other): if getattr(self, 'conditional', False) and getattr(other, 'conditional', False): return Q(self) | Q(other) |
