polars_plan/dsl/function_expr/
mod.rs

1#[cfg(feature = "dtype-array")]
2mod array;
3mod binary;
4#[cfg(feature = "bitwise")]
5mod bitwise;
6mod boolean;
7#[cfg(feature = "business")]
8mod business;
9#[cfg(feature = "dtype-categorical")]
10mod cat;
11#[cfg(feature = "cov")]
12mod correlation;
13#[cfg(feature = "temporal")]
14mod datetime;
15mod list;
16mod pow;
17#[cfg(feature = "random")]
18mod random;
19#[cfg(feature = "range")]
20mod range;
21#[cfg(feature = "rolling_window")]
22mod rolling;
23#[cfg(feature = "rolling_window_by")]
24mod rolling_by;
25#[cfg(feature = "strings")]
26mod strings;
27#[cfg(feature = "dtype-struct")]
28mod struct_;
29#[cfg(feature = "trigonometry")]
30mod trigonometry;
31
32use std::fmt::{Display, Formatter};
33use std::hash::{Hash, Hasher};
34
35#[cfg(feature = "dtype-array")]
36pub use array::ArrayFunction;
37#[cfg(feature = "cov")]
38pub use correlation::CorrelationMethod;
39pub use list::ListFunction;
40pub use polars_core::datatypes::ReshapeDimension;
41use polars_core::prelude::*;
42#[cfg(feature = "random")]
43pub use random::RandomMethod;
44#[cfg(feature = "serde")]
45use serde::{Deserialize, Serialize};
46
47pub use self::binary::BinaryFunction;
48#[cfg(feature = "bitwise")]
49pub use self::bitwise::BitwiseFunction;
50pub use self::boolean::BooleanFunction;
51#[cfg(feature = "business")]
52pub use self::business::BusinessFunction;
53#[cfg(feature = "dtype-categorical")]
54pub use self::cat::CategoricalFunction;
55#[cfg(feature = "temporal")]
56pub use self::datetime::TemporalFunction;
57pub use self::pow::PowFunction;
58#[cfg(feature = "range")]
59pub use self::range::RangeFunction;
60#[cfg(feature = "rolling_window")]
61pub use self::rolling::RollingFunction;
62#[cfg(feature = "rolling_window_by")]
63pub use self::rolling_by::RollingFunctionBy;
64#[cfg(feature = "strings")]
65pub use self::strings::StringFunction;
66#[cfg(feature = "dtype-struct")]
67pub use self::struct_::StructFunction;
68#[cfg(feature = "trigonometry")]
69pub use self::trigonometry::TrigonometricFunction;
70use super::*;
71
72#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
73#[cfg_attr(feature = "dsl-schema", derive(schemars::JsonSchema))]
74#[derive(Clone, PartialEq, Debug)]
75pub enum FunctionExpr {
76    // Namespaces
77    #[cfg(feature = "dtype-array")]
78    ArrayExpr(ArrayFunction),
79    BinaryExpr(BinaryFunction),
80    #[cfg(feature = "dtype-categorical")]
81    Categorical(CategoricalFunction),
82    ListExpr(ListFunction),
83    #[cfg(feature = "strings")]
84    StringExpr(StringFunction),
85    #[cfg(feature = "dtype-struct")]
86    StructExpr(StructFunction),
87    #[cfg(feature = "temporal")]
88    TemporalExpr(TemporalFunction),
89    #[cfg(feature = "bitwise")]
90    Bitwise(BitwiseFunction),
91
92    // Other expressions
93    Boolean(BooleanFunction),
94    #[cfg(feature = "business")]
95    Business(BusinessFunction),
96    #[cfg(feature = "abs")]
97    Abs,
98    Negate,
99    #[cfg(feature = "hist")]
100    Hist {
101        bin_count: Option<usize>,
102        include_category: bool,
103        include_breakpoint: bool,
104    },
105    NullCount,
106    Pow(PowFunction),
107    #[cfg(feature = "row_hash")]
108    Hash(u64, u64, u64, u64),
109    #[cfg(feature = "arg_where")]
110    ArgWhere,
111    #[cfg(feature = "index_of")]
112    IndexOf,
113    #[cfg(feature = "search_sorted")]
114    SearchSorted {
115        side: SearchSortedSide,
116        descending: bool,
117    },
118    #[cfg(feature = "range")]
119    Range(RangeFunction),
120    #[cfg(feature = "trigonometry")]
121    Trigonometry(TrigonometricFunction),
122    #[cfg(feature = "trigonometry")]
123    Atan2,
124    #[cfg(feature = "sign")]
125    Sign,
126    FillNull,
127    FillNullWithStrategy(FillNullStrategy),
128    #[cfg(feature = "rolling_window")]
129    RollingExpr(RollingFunction),
130    #[cfg(feature = "rolling_window_by")]
131    RollingExprBy(RollingFunctionBy),
132    ShiftAndFill,
133    Shift,
134    DropNans,
135    DropNulls,
136    #[cfg(feature = "mode")]
137    Mode,
138    #[cfg(feature = "moment")]
139    Skew(bool),
140    #[cfg(feature = "moment")]
141    Kurtosis(bool, bool),
142    #[cfg(feature = "dtype-array")]
143    Reshape(Vec<ReshapeDimension>),
144    #[cfg(feature = "repeat_by")]
145    RepeatBy,
146    ArgUnique,
147    #[cfg(feature = "rank")]
148    Rank {
149        options: RankOptions,
150        seed: Option<u64>,
151    },
152    Repeat,
153    #[cfg(feature = "round_series")]
154    Clip {
155        has_min: bool,
156        has_max: bool,
157    },
158    #[cfg(feature = "dtype-struct")]
159    AsStruct,
160    #[cfg(feature = "top_k")]
161    TopK {
162        descending: bool,
163    },
164    #[cfg(feature = "top_k")]
165    TopKBy {
166        descending: Vec<bool>,
167    },
168    #[cfg(feature = "cum_agg")]
169    CumCount {
170        reverse: bool,
171    },
172    #[cfg(feature = "cum_agg")]
173    CumSum {
174        reverse: bool,
175    },
176    #[cfg(feature = "cum_agg")]
177    CumProd {
178        reverse: bool,
179    },
180    #[cfg(feature = "cum_agg")]
181    CumMin {
182        reverse: bool,
183    },
184    #[cfg(feature = "cum_agg")]
185    CumMax {
186        reverse: bool,
187    },
188    Reverse,
189    #[cfg(feature = "dtype-struct")]
190    ValueCounts {
191        sort: bool,
192        parallel: bool,
193        name: PlSmallStr,
194        normalize: bool,
195    },
196    #[cfg(feature = "unique_counts")]
197    UniqueCounts,
198    #[cfg(feature = "approx_unique")]
199    ApproxNUnique,
200    Coalesce,
201    ShrinkType,
202    #[cfg(feature = "diff")]
203    Diff(NullBehavior),
204    #[cfg(feature = "pct_change")]
205    PctChange,
206    #[cfg(feature = "interpolate")]
207    Interpolate(InterpolationMethod),
208    #[cfg(feature = "interpolate_by")]
209    InterpolateBy,
210    #[cfg(feature = "log")]
211    Entropy {
212        base: f64,
213        normalize: bool,
214    },
215    #[cfg(feature = "log")]
216    Log {
217        base: f64,
218    },
219    #[cfg(feature = "log")]
220    Log1p,
221    #[cfg(feature = "log")]
222    Exp,
223    Unique(bool),
224    #[cfg(feature = "round_series")]
225    Round {
226        decimals: u32,
227        mode: RoundMode,
228    },
229    #[cfg(feature = "round_series")]
230    RoundSF {
231        digits: i32,
232    },
233    #[cfg(feature = "round_series")]
234    Floor,
235    #[cfg(feature = "round_series")]
236    Ceil,
237    UpperBound,
238    LowerBound,
239    ConcatExpr(bool),
240    #[cfg(feature = "cov")]
241    Correlation {
242        method: correlation::CorrelationMethod,
243    },
244    #[cfg(feature = "peaks")]
245    PeakMin,
246    #[cfg(feature = "peaks")]
247    PeakMax,
248    #[cfg(feature = "cutqcut")]
249    Cut {
250        breaks: Vec<f64>,
251        labels: Option<Vec<PlSmallStr>>,
252        left_closed: bool,
253        include_breaks: bool,
254    },
255    #[cfg(feature = "cutqcut")]
256    QCut {
257        probs: Vec<f64>,
258        labels: Option<Vec<PlSmallStr>>,
259        left_closed: bool,
260        allow_duplicates: bool,
261        include_breaks: bool,
262    },
263    #[cfg(feature = "rle")]
264    RLE,
265    #[cfg(feature = "rle")]
266    RLEID,
267    ToPhysical,
268    #[cfg(feature = "random")]
269    Random {
270        method: random::RandomMethod,
271        seed: Option<u64>,
272    },
273    SetSortedFlag(IsSorted),
274    #[cfg(feature = "ffi_plugin")]
275    /// Creating this node is unsafe
276    /// This will lead to calls over FFI.
277    FfiPlugin {
278        flags: FunctionOptions,
279        /// Shared library.
280        lib: PlSmallStr,
281        /// Identifier in the shared lib.
282        symbol: PlSmallStr,
283        /// Pickle serialized keyword arguments.
284        kwargs: Arc<[u8]>,
285    },
286    MaxHorizontal,
287    MinHorizontal,
288    SumHorizontal {
289        ignore_nulls: bool,
290    },
291    MeanHorizontal {
292        ignore_nulls: bool,
293    },
294    #[cfg(feature = "ewma")]
295    EwmMean {
296        options: EWMOptions,
297    },
298    #[cfg(feature = "ewma_by")]
299    EwmMeanBy {
300        half_life: Duration,
301    },
302    #[cfg(feature = "ewma")]
303    EwmStd {
304        options: EWMOptions,
305    },
306    #[cfg(feature = "ewma")]
307    EwmVar {
308        options: EWMOptions,
309    },
310    #[cfg(feature = "replace")]
311    Replace,
312    #[cfg(feature = "replace")]
313    ReplaceStrict {
314        return_dtype: Option<DataTypeExpr>,
315    },
316    GatherEvery {
317        n: usize,
318        offset: usize,
319    },
320    #[cfg(feature = "reinterpret")]
321    Reinterpret(bool),
322    ExtendConstant,
323}
324
325impl Hash for FunctionExpr {
326    fn hash<H: Hasher>(&self, state: &mut H) {
327        std::mem::discriminant(self).hash(state);
328        use FunctionExpr::*;
329        match self {
330            // Namespaces
331            #[cfg(feature = "dtype-array")]
332            ArrayExpr(f) => f.hash(state),
333            BinaryExpr(f) => f.hash(state),
334            #[cfg(feature = "dtype-categorical")]
335            Categorical(f) => f.hash(state),
336            ListExpr(f) => f.hash(state),
337            #[cfg(feature = "strings")]
338            StringExpr(f) => f.hash(state),
339            #[cfg(feature = "dtype-struct")]
340            StructExpr(f) => f.hash(state),
341            #[cfg(feature = "temporal")]
342            TemporalExpr(f) => f.hash(state),
343            #[cfg(feature = "bitwise")]
344            Bitwise(f) => f.hash(state),
345
346            // Other expressions
347            Boolean(f) => f.hash(state),
348            #[cfg(feature = "business")]
349            Business(f) => f.hash(state),
350            Pow(f) => f.hash(state),
351            #[cfg(feature = "index_of")]
352            IndexOf => {},
353            #[cfg(feature = "search_sorted")]
354            SearchSorted { side, descending } => {
355                side.hash(state);
356                descending.hash(state);
357            },
358            #[cfg(feature = "random")]
359            Random { method, .. } => method.hash(state),
360            #[cfg(feature = "cov")]
361            Correlation { method, .. } => method.hash(state),
362            #[cfg(feature = "range")]
363            Range(f) => f.hash(state),
364            #[cfg(feature = "trigonometry")]
365            Trigonometry(f) => f.hash(state),
366            #[cfg(feature = "diff")]
367            Diff(null_behavior) => null_behavior.hash(state),
368            #[cfg(feature = "interpolate")]
369            Interpolate(f) => f.hash(state),
370            #[cfg(feature = "interpolate_by")]
371            InterpolateBy => {},
372            #[cfg(feature = "ffi_plugin")]
373            FfiPlugin {
374                flags: _,
375                lib,
376                symbol,
377                kwargs,
378            } => {
379                kwargs.hash(state);
380                lib.hash(state);
381                symbol.hash(state);
382            },
383            MaxHorizontal
384            | MinHorizontal
385            | SumHorizontal { .. }
386            | MeanHorizontal { .. }
387            | DropNans
388            | DropNulls
389            | Reverse
390            | ArgUnique
391            | Shift
392            | ShiftAndFill => {},
393            #[cfg(feature = "mode")]
394            Mode => {},
395            #[cfg(feature = "abs")]
396            Abs => {},
397            Negate => {},
398            NullCount => {},
399            #[cfg(feature = "arg_where")]
400            ArgWhere => {},
401            #[cfg(feature = "trigonometry")]
402            Atan2 => {},
403            #[cfg(feature = "dtype-struct")]
404            AsStruct => {},
405            #[cfg(feature = "sign")]
406            Sign => {},
407            #[cfg(feature = "row_hash")]
408            Hash(a, b, c, d) => (a, b, c, d).hash(state),
409            FillNull => {},
410            #[cfg(feature = "rolling_window")]
411            RollingExpr(f) => {
412                f.hash(state);
413            },
414            #[cfg(feature = "rolling_window_by")]
415            RollingExprBy(f) => {
416                f.hash(state);
417            },
418            #[cfg(feature = "moment")]
419            Skew(a) => a.hash(state),
420            #[cfg(feature = "moment")]
421            Kurtosis(a, b) => {
422                a.hash(state);
423                b.hash(state);
424            },
425            Repeat => {},
426            #[cfg(feature = "rank")]
427            Rank { options, seed } => {
428                options.hash(state);
429                seed.hash(state);
430            },
431            #[cfg(feature = "round_series")]
432            Clip { has_min, has_max } => {
433                has_min.hash(state);
434                has_max.hash(state);
435            },
436            #[cfg(feature = "top_k")]
437            TopK { descending } => descending.hash(state),
438            #[cfg(feature = "cum_agg")]
439            CumCount { reverse } => reverse.hash(state),
440            #[cfg(feature = "cum_agg")]
441            CumSum { reverse } => reverse.hash(state),
442            #[cfg(feature = "cum_agg")]
443            CumProd { reverse } => reverse.hash(state),
444            #[cfg(feature = "cum_agg")]
445            CumMin { reverse } => reverse.hash(state),
446            #[cfg(feature = "cum_agg")]
447            CumMax { reverse } => reverse.hash(state),
448            #[cfg(feature = "dtype-struct")]
449            ValueCounts {
450                sort,
451                parallel,
452                name,
453                normalize,
454            } => {
455                sort.hash(state);
456                parallel.hash(state);
457                name.hash(state);
458                normalize.hash(state);
459            },
460            #[cfg(feature = "unique_counts")]
461            UniqueCounts => {},
462            #[cfg(feature = "approx_unique")]
463            ApproxNUnique => {},
464            Coalesce => {},
465            ShrinkType => {},
466            #[cfg(feature = "pct_change")]
467            PctChange => {},
468            #[cfg(feature = "log")]
469            Entropy { base, normalize } => {
470                base.to_bits().hash(state);
471                normalize.hash(state);
472            },
473            #[cfg(feature = "log")]
474            Log { base } => base.to_bits().hash(state),
475            #[cfg(feature = "log")]
476            Log1p => {},
477            #[cfg(feature = "log")]
478            Exp => {},
479            Unique(a) => a.hash(state),
480            #[cfg(feature = "round_series")]
481            Round { decimals, mode } => {
482                decimals.hash(state);
483                mode.hash(state);
484            },
485            #[cfg(feature = "round_series")]
486            FunctionExpr::RoundSF { digits } => digits.hash(state),
487            #[cfg(feature = "round_series")]
488            FunctionExpr::Floor => {},
489            #[cfg(feature = "round_series")]
490            Ceil => {},
491            UpperBound => {},
492            LowerBound => {},
493            ConcatExpr(a) => a.hash(state),
494            #[cfg(feature = "peaks")]
495            PeakMin => {},
496            #[cfg(feature = "peaks")]
497            PeakMax => {},
498            #[cfg(feature = "cutqcut")]
499            Cut {
500                breaks,
501                labels,
502                left_closed,
503                include_breaks,
504            } => {
505                let slice = bytemuck::cast_slice::<_, u64>(breaks);
506                slice.hash(state);
507                labels.hash(state);
508                left_closed.hash(state);
509                include_breaks.hash(state);
510            },
511            #[cfg(feature = "dtype-array")]
512            Reshape(dims) => dims.hash(state),
513            #[cfg(feature = "repeat_by")]
514            RepeatBy => {},
515            #[cfg(feature = "cutqcut")]
516            QCut {
517                probs,
518                labels,
519                left_closed,
520                allow_duplicates,
521                include_breaks,
522            } => {
523                let slice = bytemuck::cast_slice::<_, u64>(probs);
524                slice.hash(state);
525                labels.hash(state);
526                left_closed.hash(state);
527                allow_duplicates.hash(state);
528                include_breaks.hash(state);
529            },
530            #[cfg(feature = "rle")]
531            RLE => {},
532            #[cfg(feature = "rle")]
533            RLEID => {},
534            ToPhysical => {},
535            SetSortedFlag(is_sorted) => is_sorted.hash(state),
536            #[cfg(feature = "ewma")]
537            EwmMean { options } => options.hash(state),
538            #[cfg(feature = "ewma_by")]
539            EwmMeanBy { half_life } => (half_life).hash(state),
540            #[cfg(feature = "ewma")]
541            EwmStd { options } => options.hash(state),
542            #[cfg(feature = "ewma")]
543            EwmVar { options } => options.hash(state),
544            #[cfg(feature = "hist")]
545            Hist {
546                bin_count,
547                include_category,
548                include_breakpoint,
549            } => {
550                bin_count.hash(state);
551                include_category.hash(state);
552                include_breakpoint.hash(state);
553            },
554            #[cfg(feature = "replace")]
555            Replace => {},
556            #[cfg(feature = "replace")]
557            ReplaceStrict { return_dtype } => return_dtype.hash(state),
558            FillNullWithStrategy(strategy) => strategy.hash(state),
559            GatherEvery { n, offset } => (n, offset).hash(state),
560            #[cfg(feature = "reinterpret")]
561            Reinterpret(signed) => signed.hash(state),
562            ExtendConstant => {},
563            #[cfg(feature = "top_k")]
564            TopKBy { descending } => descending.hash(state),
565        }
566    }
567}
568
569impl Display for FunctionExpr {
570    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
571        use FunctionExpr::*;
572        let s = match self {
573            // Namespaces
574            #[cfg(feature = "dtype-array")]
575            ArrayExpr(func) => return write!(f, "{func}"),
576            BinaryExpr(func) => return write!(f, "{func}"),
577            #[cfg(feature = "dtype-categorical")]
578            Categorical(func) => return write!(f, "{func}"),
579            ListExpr(func) => return write!(f, "{func}"),
580            #[cfg(feature = "strings")]
581            StringExpr(func) => return write!(f, "{func}"),
582            #[cfg(feature = "dtype-struct")]
583            StructExpr(func) => return write!(f, "{func}"),
584            #[cfg(feature = "temporal")]
585            TemporalExpr(func) => return write!(f, "{func}"),
586            #[cfg(feature = "bitwise")]
587            Bitwise(func) => return write!(f, "bitwise_{func}"),
588
589            // Other expressions
590            Boolean(func) => return write!(f, "{func}"),
591            #[cfg(feature = "business")]
592            Business(func) => return write!(f, "{func}"),
593            #[cfg(feature = "abs")]
594            Abs => "abs",
595            Negate => "negate",
596            NullCount => "null_count",
597            Pow(func) => return write!(f, "{func}"),
598            #[cfg(feature = "row_hash")]
599            Hash(_, _, _, _) => "hash",
600            #[cfg(feature = "arg_where")]
601            ArgWhere => "arg_where",
602            #[cfg(feature = "index_of")]
603            IndexOf => "index_of",
604            #[cfg(feature = "search_sorted")]
605            SearchSorted { .. } => "search_sorted",
606            #[cfg(feature = "range")]
607            Range(func) => return write!(f, "{func}"),
608            #[cfg(feature = "trigonometry")]
609            Trigonometry(func) => return write!(f, "{func}"),
610            #[cfg(feature = "trigonometry")]
611            Atan2 => return write!(f, "arctan2"),
612            #[cfg(feature = "sign")]
613            Sign => "sign",
614            FillNull => "fill_null",
615            #[cfg(feature = "rolling_window")]
616            RollingExpr(func, ..) => return write!(f, "{func}"),
617            #[cfg(feature = "rolling_window_by")]
618            RollingExprBy(func, ..) => return write!(f, "{func}"),
619            ShiftAndFill => "shift_and_fill",
620            DropNans => "drop_nans",
621            DropNulls => "drop_nulls",
622            #[cfg(feature = "mode")]
623            Mode => "mode",
624            #[cfg(feature = "moment")]
625            Skew(_) => "skew",
626            #[cfg(feature = "moment")]
627            Kurtosis(..) => "kurtosis",
628            ArgUnique => "arg_unique",
629            Repeat => "repeat",
630            #[cfg(feature = "rank")]
631            Rank { .. } => "rank",
632            #[cfg(feature = "round_series")]
633            Clip { has_min, has_max } => match (has_min, has_max) {
634                (true, true) => "clip",
635                (false, true) => "clip_max",
636                (true, false) => "clip_min",
637                _ => unreachable!(),
638            },
639            #[cfg(feature = "dtype-struct")]
640            AsStruct => "as_struct",
641            #[cfg(feature = "top_k")]
642            TopK { descending } => {
643                if *descending {
644                    "bottom_k"
645                } else {
646                    "top_k"
647                }
648            },
649            #[cfg(feature = "top_k")]
650            TopKBy { .. } => "top_k_by",
651            Shift => "shift",
652            #[cfg(feature = "cum_agg")]
653            CumCount { .. } => "cum_count",
654            #[cfg(feature = "cum_agg")]
655            CumSum { .. } => "cum_sum",
656            #[cfg(feature = "cum_agg")]
657            CumProd { .. } => "cum_prod",
658            #[cfg(feature = "cum_agg")]
659            CumMin { .. } => "cum_min",
660            #[cfg(feature = "cum_agg")]
661            CumMax { .. } => "cum_max",
662            #[cfg(feature = "dtype-struct")]
663            ValueCounts { .. } => "value_counts",
664            #[cfg(feature = "unique_counts")]
665            UniqueCounts => "unique_counts",
666            Reverse => "reverse",
667            #[cfg(feature = "approx_unique")]
668            ApproxNUnique => "approx_n_unique",
669            Coalesce => "coalesce",
670            ShrinkType => "shrink_dtype",
671            #[cfg(feature = "diff")]
672            Diff(_) => "diff",
673            #[cfg(feature = "pct_change")]
674            PctChange => "pct_change",
675            #[cfg(feature = "interpolate")]
676            Interpolate(_) => "interpolate",
677            #[cfg(feature = "interpolate_by")]
678            InterpolateBy => "interpolate_by",
679            #[cfg(feature = "log")]
680            Entropy { .. } => "entropy",
681            #[cfg(feature = "log")]
682            Log { .. } => "log",
683            #[cfg(feature = "log")]
684            Log1p => "log1p",
685            #[cfg(feature = "log")]
686            Exp => "exp",
687            Unique(stable) => {
688                if *stable {
689                    "unique_stable"
690                } else {
691                    "unique"
692                }
693            },
694            #[cfg(feature = "round_series")]
695            Round { .. } => "round",
696            #[cfg(feature = "round_series")]
697            RoundSF { .. } => "round_sig_figs",
698            #[cfg(feature = "round_series")]
699            Floor => "floor",
700            #[cfg(feature = "round_series")]
701            Ceil => "ceil",
702            UpperBound => "upper_bound",
703            LowerBound => "lower_bound",
704            ConcatExpr(_) => "concat_expr",
705            #[cfg(feature = "cov")]
706            Correlation { method, .. } => return Display::fmt(method, f),
707            #[cfg(feature = "peaks")]
708            PeakMin => "peak_min",
709            #[cfg(feature = "peaks")]
710            PeakMax => "peak_max",
711            #[cfg(feature = "cutqcut")]
712            Cut { .. } => "cut",
713            #[cfg(feature = "cutqcut")]
714            QCut { .. } => "qcut",
715            #[cfg(feature = "dtype-array")]
716            Reshape(_) => "reshape",
717            #[cfg(feature = "repeat_by")]
718            RepeatBy => "repeat_by",
719            #[cfg(feature = "rle")]
720            RLE => "rle",
721            #[cfg(feature = "rle")]
722            RLEID => "rle_id",
723            ToPhysical => "to_physical",
724            #[cfg(feature = "random")]
725            Random { method, .. } => method.into(),
726            SetSortedFlag(_) => "set_sorted",
727            #[cfg(feature = "ffi_plugin")]
728            FfiPlugin { lib, symbol, .. } => return write!(f, "{lib}:{symbol}"),
729            MaxHorizontal => "max_horizontal",
730            MinHorizontal => "min_horizontal",
731            SumHorizontal { .. } => "sum_horizontal",
732            MeanHorizontal { .. } => "mean_horizontal",
733            #[cfg(feature = "ewma")]
734            EwmMean { .. } => "ewm_mean",
735            #[cfg(feature = "ewma_by")]
736            EwmMeanBy { .. } => "ewm_mean_by",
737            #[cfg(feature = "ewma")]
738            EwmStd { .. } => "ewm_std",
739            #[cfg(feature = "ewma")]
740            EwmVar { .. } => "ewm_var",
741            #[cfg(feature = "hist")]
742            Hist { .. } => "hist",
743            #[cfg(feature = "replace")]
744            Replace => "replace",
745            #[cfg(feature = "replace")]
746            ReplaceStrict { .. } => "replace_strict",
747            FillNullWithStrategy(_) => "fill_null_with_strategy",
748            GatherEvery { .. } => "gather_every",
749            #[cfg(feature = "reinterpret")]
750            Reinterpret(_) => "reinterpret",
751            ExtendConstant => "extend_constant",
752        };
753        write!(f, "{s}")
754    }
755}