Loading django/db/backends/base/features.py +4 −0 Original line number Diff line number Diff line Loading @@ -208,6 +208,10 @@ class BaseDatabaseFeatures(object): # Does the backend support "select for update" queries with limit (and offset)? supports_select_for_update_with_limit = True # Does the backend ignore null expressions in GREATEST and LEAST queries unless # every expression is null? greatest_least_ignores_nulls = False def __init__(self, connection): self.connection = connection Loading django/db/backends/postgresql_psycopg2/features.py +1 −0 Original line number Diff line number Diff line Loading @@ -27,3 +27,4 @@ class DatabaseFeatures(BaseDatabaseFeatures): closed_cursor_error_class = InterfaceError has_case_insensitive_like = False requires_sqlparse_for_splitting = False greatest_least_ignores_nulls = True django/db/models/functions.py +42 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,48 @@ class Concat(Func): return ConcatPair(expressions[0], self._paired(expressions[1:])) class Greatest(Func): """ Chooses the maximum expression and returns it. If any expression is null the return value is database-specific: On Postgres, the maximum not-null expression is returned. On MySQL, Oracle and SQLite, if any expression is null, null is returned. """ function = 'GREATEST' def __init__(self, *expressions, **extra): if len(expressions) < 2: raise ValueError('Greatest must take at least two expressions') super(Greatest, self).__init__(*expressions, **extra) def as_sqlite(self, compiler, connection): """Use the MAX function on SQLite.""" return super(Greatest, self).as_sql(compiler, connection, function='MAX') class Least(Func): """ Chooses the minimum expression and returns it. If any expression is null the return value is database-specific: On Postgres, the minimum not-null expression is returned. On MySQL, Oracle and SQLite, if any expression is null, null is returned. """ function = 'LEAST' def __init__(self, *expressions, **extra): if len(expressions) < 2: raise ValueError('Least must take at least two expressions') super(Least, self).__init__(*expressions, **extra) def as_sqlite(self, compiler, connection): """Use the MIN function on SQLite.""" return super(Least, self).as_sql(compiler, connection, function='MIN') class Length(Func): """Returns the number of characters in the expression""" function = 'LENGTH' Loading docs/ref/models/database-functions.txt +68 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,74 @@ Usage example:: >>> print(author.screen_name) Margaret Smith (Maggie) Greatest -------- .. versionadded:: 1.9 .. class:: Greatest(*expressions, **extra) Accepts a list of at least two field names or expressions and returns the greatest value. Each argument must be of a similar type, so mixing text and numbers will result in a database error. Usage example:: class Blog(models.Model): body = models.TextField() modified = models.DateTimeField(auto_now=True) class Comment(models.Model): body = models.TextField() modified = models.DateTimeField(auto_now=True) blog = models.ForeignKey(Blog) >>> from django.db.models.functions import Greatest >>> blog = Blog.objects.create(body='Greatest is the best.') >>> comment = Comment.objects.create(body='No, Least is better.', blog=blog) >>> comments = Comment.objects.annotate(last_updated=Greatest('modified', 'blog__modified')) >>> annotated_comment = comments.get() ``annotated_comment.last_updated`` will be the most recent of ``blog.modified`` and ``comment.modified``. .. warning:: The behavior of ``Greatest`` when one or more expression may be ``null`` varies between databases: - PostgreSQL: ``Greatest`` will return the largest non-null expression, or ``null`` if all expressions are ``null``. - SQLite, Oracle and MySQL: If any expression is ``null``, ``Greatest`` will return ``null``. The PostgreSQL behavior can be emulated using ``Coalesce`` if you know a sensible minimum value to provide as a default. Least -------- .. versionadded:: 1.9 .. class:: Least(*expressions, **extra) Accepts a list of at least two field names or expressions and returns the least value. Each argument must be of a similar type, so mixing text and numbers will result in a database error. .. warning:: The behavior of ``Least`` when one or more expression may be ``null`` varies between databases: - PostgreSQL: ``Least`` will return the smallest non-null expression, or ``null`` if all expressions are ``null``. - SQLite, Oracle and MySQL: If any expression is ``null``, ``Least`` will return ``null``. The PostgreSQL behavior can be emulated using ``Coalesce`` if you know a sensible maximum value to provide as a default. Length ------ Loading docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,9 @@ Models * Added the :lookup:`date` lookup to :class:`~django.db.models.DateTimeField` to allow querying the field by only the date portion. * Added the :class:`~django.db.models.functions.Greatest` and :class:`~django.db.models.functions.Least` database functions. * Added the :class:`~django.db.models.functions.Now` database function, which returns the current date and time. Loading Loading
django/db/backends/base/features.py +4 −0 Original line number Diff line number Diff line Loading @@ -208,6 +208,10 @@ class BaseDatabaseFeatures(object): # Does the backend support "select for update" queries with limit (and offset)? supports_select_for_update_with_limit = True # Does the backend ignore null expressions in GREATEST and LEAST queries unless # every expression is null? greatest_least_ignores_nulls = False def __init__(self, connection): self.connection = connection Loading
django/db/backends/postgresql_psycopg2/features.py +1 −0 Original line number Diff line number Diff line Loading @@ -27,3 +27,4 @@ class DatabaseFeatures(BaseDatabaseFeatures): closed_cursor_error_class = InterfaceError has_case_insensitive_like = False requires_sqlparse_for_splitting = False greatest_least_ignores_nulls = True
django/db/models/functions.py +42 −0 Original line number Diff line number Diff line Loading @@ -83,6 +83,48 @@ class Concat(Func): return ConcatPair(expressions[0], self._paired(expressions[1:])) class Greatest(Func): """ Chooses the maximum expression and returns it. If any expression is null the return value is database-specific: On Postgres, the maximum not-null expression is returned. On MySQL, Oracle and SQLite, if any expression is null, null is returned. """ function = 'GREATEST' def __init__(self, *expressions, **extra): if len(expressions) < 2: raise ValueError('Greatest must take at least two expressions') super(Greatest, self).__init__(*expressions, **extra) def as_sqlite(self, compiler, connection): """Use the MAX function on SQLite.""" return super(Greatest, self).as_sql(compiler, connection, function='MAX') class Least(Func): """ Chooses the minimum expression and returns it. If any expression is null the return value is database-specific: On Postgres, the minimum not-null expression is returned. On MySQL, Oracle and SQLite, if any expression is null, null is returned. """ function = 'LEAST' def __init__(self, *expressions, **extra): if len(expressions) < 2: raise ValueError('Least must take at least two expressions') super(Least, self).__init__(*expressions, **extra) def as_sqlite(self, compiler, connection): """Use the MIN function on SQLite.""" return super(Least, self).as_sql(compiler, connection, function='MIN') class Length(Func): """Returns the number of characters in the expression""" function = 'LENGTH' Loading
docs/ref/models/database-functions.txt +68 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,74 @@ Usage example:: >>> print(author.screen_name) Margaret Smith (Maggie) Greatest -------- .. versionadded:: 1.9 .. class:: Greatest(*expressions, **extra) Accepts a list of at least two field names or expressions and returns the greatest value. Each argument must be of a similar type, so mixing text and numbers will result in a database error. Usage example:: class Blog(models.Model): body = models.TextField() modified = models.DateTimeField(auto_now=True) class Comment(models.Model): body = models.TextField() modified = models.DateTimeField(auto_now=True) blog = models.ForeignKey(Blog) >>> from django.db.models.functions import Greatest >>> blog = Blog.objects.create(body='Greatest is the best.') >>> comment = Comment.objects.create(body='No, Least is better.', blog=blog) >>> comments = Comment.objects.annotate(last_updated=Greatest('modified', 'blog__modified')) >>> annotated_comment = comments.get() ``annotated_comment.last_updated`` will be the most recent of ``blog.modified`` and ``comment.modified``. .. warning:: The behavior of ``Greatest`` when one or more expression may be ``null`` varies between databases: - PostgreSQL: ``Greatest`` will return the largest non-null expression, or ``null`` if all expressions are ``null``. - SQLite, Oracle and MySQL: If any expression is ``null``, ``Greatest`` will return ``null``. The PostgreSQL behavior can be emulated using ``Coalesce`` if you know a sensible minimum value to provide as a default. Least -------- .. versionadded:: 1.9 .. class:: Least(*expressions, **extra) Accepts a list of at least two field names or expressions and returns the least value. Each argument must be of a similar type, so mixing text and numbers will result in a database error. .. warning:: The behavior of ``Least`` when one or more expression may be ``null`` varies between databases: - PostgreSQL: ``Least`` will return the smallest non-null expression, or ``null`` if all expressions are ``null``. - SQLite, Oracle and MySQL: If any expression is ``null``, ``Least`` will return ``null``. The PostgreSQL behavior can be emulated using ``Coalesce`` if you know a sensible maximum value to provide as a default. Length ------ Loading
docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,9 @@ Models * Added the :lookup:`date` lookup to :class:`~django.db.models.DateTimeField` to allow querying the field by only the date portion. * Added the :class:`~django.db.models.functions.Greatest` and :class:`~django.db.models.functions.Least` database functions. * Added the :class:`~django.db.models.functions.Now` database function, which returns the current date and time. Loading