Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-plan/src/plans/conversion/ir_to_dsl.rs
8506 views
1
use polars_utils::format_pl_smallstr;
2
3
use super::*;
4
5
/// converts a node from the AExpr arena to Expr
6
#[recursive]
7
pub fn node_to_expr(node: Node, expr_arena: &Arena<AExpr>) -> Expr {
8
let expr = expr_arena.get(node).clone();
9
10
match expr {
11
AExpr::Element => Expr::Element,
12
AExpr::Explode { expr, options } => Expr::Explode {
13
input: Arc::new(node_to_expr(expr, expr_arena)),
14
options,
15
},
16
AExpr::Column(a) => Expr::Column(a),
17
#[cfg(feature = "dtype-struct")]
18
AExpr::StructField(a) => Expr::Field(Arc::new([a])),
19
AExpr::Literal(s) => Expr::Literal(s),
20
AExpr::BinaryExpr { left, op, right } => {
21
let l = node_to_expr(left, expr_arena);
22
let r = node_to_expr(right, expr_arena);
23
Expr::BinaryExpr {
24
left: Arc::new(l),
25
op,
26
right: Arc::new(r),
27
}
28
},
29
AExpr::Cast {
30
expr,
31
dtype,
32
options: strict,
33
} => {
34
let exp = node_to_expr(expr, expr_arena);
35
Expr::Cast {
36
expr: Arc::new(exp),
37
dtype: dtype.into(),
38
options: strict,
39
}
40
},
41
AExpr::Sort { expr, options } => {
42
let exp = node_to_expr(expr, expr_arena);
43
Expr::Sort {
44
expr: Arc::new(exp),
45
options,
46
}
47
},
48
AExpr::Gather {
49
expr,
50
idx,
51
returns_scalar,
52
null_on_oob,
53
} => {
54
let expr = node_to_expr(expr, expr_arena);
55
let idx = node_to_expr(idx, expr_arena);
56
Expr::Gather {
57
expr: Arc::new(expr),
58
idx: Arc::new(idx),
59
returns_scalar,
60
null_on_oob,
61
}
62
},
63
AExpr::SortBy {
64
expr,
65
by,
66
sort_options,
67
} => {
68
let expr = node_to_expr(expr, expr_arena);
69
let by = by
70
.iter()
71
.map(|node| node_to_expr(*node, expr_arena))
72
.collect();
73
Expr::SortBy {
74
expr: Arc::new(expr),
75
by,
76
sort_options,
77
}
78
},
79
AExpr::Filter { input, by } => {
80
let input = node_to_expr(input, expr_arena);
81
let by = node_to_expr(by, expr_arena);
82
Expr::Filter {
83
input: Arc::new(input),
84
by: Arc::new(by),
85
}
86
},
87
AExpr::Agg(agg) => match agg {
88
IRAggExpr::Min {
89
input,
90
propagate_nans,
91
} => {
92
let exp = node_to_expr(input, expr_arena);
93
AggExpr::Min {
94
input: Arc::new(exp),
95
propagate_nans,
96
}
97
.into()
98
},
99
IRAggExpr::Max {
100
input,
101
propagate_nans,
102
} => {
103
let exp = node_to_expr(input, expr_arena);
104
AggExpr::Max {
105
input: Arc::new(exp),
106
propagate_nans,
107
}
108
.into()
109
},
110
111
IRAggExpr::Mean(expr) => {
112
let exp = node_to_expr(expr, expr_arena);
113
AggExpr::Mean(Arc::new(exp)).into()
114
},
115
IRAggExpr::Median(expr) => {
116
let exp = node_to_expr(expr, expr_arena);
117
AggExpr::Median(Arc::new(exp)).into()
118
},
119
IRAggExpr::NUnique(expr) => {
120
let exp = node_to_expr(expr, expr_arena);
121
AggExpr::NUnique(Arc::new(exp)).into()
122
},
123
IRAggExpr::First(expr) => {
124
let exp = node_to_expr(expr, expr_arena);
125
AggExpr::First(Arc::new(exp)).into()
126
},
127
IRAggExpr::FirstNonNull(expr) => {
128
let exp = node_to_expr(expr, expr_arena);
129
AggExpr::FirstNonNull(Arc::new(exp)).into()
130
},
131
IRAggExpr::Last(expr) => {
132
let exp = node_to_expr(expr, expr_arena);
133
AggExpr::Last(Arc::new(exp)).into()
134
},
135
IRAggExpr::LastNonNull(expr) => {
136
let exp = node_to_expr(expr, expr_arena);
137
AggExpr::LastNonNull(Arc::new(exp)).into()
138
},
139
IRAggExpr::Item { input, allow_empty } => {
140
let exp = node_to_expr(input, expr_arena);
141
AggExpr::Item {
142
input: Arc::new(exp),
143
allow_empty,
144
}
145
.into()
146
},
147
IRAggExpr::Implode(expr) => {
148
let exp = node_to_expr(expr, expr_arena);
149
AggExpr::Implode(Arc::new(exp)).into()
150
},
151
IRAggExpr::Quantile {
152
expr,
153
quantile,
154
method,
155
} => {
156
let expr = node_to_expr(expr, expr_arena);
157
let quantile = node_to_expr(quantile, expr_arena);
158
AggExpr::Quantile {
159
expr: Arc::new(expr),
160
quantile: Arc::new(quantile),
161
method,
162
}
163
.into()
164
},
165
IRAggExpr::Sum(expr) => {
166
let exp = node_to_expr(expr, expr_arena);
167
AggExpr::Sum(Arc::new(exp)).into()
168
},
169
IRAggExpr::Std(expr, ddof) => {
170
let exp = node_to_expr(expr, expr_arena);
171
AggExpr::Std(Arc::new(exp), ddof).into()
172
},
173
IRAggExpr::Var(expr, ddof) => {
174
let exp = node_to_expr(expr, expr_arena);
175
AggExpr::Var(Arc::new(exp), ddof).into()
176
},
177
IRAggExpr::AggGroups(expr) => {
178
let exp = node_to_expr(expr, expr_arena);
179
AggExpr::AggGroups(Arc::new(exp)).into()
180
},
181
IRAggExpr::Count {
182
input,
183
include_nulls,
184
} => {
185
let input = node_to_expr(input, expr_arena);
186
AggExpr::Count {
187
input: Arc::new(input),
188
include_nulls,
189
}
190
.into()
191
},
192
},
193
AExpr::Ternary {
194
predicate,
195
truthy,
196
falsy,
197
} => {
198
let p = node_to_expr(predicate, expr_arena);
199
let t = node_to_expr(truthy, expr_arena);
200
let f = node_to_expr(falsy, expr_arena);
201
202
Expr::Ternary {
203
predicate: Arc::new(p),
204
truthy: Arc::new(t),
205
falsy: Arc::new(f),
206
}
207
},
208
AExpr::AnonymousAgg {
209
input,
210
fmt_str,
211
function: _,
212
} => {
213
let inputs = expr_irs_to_exprs(input.clone(), expr_arena);
214
Expr::Display {
215
inputs,
216
fmt_str: fmt_str.clone(),
217
}
218
},
219
AExpr::AnonymousFunction {
220
input,
221
function,
222
options,
223
fmt_str,
224
} => Expr::AnonymousFunction {
225
input: expr_irs_to_exprs(input, expr_arena),
226
function,
227
options,
228
fmt_str,
229
},
230
AExpr::Eval {
231
expr,
232
evaluation,
233
variant,
234
} => Expr::Eval {
235
expr: Arc::new(node_to_expr(expr, expr_arena)),
236
evaluation: Arc::new(node_to_expr(evaluation, expr_arena)),
237
variant,
238
},
239
#[cfg(feature = "dtype-struct")]
240
AExpr::StructEval { expr, evaluation } => Expr::StructEval {
241
expr: Arc::new(node_to_expr(expr, expr_arena)),
242
evaluation: expr_irs_to_exprs(evaluation, expr_arena),
243
},
244
AExpr::Function {
245
input,
246
function,
247
options: _,
248
} => {
249
let input = expr_irs_to_exprs(input, expr_arena);
250
ir_function_to_dsl(input, function)
251
},
252
#[cfg(feature = "dynamic_group_by")]
253
AExpr::Rolling {
254
function,
255
index_column,
256
period,
257
offset,
258
closed_window,
259
} => {
260
let function = Arc::new(node_to_expr(function, expr_arena));
261
let index_column = Arc::new(node_to_expr(index_column, expr_arena));
262
Expr::Rolling {
263
function,
264
index_column,
265
period,
266
offset,
267
closed_window,
268
}
269
},
270
AExpr::Over {
271
function,
272
partition_by,
273
order_by,
274
mapping,
275
} => {
276
let function = Arc::new(node_to_expr(function, expr_arena));
277
let partition_by = nodes_to_exprs(&partition_by, expr_arena);
278
let order_by =
279
order_by.map(|(n, options)| (Arc::new(node_to_expr(n, expr_arena)), options));
280
Expr::Over {
281
function,
282
partition_by,
283
order_by,
284
mapping,
285
}
286
},
287
AExpr::Slice {
288
input,
289
offset,
290
length,
291
} => Expr::Slice {
292
input: Arc::new(node_to_expr(input, expr_arena)),
293
offset: Arc::new(node_to_expr(offset, expr_arena)),
294
length: Arc::new(node_to_expr(length, expr_arena)),
295
},
296
AExpr::Len => Expr::Len,
297
}
298
}
299
300
fn nodes_to_exprs(nodes: &[Node], expr_arena: &Arena<AExpr>) -> Vec<Expr> {
301
nodes.iter().map(|n| node_to_expr(*n, expr_arena)).collect()
302
}
303
304
pub fn ir_function_to_dsl(input: Vec<Expr>, function: IRFunctionExpr) -> Expr {
305
use {FunctionExpr as F, IRFunctionExpr as IF};
306
307
let function = match function {
308
#[cfg(feature = "dtype-array")]
309
IF::ArrayExpr(f) => {
310
use {ArrayFunction as A, IRArrayFunction as IA};
311
F::ArrayExpr(match f {
312
IA::Concat => A::Concat,
313
IA::Length => A::Length,
314
IA::Min => A::Min,
315
IA::Max => A::Max,
316
IA::Sum => A::Sum,
317
IA::ToList => A::ToList,
318
IA::Unique(v) => A::Unique(v),
319
IA::NUnique => A::NUnique,
320
IA::Std(v) => A::Std(v),
321
IA::Var(v) => A::Var(v),
322
IA::Mean => A::Mean,
323
IA::Median => A::Median,
324
#[cfg(feature = "array_any_all")]
325
IA::Any => A::Any,
326
#[cfg(feature = "array_any_all")]
327
IA::All => A::All,
328
IA::Sort(v) => A::Sort(v),
329
IA::Reverse => A::Reverse,
330
IA::ArgMin => A::ArgMin,
331
IA::ArgMax => A::ArgMax,
332
IA::Get(v) => A::Get(v),
333
IA::Join(v) => A::Join(v),
334
#[cfg(feature = "is_in")]
335
IA::Contains { nulls_equal } => A::Contains { nulls_equal },
336
#[cfg(feature = "array_count")]
337
IA::CountMatches => A::CountMatches,
338
IA::Shift => A::Shift,
339
IA::Slice(offset, length) => A::Slice(offset, length),
340
IA::Explode(options) => A::Explode(options),
341
#[cfg(feature = "array_to_struct")]
342
IA::ToStruct(ng) => A::ToStruct(ng),
343
})
344
},
345
IF::BinaryExpr(f) => {
346
use {BinaryFunction as B, IRBinaryFunction as IB};
347
F::BinaryExpr(match f {
348
IB::Contains => B::Contains,
349
IB::StartsWith => B::StartsWith,
350
IB::EndsWith => B::EndsWith,
351
#[cfg(feature = "binary_encoding")]
352
IB::HexDecode(v) => B::HexDecode(v),
353
#[cfg(feature = "binary_encoding")]
354
IB::HexEncode => B::HexEncode,
355
#[cfg(feature = "binary_encoding")]
356
IB::Base64Decode(v) => B::Base64Decode(v),
357
#[cfg(feature = "binary_encoding")]
358
IB::Base64Encode => B::Base64Encode,
359
IB::Size => B::Size,
360
#[cfg(feature = "binary_encoding")]
361
IB::Reinterpret(data_type, v) => B::Reinterpret(data_type.into(), v),
362
IB::Slice => B::Slice,
363
IB::Head => B::Head,
364
IB::Tail => B::Tail,
365
IB::Get(null_on_oob) => B::Get(null_on_oob),
366
})
367
},
368
#[cfg(feature = "dtype-categorical")]
369
IF::Categorical(f) => {
370
use {CategoricalFunction as C, IRCategoricalFunction as IC};
371
F::Categorical(match f {
372
IC::GetCategories => C::GetCategories,
373
#[cfg(feature = "strings")]
374
IC::LenBytes => C::LenBytes,
375
#[cfg(feature = "strings")]
376
IC::LenChars => C::LenChars,
377
#[cfg(feature = "strings")]
378
IC::StartsWith(v) => C::StartsWith(v),
379
#[cfg(feature = "strings")]
380
IC::EndsWith(v) => C::EndsWith(v),
381
#[cfg(feature = "strings")]
382
IC::Slice(s, l) => C::Slice(s, l),
383
})
384
},
385
#[cfg(feature = "dtype-extension")]
386
IF::Extension(f) => {
387
use {ExtensionFunction as E, IRExtensionFunction as IE};
388
F::Extension(match f {
389
IE::To(dtype) => E::To(dtype.into()),
390
IE::Storage => E::Storage,
391
})
392
},
393
IF::ListExpr(f) => {
394
use {IRListFunction as IL, ListFunction as L};
395
F::ListExpr(match f {
396
IL::Concat => L::Concat,
397
#[cfg(feature = "is_in")]
398
IL::Contains { nulls_equal } => L::Contains { nulls_equal },
399
#[cfg(feature = "list_drop_nulls")]
400
IL::DropNulls => L::DropNulls,
401
#[cfg(feature = "list_sample")]
402
IL::Sample {
403
is_fraction,
404
with_replacement,
405
shuffle,
406
seed,
407
} => L::Sample {
408
is_fraction,
409
with_replacement,
410
shuffle,
411
seed,
412
},
413
IL::Slice => L::Slice,
414
IL::Shift => L::Shift,
415
IL::Get(v) => L::Get(v),
416
#[cfg(feature = "list_gather")]
417
IL::Gather(v) => L::Gather(v),
418
#[cfg(feature = "list_gather")]
419
IL::GatherEvery => L::GatherEvery,
420
#[cfg(feature = "list_count")]
421
IL::CountMatches => L::CountMatches,
422
IL::Sum => L::Sum,
423
IL::Length => L::Length,
424
IL::Max => L::Max,
425
IL::Min => L::Min,
426
IL::Mean => L::Mean,
427
IL::Median => L::Median,
428
IL::Std(v) => L::Std(v),
429
IL::Var(v) => L::Var(v),
430
IL::ArgMin => L::ArgMin,
431
IL::ArgMax => L::ArgMax,
432
#[cfg(feature = "diff")]
433
IL::Diff { n, null_behavior } => L::Diff { n, null_behavior },
434
IL::Sort(sort_options) => L::Sort(sort_options),
435
IL::Reverse => L::Reverse,
436
IL::Unique(v) => L::Unique(v),
437
IL::NUnique => L::NUnique,
438
#[cfg(feature = "list_sets")]
439
IL::SetOperation(set_operation) => L::SetOperation(set_operation),
440
#[cfg(feature = "list_any_all")]
441
IL::Any => L::Any,
442
#[cfg(feature = "list_any_all")]
443
IL::All => L::All,
444
IL::Join(v) => L::Join(v),
445
#[cfg(feature = "dtype-array")]
446
IL::ToArray(v) => L::ToArray(v),
447
#[cfg(feature = "list_to_struct")]
448
IL::ToStruct(list_to_struct_args) => L::ToStruct(list_to_struct_args),
449
})
450
},
451
#[cfg(feature = "strings")]
452
IF::StringExpr(f) => {
453
use {IRStringFunction as IB, StringFunction as B};
454
F::StringExpr(match f {
455
IB::Format { format, insertions } => B::Format { format, insertions },
456
#[cfg(feature = "concat_str")]
457
IB::ConcatHorizontal {
458
delimiter,
459
ignore_nulls,
460
} => B::ConcatHorizontal {
461
delimiter,
462
ignore_nulls,
463
},
464
#[cfg(feature = "concat_str")]
465
IB::ConcatVertical {
466
delimiter,
467
ignore_nulls,
468
} => B::ConcatVertical {
469
delimiter,
470
ignore_nulls,
471
},
472
#[cfg(feature = "regex")]
473
IB::Contains { literal, strict } => B::Contains { literal, strict },
474
IB::CountMatches(v) => B::CountMatches(v),
475
IB::EndsWith => B::EndsWith,
476
IB::Extract(v) => B::Extract(v),
477
IB::ExtractAll => B::ExtractAll,
478
#[cfg(feature = "extract_groups")]
479
IB::ExtractGroups { dtype, pat } => B::ExtractGroups { dtype, pat },
480
#[cfg(feature = "regex")]
481
IB::Find { literal, strict } => B::Find { literal, strict },
482
#[cfg(feature = "string_to_integer")]
483
IB::ToInteger { dtype, strict } => B::ToInteger { dtype, strict },
484
IB::LenBytes => B::LenBytes,
485
IB::LenChars => B::LenChars,
486
IB::Lowercase => B::Lowercase,
487
#[cfg(feature = "extract_jsonpath")]
488
IB::JsonDecode(dtype) => B::JsonDecode(dtype.into()),
489
#[cfg(feature = "extract_jsonpath")]
490
IB::JsonPathMatch => B::JsonPathMatch,
491
#[cfg(feature = "regex")]
492
IB::Replace { n, literal } => B::Replace { n, literal },
493
#[cfg(feature = "string_normalize")]
494
IB::Normalize { form } => B::Normalize { form },
495
#[cfg(feature = "string_reverse")]
496
IB::Reverse => B::Reverse,
497
#[cfg(feature = "string_pad")]
498
IB::PadStart { fill_char } => B::PadStart { fill_char },
499
#[cfg(feature = "string_pad")]
500
IB::PadEnd { fill_char } => B::PadEnd { fill_char },
501
IB::Slice => B::Slice,
502
IB::Head => B::Head,
503
IB::Tail => B::Tail,
504
#[cfg(feature = "string_encoding")]
505
IB::HexEncode => B::HexEncode,
506
#[cfg(feature = "binary_encoding")]
507
IB::HexDecode(v) => B::HexDecode(v),
508
#[cfg(feature = "string_encoding")]
509
IB::Base64Encode => B::Base64Encode,
510
#[cfg(feature = "binary_encoding")]
511
IB::Base64Decode(v) => B::Base64Decode(v),
512
IB::StartsWith => B::StartsWith,
513
IB::StripChars => B::StripChars,
514
IB::StripCharsStart => B::StripCharsStart,
515
IB::StripCharsEnd => B::StripCharsEnd,
516
IB::StripPrefix => B::StripPrefix,
517
IB::StripSuffix => B::StripSuffix,
518
#[cfg(feature = "dtype-struct")]
519
IB::SplitExact { n, inclusive } => B::SplitExact { n, inclusive },
520
#[cfg(feature = "dtype-struct")]
521
IB::SplitN(n) => B::SplitN(n),
522
#[cfg(feature = "temporal")]
523
IB::Strptime(dtype, strptime_options) => {
524
B::Strptime(dtype.into(), strptime_options)
525
},
526
IB::Split(v) => B::Split(v),
527
#[cfg(feature = "regex")]
528
IB::SplitRegex { inclusive, strict } => B::SplitRegex { inclusive, strict },
529
#[cfg(feature = "dtype-decimal")]
530
IB::ToDecimal { scale } => B::ToDecimal { scale },
531
#[cfg(feature = "nightly")]
532
IB::Titlecase => B::Titlecase,
533
IB::Uppercase => B::Uppercase,
534
#[cfg(feature = "string_pad")]
535
IB::ZFill => B::ZFill,
536
#[cfg(feature = "find_many")]
537
IB::ContainsAny {
538
ascii_case_insensitive,
539
} => B::ContainsAny {
540
ascii_case_insensitive,
541
},
542
#[cfg(feature = "find_many")]
543
IB::ReplaceMany {
544
ascii_case_insensitive,
545
leftmost,
546
} => B::ReplaceMany {
547
ascii_case_insensitive,
548
leftmost,
549
},
550
#[cfg(feature = "find_many")]
551
IB::ExtractMany {
552
ascii_case_insensitive,
553
overlapping,
554
leftmost,
555
} => B::ExtractMany {
556
ascii_case_insensitive,
557
overlapping,
558
leftmost,
559
},
560
#[cfg(feature = "find_many")]
561
IB::FindMany {
562
ascii_case_insensitive,
563
overlapping,
564
leftmost,
565
} => B::FindMany {
566
ascii_case_insensitive,
567
overlapping,
568
leftmost,
569
},
570
#[cfg(feature = "regex")]
571
IB::EscapeRegex => B::EscapeRegex,
572
})
573
},
574
#[cfg(feature = "dtype-struct")]
575
IF::StructExpr(f) => {
576
use {IRStructFunction as IB, StructFunction as B};
577
F::StructExpr(match f {
578
IB::FieldByName(pl_small_str) => B::FieldByName(pl_small_str),
579
IB::RenameFields(pl_small_strs) => B::RenameFields(pl_small_strs),
580
IB::PrefixFields(pl_small_str) => B::PrefixFields(pl_small_str),
581
IB::SuffixFields(pl_small_str) => B::SuffixFields(pl_small_str),
582
#[cfg(feature = "json")]
583
IB::JsonEncode => B::JsonEncode,
584
IB::MapFieldNames(f) => B::MapFieldNames(f),
585
})
586
},
587
#[cfg(feature = "temporal")]
588
IF::TemporalExpr(f) => {
589
use {IRTemporalFunction as IB, TemporalFunction as B};
590
F::TemporalExpr(match f {
591
IB::Millennium => B::Millennium,
592
IB::Century => B::Century,
593
IB::Year => B::Year,
594
IB::IsLeapYear => B::IsLeapYear,
595
IB::IsoYear => B::IsoYear,
596
IB::Quarter => B::Quarter,
597
IB::Month => B::Month,
598
IB::DaysInMonth => B::DaysInMonth,
599
IB::Week => B::Week,
600
IB::WeekDay => B::WeekDay,
601
IB::Day => B::Day,
602
IB::OrdinalDay => B::OrdinalDay,
603
IB::Time => B::Time,
604
IB::Date => B::Date,
605
IB::Datetime => B::Datetime,
606
#[cfg(feature = "dtype-duration")]
607
IB::Duration(time_unit) => B::Duration(time_unit),
608
IB::Hour => B::Hour,
609
IB::Minute => B::Minute,
610
IB::Second => B::Second,
611
IB::Millisecond => B::Millisecond,
612
IB::Microsecond => B::Microsecond,
613
IB::Nanosecond => B::Nanosecond,
614
#[cfg(feature = "dtype-duration")]
615
IB::TotalDays { fractional } => B::TotalDays { fractional },
616
#[cfg(feature = "dtype-duration")]
617
IB::TotalHours { fractional } => B::TotalHours { fractional },
618
#[cfg(feature = "dtype-duration")]
619
IB::TotalMinutes { fractional } => B::TotalMinutes { fractional },
620
#[cfg(feature = "dtype-duration")]
621
IB::TotalSeconds { fractional } => B::TotalSeconds { fractional },
622
#[cfg(feature = "dtype-duration")]
623
IB::TotalMilliseconds { fractional } => B::TotalMilliseconds { fractional },
624
#[cfg(feature = "dtype-duration")]
625
IB::TotalMicroseconds { fractional } => B::TotalMicroseconds { fractional },
626
#[cfg(feature = "dtype-duration")]
627
IB::TotalNanoseconds { fractional } => B::TotalNanoseconds { fractional },
628
IB::ToString(v) => B::ToString(v),
629
IB::CastTimeUnit(time_unit) => B::CastTimeUnit(time_unit),
630
IB::WithTimeUnit(time_unit) => B::WithTimeUnit(time_unit),
631
#[cfg(feature = "timezones")]
632
IB::ConvertTimeZone(time_zone) => B::ConvertTimeZone(time_zone),
633
IB::TimeStamp(time_unit) => B::TimeStamp(time_unit),
634
IB::Truncate => B::Truncate,
635
#[cfg(feature = "offset_by")]
636
IB::OffsetBy => B::OffsetBy,
637
#[cfg(feature = "month_start")]
638
IB::MonthStart => B::MonthStart,
639
#[cfg(feature = "month_end")]
640
IB::MonthEnd => B::MonthEnd,
641
#[cfg(feature = "timezones")]
642
IB::BaseUtcOffset => B::BaseUtcOffset,
643
#[cfg(feature = "timezones")]
644
IB::DSTOffset => B::DSTOffset,
645
IB::Round => B::Round,
646
IB::Replace => B::Replace,
647
#[cfg(feature = "timezones")]
648
IB::ReplaceTimeZone(time_zone, non_existent) => {
649
B::ReplaceTimeZone(time_zone, non_existent)
650
},
651
IB::Combine(time_unit) => B::Combine(time_unit),
652
IB::DatetimeFunction {
653
time_unit,
654
time_zone,
655
} => B::DatetimeFunction {
656
time_unit,
657
time_zone,
658
},
659
})
660
},
661
#[cfg(feature = "bitwise")]
662
IF::Bitwise(f) => {
663
use {BitwiseFunction as B, IRBitwiseFunction as IB};
664
F::Bitwise(match f {
665
IB::CountOnes => B::CountOnes,
666
IB::CountZeros => B::CountZeros,
667
IB::LeadingOnes => B::LeadingOnes,
668
IB::LeadingZeros => B::LeadingZeros,
669
IB::TrailingOnes => B::TrailingOnes,
670
IB::TrailingZeros => B::TrailingZeros,
671
IB::And => B::And,
672
IB::Or => B::Or,
673
IB::Xor => B::Xor,
674
})
675
},
676
IF::Boolean(f) => {
677
use {BooleanFunction as B, IRBooleanFunction as IB};
678
F::Boolean(match f {
679
IB::Any { ignore_nulls } => B::Any { ignore_nulls },
680
IB::All { ignore_nulls } => B::All { ignore_nulls },
681
IB::IsNull => B::IsNull,
682
IB::IsNotNull => B::IsNotNull,
683
IB::IsFinite => B::IsFinite,
684
IB::IsInfinite => B::IsInfinite,
685
IB::IsNan => B::IsNan,
686
IB::IsNotNan => B::IsNotNan,
687
#[cfg(feature = "is_first_distinct")]
688
IB::IsFirstDistinct => B::IsFirstDistinct,
689
#[cfg(feature = "is_last_distinct")]
690
IB::IsLastDistinct => B::IsLastDistinct,
691
#[cfg(feature = "is_unique")]
692
IB::IsUnique => B::IsUnique,
693
#[cfg(feature = "is_unique")]
694
IB::IsDuplicated => B::IsDuplicated,
695
#[cfg(feature = "is_between")]
696
IB::IsBetween { closed } => B::IsBetween { closed },
697
#[cfg(feature = "is_in")]
698
IB::IsIn { nulls_equal } => B::IsIn { nulls_equal },
699
#[cfg(feature = "is_close")]
700
IB::IsClose {
701
abs_tol,
702
rel_tol,
703
nans_equal,
704
} => B::IsClose {
705
abs_tol,
706
rel_tol,
707
nans_equal,
708
},
709
IB::AllHorizontal => B::AllHorizontal,
710
IB::AnyHorizontal => B::AnyHorizontal,
711
IB::Not => B::Not,
712
})
713
},
714
#[cfg(feature = "business")]
715
IF::Business(f) => {
716
use {BusinessFunction as B, IRBusinessFunction as IB};
717
F::Business(match f {
718
IB::BusinessDayCount {
719
week_mask,
720
holidays,
721
} => B::BusinessDayCount {
722
week_mask,
723
holidays,
724
},
725
IB::AddBusinessDay {
726
week_mask,
727
holidays,
728
roll,
729
} => B::AddBusinessDay {
730
week_mask,
731
holidays,
732
roll,
733
},
734
IB::IsBusinessDay {
735
week_mask,
736
holidays,
737
} => B::IsBusinessDay {
738
week_mask,
739
holidays,
740
},
741
})
742
},
743
#[cfg(feature = "abs")]
744
IF::Abs => F::Abs,
745
IF::Negate => F::Negate,
746
#[cfg(feature = "hist")]
747
IF::Hist {
748
bin_count,
749
include_category,
750
include_breakpoint,
751
} => F::Hist {
752
bin_count,
753
include_category,
754
include_breakpoint,
755
},
756
IF::NullCount => F::NullCount,
757
IF::Pow(f) => {
758
use {IRPowFunction as IP, PowFunction as P};
759
F::Pow(match f {
760
IP::Generic => P::Generic,
761
IP::Sqrt => P::Sqrt,
762
IP::Cbrt => P::Cbrt,
763
})
764
},
765
#[cfg(feature = "row_hash")]
766
IF::Hash(s0, s1, s2, s3) => F::Hash(s0, s1, s2, s3),
767
#[cfg(feature = "arg_where")]
768
IF::ArgWhere => F::ArgWhere,
769
#[cfg(feature = "index_of")]
770
IF::IndexOf => F::IndexOf,
771
#[cfg(feature = "search_sorted")]
772
IF::SearchSorted { side, descending } => F::SearchSorted { side, descending },
773
#[cfg(feature = "range")]
774
IF::Range(f) => {
775
use {IRRangeFunction as IR, RangeFunction as R};
776
F::Range(match f {
777
IR::IntRange { step, dtype } => R::IntRange {
778
step,
779
dtype: dtype.into(),
780
},
781
IR::IntRanges { dtype } => R::IntRanges {
782
dtype: dtype.into(),
783
},
784
IR::LinearSpace { closed } => R::LinearSpace { closed },
785
IR::LinearSpaces {
786
closed,
787
array_width,
788
} => R::LinearSpaces {
789
closed,
790
array_width,
791
},
792
#[cfg(all(feature = "range", feature = "dtype-date"))]
793
IR::DateRange {
794
interval,
795
closed,
796
arg_type,
797
} => R::DateRange {
798
interval,
799
closed,
800
arg_type,
801
},
802
#[cfg(all(feature = "range", feature = "dtype-date"))]
803
IR::DateRanges {
804
interval,
805
closed,
806
arg_type,
807
} => R::DateRanges {
808
interval,
809
closed,
810
arg_type,
811
},
812
#[cfg(all(feature = "range", feature = "dtype-datetime"))]
813
IR::DatetimeRange {
814
interval,
815
closed,
816
time_unit,
817
time_zone,
818
arg_type,
819
} => R::DatetimeRange {
820
interval,
821
closed,
822
time_unit,
823
time_zone,
824
arg_type,
825
},
826
#[cfg(all(feature = "range", feature = "dtype-datetime"))]
827
IR::DatetimeRanges {
828
interval,
829
closed,
830
time_unit,
831
time_zone,
832
arg_type,
833
} => R::DatetimeRanges {
834
interval,
835
closed,
836
time_unit,
837
time_zone,
838
arg_type,
839
},
840
#[cfg(feature = "dtype-time")]
841
IR::TimeRange { interval, closed } => R::TimeRange { interval, closed },
842
#[cfg(feature = "dtype-time")]
843
IR::TimeRanges { interval, closed } => R::TimeRanges { interval, closed },
844
})
845
},
846
#[cfg(feature = "trigonometry")]
847
IF::Trigonometry(f) => {
848
use {IRTrigonometricFunction as IT, TrigonometricFunction as T};
849
F::Trigonometry(match f {
850
IT::Cos => T::Cos,
851
IT::Cot => T::Cot,
852
IT::Sin => T::Sin,
853
IT::Tan => T::Tan,
854
IT::ArcCos => T::ArcCos,
855
IT::ArcSin => T::ArcSin,
856
IT::ArcTan => T::ArcTan,
857
IT::Cosh => T::Cosh,
858
IT::Sinh => T::Sinh,
859
IT::Tanh => T::Tanh,
860
IT::ArcCosh => T::ArcCosh,
861
IT::ArcSinh => T::ArcSinh,
862
IT::ArcTanh => T::ArcTanh,
863
IT::Degrees => T::Degrees,
864
IT::Radians => T::Radians,
865
})
866
},
867
#[cfg(feature = "trigonometry")]
868
IF::Atan2 => F::Atan2,
869
#[cfg(feature = "sign")]
870
IF::Sign => F::Sign,
871
IF::FillNull => F::FillNull,
872
IF::FillNullWithStrategy(strategy) => F::FillNullWithStrategy(strategy),
873
#[cfg(feature = "rolling_window")]
874
IF::RollingExpr { function, options } => {
875
use {IRRollingFunction as IR, RollingFunction as R};
876
FunctionExpr::RollingExpr {
877
function: match function {
878
IR::Min => R::Min,
879
IR::Max => R::Max,
880
IR::Mean => R::Mean,
881
IR::Sum => R::Sum,
882
IR::Quantile => R::Quantile,
883
IR::Var => R::Var,
884
IR::Std => R::Std,
885
IR::Rank => R::Rank,
886
#[cfg(feature = "moment")]
887
IR::Skew => R::Skew,
888
#[cfg(feature = "moment")]
889
IR::Kurtosis => R::Kurtosis,
890
#[cfg(feature = "cov")]
891
IR::CorrCov {
892
corr_cov_options,
893
is_corr,
894
} => R::CorrCov {
895
corr_cov_options,
896
is_corr,
897
},
898
IR::Map(f) => R::Map(f),
899
},
900
options,
901
}
902
},
903
#[cfg(feature = "rolling_window_by")]
904
IF::RollingExprBy {
905
function_by,
906
options,
907
} => {
908
use {IRRollingFunctionBy as IR, RollingFunctionBy as R};
909
FunctionExpr::RollingExprBy {
910
function_by: match function_by {
911
IR::MinBy => R::MinBy,
912
IR::MaxBy => R::MaxBy,
913
IR::MeanBy => R::MeanBy,
914
IR::SumBy => R::SumBy,
915
IR::QuantileBy => R::QuantileBy,
916
IR::VarBy => R::VarBy,
917
IR::StdBy => R::StdBy,
918
IR::RankBy => R::RankBy,
919
},
920
options,
921
}
922
},
923
IF::Rechunk => F::Rechunk,
924
IF::Append { upcast } => F::Append { upcast },
925
IF::ShiftAndFill => F::ShiftAndFill,
926
IF::Shift => F::Shift,
927
IF::DropNans => F::DropNans,
928
IF::DropNulls => F::DropNulls,
929
#[cfg(feature = "mode")]
930
IF::Mode { maintain_order } => F::Mode { maintain_order },
931
#[cfg(feature = "moment")]
932
IF::Skew(v) => F::Skew(v),
933
#[cfg(feature = "moment")]
934
IF::Kurtosis(fisher, bias) => F::Kurtosis(fisher, bias),
935
#[cfg(feature = "dtype-array")]
936
IF::Reshape(dims) => F::Reshape(dims),
937
#[cfg(feature = "repeat_by")]
938
IF::RepeatBy => F::RepeatBy,
939
IF::ArgUnique => F::ArgUnique,
940
IF::ArgMin => F::ArgMin,
941
IF::ArgMax => F::ArgMax,
942
IF::ArgSort {
943
descending,
944
nulls_last,
945
} => F::ArgSort {
946
descending,
947
nulls_last,
948
},
949
IF::MinBy => F::MinBy,
950
IF::MaxBy => F::MaxBy,
951
IF::Product => F::Product,
952
#[cfg(feature = "rank")]
953
IF::Rank { options, seed } => F::Rank { options, seed },
954
IF::Repeat => F::Repeat,
955
#[cfg(feature = "round_series")]
956
IF::Clip { has_min, has_max } => F::Clip { has_min, has_max },
957
#[cfg(feature = "dtype-struct")]
958
IF::AsStruct => F::AsStruct,
959
#[cfg(feature = "top_k")]
960
IF::TopK { descending } => F::TopK { descending },
961
#[cfg(feature = "top_k")]
962
IF::TopKBy { descending } => F::TopKBy { descending },
963
#[cfg(feature = "cum_agg")]
964
IF::CumCount { reverse } => F::CumCount { reverse },
965
#[cfg(feature = "cum_agg")]
966
IF::CumSum { reverse } => F::CumSum { reverse },
967
#[cfg(feature = "cum_agg")]
968
IF::CumProd { reverse } => F::CumProd { reverse },
969
#[cfg(feature = "cum_agg")]
970
IF::CumMin { reverse } => F::CumMin { reverse },
971
#[cfg(feature = "cum_agg")]
972
IF::CumMax { reverse } => F::CumMax { reverse },
973
IF::Reverse => F::Reverse,
974
#[cfg(feature = "dtype-struct")]
975
IF::ValueCounts {
976
sort,
977
parallel,
978
name,
979
normalize,
980
} => F::ValueCounts {
981
sort,
982
parallel,
983
name,
984
normalize,
985
},
986
#[cfg(feature = "unique_counts")]
987
IF::UniqueCounts => F::UniqueCounts,
988
#[cfg(feature = "approx_unique")]
989
IF::ApproxNUnique => F::ApproxNUnique,
990
IF::Coalesce => F::Coalesce,
991
#[cfg(feature = "diff")]
992
IF::Diff(nb) => F::Diff(nb),
993
#[cfg(feature = "pct_change")]
994
IF::PctChange => F::PctChange,
995
#[cfg(feature = "interpolate")]
996
IF::Interpolate(m) => F::Interpolate(m),
997
#[cfg(feature = "interpolate_by")]
998
IF::InterpolateBy => F::InterpolateBy,
999
#[cfg(feature = "log")]
1000
IF::Entropy { base, normalize } => F::Entropy { base, normalize },
1001
#[cfg(feature = "log")]
1002
IF::Log => F::Log,
1003
#[cfg(feature = "log")]
1004
IF::Log1p => F::Log1p,
1005
#[cfg(feature = "log")]
1006
IF::Exp => F::Exp,
1007
IF::Unique(v) => F::Unique(v),
1008
#[cfg(feature = "round_series")]
1009
IF::Round { decimals, mode } => F::Round { decimals, mode },
1010
#[cfg(feature = "round_series")]
1011
IF::RoundSF { digits } => F::RoundSF { digits },
1012
#[cfg(feature = "round_series")]
1013
IF::Truncate { decimals } => F::Truncate { decimals },
1014
#[cfg(feature = "round_series")]
1015
IF::Floor => F::Floor,
1016
#[cfg(feature = "round_series")]
1017
IF::Ceil => F::Ceil,
1018
#[cfg(feature = "fused")]
1019
IF::Fused(f) => {
1020
assert_eq!(input.len(), 3);
1021
let mut input = input.into_iter();
1022
let fst = input.next().unwrap();
1023
let snd = input.next().unwrap();
1024
let trd = input.next().unwrap();
1025
return match f {
1026
FusedOperator::MultiplyAdd => (fst * snd) + trd,
1027
FusedOperator::SubMultiply => fst - (snd * trd),
1028
FusedOperator::MultiplySub => (fst * snd) - trd,
1029
};
1030
},
1031
IF::ConcatExpr(v) => F::ConcatExpr(v),
1032
#[cfg(feature = "cov")]
1033
IF::Correlation { method } => {
1034
use {CorrelationMethod as C, IRCorrelationMethod as IC};
1035
F::Correlation {
1036
method: match method {
1037
IC::Pearson => C::Pearson,
1038
#[cfg(all(feature = "rank", feature = "propagate_nans"))]
1039
IC::SpearmanRank(v) => C::SpearmanRank(v),
1040
IC::Covariance(v) => C::Covariance(v),
1041
},
1042
}
1043
},
1044
#[cfg(feature = "peaks")]
1045
IF::PeakMin => F::PeakMin,
1046
#[cfg(feature = "peaks")]
1047
IF::PeakMax => F::PeakMax,
1048
#[cfg(feature = "cutqcut")]
1049
IF::Cut {
1050
breaks,
1051
labels,
1052
left_closed,
1053
include_breaks,
1054
} => F::Cut {
1055
breaks,
1056
labels,
1057
left_closed,
1058
include_breaks,
1059
},
1060
#[cfg(feature = "cutqcut")]
1061
IF::QCut {
1062
probs,
1063
labels,
1064
left_closed,
1065
allow_duplicates,
1066
include_breaks,
1067
} => F::QCut {
1068
probs,
1069
labels,
1070
left_closed,
1071
allow_duplicates,
1072
include_breaks,
1073
},
1074
#[cfg(feature = "rle")]
1075
IF::RLE => F::RLE,
1076
#[cfg(feature = "rle")]
1077
IF::RLEID => F::RLEID,
1078
IF::ToPhysical => F::ToPhysical,
1079
#[cfg(feature = "random")]
1080
IF::Random { method, seed } => {
1081
use {IRRandomMethod as IR, RandomMethod as R};
1082
F::Random {
1083
method: match method {
1084
IR::Shuffle => R::Shuffle,
1085
IR::Sample {
1086
is_fraction,
1087
with_replacement,
1088
shuffle,
1089
} => R::Sample {
1090
is_fraction,
1091
with_replacement,
1092
shuffle,
1093
},
1094
},
1095
seed,
1096
}
1097
},
1098
IF::SetSortedFlag(s) => F::SetSortedFlag(s),
1099
#[cfg(feature = "ffi_plugin")]
1100
IF::FfiPlugin {
1101
flags,
1102
lib,
1103
symbol,
1104
kwargs,
1105
} => F::FfiPlugin {
1106
flags,
1107
lib,
1108
symbol,
1109
kwargs,
1110
},
1111
1112
IF::FoldHorizontal {
1113
callback,
1114
returns_scalar,
1115
return_dtype,
1116
} => F::FoldHorizontal {
1117
callback,
1118
returns_scalar,
1119
return_dtype: return_dtype.map(DataTypeExpr::Literal),
1120
},
1121
IF::ReduceHorizontal {
1122
callback,
1123
returns_scalar,
1124
return_dtype,
1125
} => F::ReduceHorizontal {
1126
callback,
1127
returns_scalar,
1128
return_dtype: return_dtype.map(DataTypeExpr::Literal),
1129
},
1130
#[cfg(feature = "dtype-struct")]
1131
IF::CumReduceHorizontal {
1132
callback,
1133
returns_scalar,
1134
return_dtype,
1135
} => F::CumReduceHorizontal {
1136
callback,
1137
returns_scalar,
1138
return_dtype: return_dtype.map(DataTypeExpr::Literal),
1139
},
1140
#[cfg(feature = "dtype-struct")]
1141
IF::CumFoldHorizontal {
1142
callback,
1143
returns_scalar,
1144
return_dtype,
1145
include_init,
1146
} => F::CumFoldHorizontal {
1147
callback,
1148
returns_scalar,
1149
return_dtype: return_dtype.map(DataTypeExpr::Literal),
1150
include_init,
1151
},
1152
1153
IF::MaxHorizontal => F::MaxHorizontal,
1154
IF::MinHorizontal => F::MinHorizontal,
1155
IF::SumHorizontal { ignore_nulls } => F::SumHorizontal { ignore_nulls },
1156
IF::MeanHorizontal { ignore_nulls } => F::MeanHorizontal { ignore_nulls },
1157
#[cfg(feature = "ewma")]
1158
IF::EwmMean { options } => F::EwmMean { options },
1159
#[cfg(feature = "ewma_by")]
1160
IF::EwmMeanBy { half_life } => F::EwmMeanBy { half_life },
1161
#[cfg(feature = "ewma")]
1162
IF::EwmStd { options } => F::EwmStd { options },
1163
#[cfg(feature = "ewma")]
1164
IF::EwmVar { options } => F::EwmVar { options },
1165
#[cfg(feature = "replace")]
1166
IF::Replace => F::Replace,
1167
#[cfg(feature = "replace")]
1168
IF::ReplaceStrict { return_dtype } => F::ReplaceStrict {
1169
return_dtype: return_dtype.map(Into::into),
1170
},
1171
IF::GatherEvery { n, offset } => F::GatherEvery { n, offset },
1172
#[cfg(feature = "reinterpret")]
1173
IF::Reinterpret(v) => F::Reinterpret(v),
1174
IF::ExtendConstant => F::ExtendConstant,
1175
1176
IF::RowEncode(_, v) => F::RowEncode(v),
1177
#[cfg(feature = "dtype-struct")]
1178
IF::RowDecode(fs, v) => F::RowDecode(
1179
fs.into_iter().map(|f| (f.name, f.dtype.into())).collect(),
1180
v,
1181
),
1182
IF::DynamicPred { pred } => {
1183
return Expr::Display {
1184
inputs: input,
1185
fmt_str: Box::new(format_pl_smallstr!("{pred:?}")),
1186
};
1187
},
1188
};
1189
1190
Expr::Function { input, function }
1191
}
1192
1193