Commit 766afc22 authored by Simon Charette's avatar Simon Charette
Browse files

Fixed #24793 -- Unified temporal difference support.

parent 31098e32
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -64,6 +64,10 @@ class BaseDatabaseFeatures(object):
    # Is there a true datatype for timedeltas?
    has_native_duration_field = False

    # Does the database driver supports same type temporal data subtraction
    # by returning the type used to store duration field?
    supports_temporal_subtraction = False

    # Does the database driver support timedeltas as arguments?
    # This is only relevant when there is a native duration field.
    # Specifically, there is a bug with cx_Oracle:
+7 −0
Original line number Diff line number Diff line
@@ -590,3 +590,10 @@ class BaseDatabaseOperations(object):
        range of the column type bound to the field.
        """
        return self.integer_field_ranges[internal_type]

    def subtract_temporals(self, internal_type, lhs, rhs):
        if self.connection.features.supports_temporal_subtraction:
            lhs_sql, lhs_params = lhs
            rhs_sql, rhs_params = rhs
            return "(%s - %s)" % (lhs_sql, rhs_sql), lhs_params + rhs_params
        raise NotImplementedError("This backend does not support %s subtraction." % internal_type)
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
    atomic_transactions = False
    supports_column_check_constraints = False
    can_clone_databases = True
    supports_temporal_subtraction = True

    @cached_property
    def _mysql_storage_engine(self):
+18 −0
Original line number Diff line number Diff line
@@ -210,3 +210,21 @@ class DatabaseOperations(BaseDatabaseOperations):
        if value is not None:
            value = uuid.UUID(value)
        return value

    def subtract_temporals(self, internal_type, lhs, rhs):
        lhs_sql, lhs_params = lhs
        rhs_sql, rhs_params = rhs
        if self.connection.features.supports_microsecond_precision:
            if internal_type == 'TimeField':
                return (
                    "((TIME_TO_SEC(%(lhs)s) * POW(10, 6) + MICROSECOND(%(lhs)s)) -"
                    " (TIME_TO_SEC(%(rhs)s) * POW(10, 6) + MICROSECOND(%(rhs)s)))"
                ) % {'lhs': lhs_sql, 'rhs': rhs_sql}, lhs_params * 2 + rhs_params * 2
            else:
                return "TIMESTAMPDIFF(MICROSECOND, %s, %s)" % (rhs_sql, lhs_sql), rhs_params + lhs_params
        elif internal_type == 'TimeField':
            return (
                "(TIME_TO_SEC(%s) * POW(10, 6) - TIME_TO_SEC(%s) * POW(10, 6))"
            ) % (lhs_sql, rhs_sql), lhs_params + rhs_params
        else:
            return "(TIMESTAMPDIFF(SECOND, %s, %s) * POW(10, 6))" % (rhs_sql, lhs_sql), rhs_params + lhs_params
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
    uppercases_column_names = True
    # select for update with limit can be achieved on Oracle, but not with the current backend.
    supports_select_for_update_with_limit = False
    supports_temporal_subtraction = True

    def introspected_boolean_field_type(self, field=None, created_separately=False):
        """
Loading