Skip to content

Instantly share code, notes, and snippets.

@jarshwah
Created October 12, 2015 00:16
Show Gist options
  • Save jarshwah/9dcffab744ed8d48993e to your computer and use it in GitHub Desktop.
Save jarshwah/9dcffab744ed8d48993e to your computer and use it in GitHub Desktop.
ConcatPair.coalesce() idempotent
diff --git a/django/db/models/functions.py b/django/db/models/functions.py
index ac24aa7..8139ec0 100644
--- a/django/db/models/functions.py
+++ b/django/db/models/functions.py
@@ -44,8 +44,12 @@ class ConcatPair(Func):
def as_sqlite(self, compiler, connection):
self.arg_joiner = ' || '
self.template = '%(expressions)s'
- self.coalesce()
- return super(ConcatPair, self).as_sql(compiler, connection)
+ original = self.get_source_expressions()
+ coalesced = self.coalesce()
+ self.set_source_expressions(coalesced)
+ sql, params = super(ConcatPair, self).as_sql(compiler, connection)
+ self.set_source_expressions(original)
+ return sql, params
def as_mysql(self, compiler, connection):
# Use CONCAT_WS with an empty separator so that NULLs are ignored.
@@ -55,9 +59,9 @@ class ConcatPair(Func):
def coalesce(self):
# null on either side results in null for expression, wrap with coalesce
- expressions = [
- Coalesce(expression, Value('')) for expression in self.get_source_expressions()]
- self.set_source_expressions(expressions)
+ return [
+ Coalesce(expression, Value('')) for expression in self.get_source_expressions()
+ ]
diff --git a/django/db/models/functions.py b/django/db/models/functions.py
index ac24aa7..f560643 100644
--- a/django/db/models/functions.py
+++ b/django/db/models/functions.py
@@ -42,10 +42,10 @@ class ConcatPair(Func):
super(ConcatPair, self).__init__(left, right, **extra)
def as_sqlite(self, compiler, connection):
- self.arg_joiner = ' || '
- self.template = '%(expressions)s'
- self.coalesce()
- return super(ConcatPair, self).as_sql(compiler, connection)
+ coalesced = self.coalesce()
+ coalesced.arg_joiner = ' || '
+ coalesced.template = '%(expressions)s'
+ return super(ConcatPair, coalesced).as_sql(compiler, connection)
def as_mysql(self, compiler, connection):
# Use CONCAT_WS with an empty separator so that NULLs are ignored.
@@ -55,9 +55,11 @@ class ConcatPair(Func):
def coalesce(self):
# null on either side results in null for expression, wrap with coalesce
+ c = self.copy()
expressions = [
- Coalesce(expression, Value('')) for expression in self.get_source_expressions()]
- self.set_source_expressions(expressions)
+ Coalesce(expression, Value('')) for expression in c.get_source_expressions()]
+ c.set_source_expressions(expressions)
+ return c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment