Opened 7 years ago

Last modified 5 years ago

#28643 closed New feature

Complete the ORM Function Library — at Version 8

Reported by: Matthew Pava Owned by: JunyiJ
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: josh.smeaton@…, Mariusz Felisiak, Shai Berger, Adam Johnson, Thomas Lagae Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Mariusz Felisiak)

I was surprised to learn that we didn't have a StrIndex function until version 2, and yet we had Substr since at least version 1.8. I wonder how users were using Substr without also finding a use for StrIndex this whole time. Anyway, since we seem to be adding these functions one at a time, why don't we work on trying to get the built-ins implemented in one sweep instead?

We may even want to split the documentation page (https://docs.djangoproject.com/en/dev/ref/models/database-functions/) into further categories with String functions and Numeric functions.

This is just a sample checklist. There are probably several more that I have missed. These functions are available directly out of the box with PostgreSQL.

String functions not yet implemented:
ASCII(): Returns numeric value of left-most character
CHR(): Character with the given code.
LEFT(): Returns the leftmost number of characters as specified
LPAD(): Returns the string argument, left-padded with the specified string
MD5(): Calculates the MD5 hash of string, returning the result in hexadecimal
REPEAT(): Repeats a string the specified number of times
REPLACE(): Replaces occurrences of a specified string
REVERSE(): Reverse the characters in a string
RIGHT(): Returns the specified rightmost number of characters
RPAD(): Appends string the specified number of times
LTRIM(): Removes leading spaces (PR #9220)
RTRIM(): Removes trailing spaces (PR #9220)
TRIM(): Removes leading and trailing spaces (PR #9220)

Numeric functions:
ABS(): Returns the absolute value.
ACOS(): Returns the arccosine.
ASIN(): Returns the arcsine.
ATAN(): Returns the arctangent.
ATAN2(): Returns the arctangent of the two variables passed to it.
CEILING(): Returns the smallest integer value that is not less than a numeric expression
COS(): Returns the cosine expressed in radians.
COT(): Returns the cotangent.
DEGREES(): Returns a numeric expression converted from radians to degrees.
EXP(): Returns the base of the natural logarithm (e) raised to the power of a numeric expression.
FLOOR(): Returns the largest integer value that is not greater than a numeric expression.
LOG(): Returns the natural logarithm of a numeric expression.
MOD(): Returns the remainder of one expression by diving by another expression.
PI(): Returns the value of pi
POWER(): Returns the value of one expression raised to the power of another expression
RADIANS(): Returns the value of an expression converted from degrees to radians.
ROUND(): Returns a numeric expression rounded to an integer. Can be used to round an expression to a number of decimal points
SIN(): Returns the sine given in radians.
SQRT(): Returns the square root.
TAN(): Returns the tangent expressed in radians.

Change History (8)

comment:1 by Josh Smeaton, 7 years ago

I had hoped that the 3rd party community would take care of providing "Function Packs" for each of the backends. But functions are fairly easy to create in your own project if you need them so I guess few people have bothered to group them into a distributable package.

I would prefer that the django ecosystem had a standard group of function expressions that can be used across backends, rather than a bunch of similar but not quite the same implementations. Then 3rd party libraries can depend on the known good versions and everyone is better off. Since the community hasn't seemed to provide such a library (that I'm aware of), I think it's fine for Django to do so.

Splitting the module up into string/numeric/date types sounds fine. Let's take inspiration from postgres and other db vendor docs so navigating them is familiar. Let's begin with functions that have standard support across our 4 backends, then look into what's left over. If we can approximate support by combining other functions we can do that. Otherwise if a particular function only has support for one or two backends we can consider ignoring it or implementing in a contrib module.

comment:2 by Josh Smeaton, 7 years ago

Cc: josh.smeaton@… added
Triage Stage: UnreviewedAccepted

comment:3 by Mariusz Felisiak, 7 years ago

Cc: Mariusz Felisiak added

comment:4 by JunyiJ, 7 years ago

Owner: changed from nobody to JunyiJ
Status: newassigned

comment:5 by Josh Smeaton, 7 years ago

For whoever wants to begin here, I think a good plan of attack will be a PR per function or per a small set of functions. Then the commit message would be something like "Refs #28643 -- Added X, Y, Z functions".

That way we can get through smaller pieces at a time, without such a large burden being placed on any one individual. We could also get some newer contributors to help in this way. Each function on its own should be a relatively easy thing to implement. A higher level task of re-organising the layout into functions/string functions/number may be helpful to get the ticket rolling.

comment:6 by Matthew Pava, 7 years ago

I did find this third-party utility that handles specific PostgreSQL functions. I wonder if there are other backends that they could be ported to.
https://github.com/hypertrack/django-pg-utils

And I also wonder how all of this connects with specific PostgreSQL aggregate functions already builtin to Django:
https://docs.djangoproject.com/en/1.11/ref/contrib/postgres/aggregates/

in reply to:  6 comment:7 by Mads Jensen, 7 years ago

Replying to Matthew Pava:

I did find this third-party utility that handles specific PostgreSQL functions. I wonder if there are other backends that they could be ported to.
https://github.com/hypertrack/django-pg-utils

From a quick look, these things are already supported by Django.

comment:8 by Mariusz Felisiak, 7 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top