1from __future__ import annotations
  2
  3from typing import TYPE_CHECKING, Any
  4
  5from plain.models.expressions import Func
  6from plain.models.fields import Field
  7from plain.models.functions.mixins import (
  8    FixDecimalInputMixin,
  9    NumericOutputFieldMixin,
 10)
 11from plain.models.lookups import Transform
 12
 13if TYPE_CHECKING:
 14    pass
 15
 16
 17class Abs(Transform):
 18    function = "ABS"
 19    lookup_name = "abs"
 20
 21
 22class ACos(NumericOutputFieldMixin, Transform):
 23    function = "ACOS"
 24    lookup_name = "acos"
 25
 26
 27class ASin(NumericOutputFieldMixin, Transform):
 28    function = "ASIN"
 29    lookup_name = "asin"
 30
 31
 32class ATan(NumericOutputFieldMixin, Transform):
 33    function = "ATAN"
 34    lookup_name = "atan"
 35
 36
 37class ATan2(NumericOutputFieldMixin, Func):
 38    function = "ATAN2"
 39    arity = 2
 40
 41
 42class Ceil(Transform):
 43    function = "CEILING"
 44    lookup_name = "ceil"
 45
 46
 47class Cos(NumericOutputFieldMixin, Transform):
 48    function = "COS"
 49    lookup_name = "cos"
 50
 51
 52class Cot(NumericOutputFieldMixin, Transform):
 53    function = "COT"
 54    lookup_name = "cot"
 55
 56
 57class Degrees(NumericOutputFieldMixin, Transform):
 58    function = "DEGREES"
 59    lookup_name = "degrees"
 60
 61
 62class Exp(NumericOutputFieldMixin, Transform):
 63    function = "EXP"
 64    lookup_name = "exp"
 65
 66
 67class Floor(Transform):
 68    function = "FLOOR"
 69    lookup_name = "floor"
 70
 71
 72class Ln(NumericOutputFieldMixin, Transform):
 73    function = "LN"
 74    lookup_name = "ln"
 75
 76
 77class Log(FixDecimalInputMixin, NumericOutputFieldMixin, Func):
 78    function = "LOG"
 79    arity = 2
 80
 81
 82class Mod(FixDecimalInputMixin, NumericOutputFieldMixin, Func):
 83    function = "MOD"
 84    arity = 2
 85
 86
 87class Pi(NumericOutputFieldMixin, Func):
 88    function = "PI"
 89    arity = 0
 90
 91
 92class Power(NumericOutputFieldMixin, Func):
 93    function = "POWER"
 94    arity = 2
 95
 96
 97class Radians(NumericOutputFieldMixin, Transform):
 98    function = "RADIANS"
 99    lookup_name = "radians"
100
101
102class Random(NumericOutputFieldMixin, Func):
103    function = "RANDOM"
104    arity = 0
105
106    def get_group_by_cols(self) -> list[Any]:
107        return []
108
109
110class Round(FixDecimalInputMixin, Transform):
111    function = "ROUND"
112    lookup_name = "round"
113    arity = None  # Override Transform's arity=1 to enable passing precision.
114
115    def __init__(self, expression: Any, precision: int = 0, **extra: Any) -> None:
116        super().__init__(expression, precision, **extra)
117
118    def _resolve_output_field(self) -> Field:
119        source = self.get_source_expressions()[0]
120        return source.output_field
121
122
123class Sign(Transform):
124    function = "SIGN"
125    lookup_name = "sign"
126
127
128class Sin(NumericOutputFieldMixin, Transform):
129    function = "SIN"
130    lookup_name = "sin"
131
132
133class Sqrt(NumericOutputFieldMixin, Transform):
134    function = "SQRT"
135    lookup_name = "sqrt"
136
137
138class Tan(NumericOutputFieldMixin, Transform):
139    function = "TAN"
140    lookup_name = "tan"