Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.10/site-packages/django/db/models/functions/mixins.py: 33%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

30 statements  

1import sys 

2 

3from django.db.models.fields import DecimalField, FloatField, IntegerField 

4from django.db.models.functions import Cast 

5 

6 

7class FixDecimalInputMixin: 

8 def as_postgresql(self, compiler, connection, **extra_context): 

9 # Cast FloatField to DecimalField as PostgreSQL doesn't support the 

10 # following function signatures: 

11 # - LOG(double, double) 

12 # - MOD(double, double) 

13 output_field = DecimalField(decimal_places=sys.float_info.dig, max_digits=1000) 

14 clone = self.copy() 

15 clone.set_source_expressions( 

16 [ 

17 ( 

18 Cast(expression, output_field) 

19 if isinstance(expression.output_field, FloatField) 

20 else expression 

21 ) 

22 for expression in self.get_source_expressions() 

23 ] 

24 ) 

25 return clone.as_sql(compiler, connection, **extra_context) 

26 

27 

28class FixDurationInputMixin: 

29 def as_mysql(self, compiler, connection, **extra_context): 

30 sql, params = super().as_sql(compiler, connection, **extra_context) 

31 if self.output_field.get_internal_type() == "DurationField": 

32 sql = "CAST(%s AS SIGNED)" % sql 

33 return sql, params 

34 

35 def as_oracle(self, compiler, connection, **extra_context): 

36 if ( 

37 self.output_field.get_internal_type() == "DurationField" 

38 and not connection.features.supports_aggregation_over_interval_types 

39 ): 

40 expression = self.get_source_expressions()[0] 

41 options = self._get_repr_options() 

42 from django.db.backends.oracle.functions import ( 

43 IntervalToSeconds, 

44 SecondsToInterval, 

45 ) 

46 

47 return compiler.compile( 

48 SecondsToInterval( 

49 self.__class__(IntervalToSeconds(expression), **options) 

50 ) 

51 ) 

52 return super().as_sql(compiler, connection, **extra_context) 

53 

54 

55class NumericOutputFieldMixin: 

56 def _resolve_output_field(self): 

57 source_fields = self.get_source_fields() 

58 if any(isinstance(s, DecimalField) for s in source_fields): 

59 return DecimalField() 

60 if any(isinstance(s, IntegerField) for s in source_fields): 

61 return FloatField() 

62 return super()._resolve_output_field() if source_fields else FloatField()