Skip to content

Commit e6e6459

Browse files
committed
window() has been deprecated since DF50
1 parent e70cd28 commit e6e6459

2 files changed

Lines changed: 4 additions & 184 deletions

File tree

crates/core/src/functions.rs

Lines changed: 3 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,14 @@
1818
use std::collections::HashMap;
1919

2020
use datafusion::common::{Column, ScalarValue, TableReference};
21-
use datafusion::execution::FunctionRegistry;
22-
use datafusion::functions_aggregate::all_default_aggregate_functions;
23-
use datafusion::functions_window::all_default_window_functions;
24-
use datafusion::logical_expr::expr::{
25-
Alias, FieldMetadata, NullTreatment as DFNullTreatment, WindowFunction, WindowFunctionParams,
26-
};
27-
use datafusion::logical_expr::{Expr, ExprFunctionExt, WindowFrame, WindowFunctionDefinition, lit};
21+
use datafusion::logical_expr::expr::{Alias, FieldMetadata, NullTreatment as DFNullTreatment};
22+
use datafusion::logical_expr::{Expr, ExprFunctionExt, lit};
2823
use datafusion::{functions, functions_aggregate, functions_window};
2924
use pyo3::prelude::*;
3025
use pyo3::wrap_pyfunction;
3126

3227
use crate::common::data_type::{NullTreatment, PyScalarValue};
33-
use crate::context::PySessionContext;
34-
use crate::errors::{PyDataFusionError, PyDataFusionResult};
28+
use crate::errors::PyDataFusionResult;
3529
use crate::expr::PyExpr;
3630
use crate::expr::conditional_expr::PyCaseBuilder;
3731
use crate::expr::sort_expr::{PySortExpr, to_sort_expressions};
@@ -306,126 +300,6 @@ fn when(when: PyExpr, then: PyExpr) -> PyResult<PyCaseBuilder> {
306300
Ok(PyCaseBuilder::new(None).when(when, then))
307301
}
308302

309-
/// Helper function to find the appropriate window function.
310-
///
311-
/// Search procedure:
312-
/// 1) Search built in window functions, which are being deprecated.
313-
/// 1) If a session context is provided:
314-
/// 1) search User Defined Aggregate Functions (UDAFs)
315-
/// 1) search registered window functions
316-
/// 1) search registered aggregate functions
317-
/// 1) If no function has been found, search default aggregate functions.
318-
///
319-
/// NOTE: we search the built-ins first because the `UDAF` versions currently do not have the same behavior.
320-
fn find_window_fn(
321-
name: &str,
322-
ctx: Option<PySessionContext>,
323-
) -> PyDataFusionResult<WindowFunctionDefinition> {
324-
if let Some(ctx) = ctx {
325-
// search UDAFs
326-
let udaf = ctx
327-
.ctx
328-
.udaf(name)
329-
.map(WindowFunctionDefinition::AggregateUDF)
330-
.ok();
331-
332-
if let Some(udaf) = udaf {
333-
return Ok(udaf);
334-
}
335-
336-
let session_state = ctx.ctx.state();
337-
338-
// search registered window functions
339-
let window_fn = session_state
340-
.window_functions()
341-
.get(name)
342-
.map(|f| WindowFunctionDefinition::WindowUDF(f.clone()));
343-
344-
if let Some(window_fn) = window_fn {
345-
return Ok(window_fn);
346-
}
347-
348-
// search registered aggregate functions
349-
let agg_fn = session_state
350-
.aggregate_functions()
351-
.get(name)
352-
.map(|f| WindowFunctionDefinition::AggregateUDF(f.clone()));
353-
354-
if let Some(agg_fn) = agg_fn {
355-
return Ok(agg_fn);
356-
}
357-
}
358-
359-
// search default aggregate functions
360-
let agg_fn = all_default_aggregate_functions()
361-
.iter()
362-
.find(|v| v.name() == name || v.aliases().contains(&name.to_string()))
363-
.map(|f| WindowFunctionDefinition::AggregateUDF(f.clone()));
364-
365-
if let Some(agg_fn) = agg_fn {
366-
return Ok(agg_fn);
367-
}
368-
369-
// search default window functions
370-
let window_fn = all_default_window_functions()
371-
.iter()
372-
.find(|v| v.name() == name || v.aliases().contains(&name.to_string()))
373-
.map(|f| WindowFunctionDefinition::WindowUDF(f.clone()));
374-
375-
if let Some(window_fn) = window_fn {
376-
return Ok(window_fn);
377-
}
378-
379-
Err(PyDataFusionError::Common(format!(
380-
"window function `{name}` not found"
381-
)))
382-
}
383-
384-
/// Creates a new Window function expression
385-
#[allow(clippy::too_many_arguments)]
386-
#[pyfunction]
387-
#[pyo3(signature = (name, args, partition_by=None, order_by=None, window_frame=None, filter=None, distinct=false, ctx=None))]
388-
fn window(
389-
name: &str,
390-
args: Vec<PyExpr>,
391-
partition_by: Option<Vec<PyExpr>>,
392-
order_by: Option<Vec<PySortExpr>>,
393-
window_frame: Option<PyWindowFrame>,
394-
filter: Option<PyExpr>,
395-
distinct: bool,
396-
ctx: Option<PySessionContext>,
397-
) -> PyResult<PyExpr> {
398-
let fun = find_window_fn(name, ctx)?;
399-
400-
let window_frame = window_frame
401-
.map(|w| w.into())
402-
.unwrap_or(WindowFrame::new(order_by.as_ref().map(|v| !v.is_empty())));
403-
let filter = filter.map(|f| f.expr.into());
404-
405-
Ok(PyExpr {
406-
expr: datafusion::logical_expr::Expr::WindowFunction(Box::new(WindowFunction {
407-
fun,
408-
params: WindowFunctionParams {
409-
args: args.into_iter().map(|x| x.expr).collect::<Vec<_>>(),
410-
partition_by: partition_by
411-
.unwrap_or_default()
412-
.into_iter()
413-
.map(|x| x.expr)
414-
.collect::<Vec<_>>(),
415-
order_by: order_by
416-
.unwrap_or_default()
417-
.into_iter()
418-
.map(|x| x.into())
419-
.collect::<Vec<_>>(),
420-
window_frame,
421-
filter,
422-
distinct,
423-
null_treatment: None,
424-
},
425-
})),
426-
})
427-
}
428-
429303
// Generates a [pyo3] wrapper for associated aggregate functions.
430304
// All of the builder options are exposed to the python internal
431305
// function and we rely on the wrappers to only use those that
@@ -1186,7 +1060,6 @@ pub(crate) fn init_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
11861060
m.add_wrapped(wrap_pyfunction!(self::uuid))?; // Use self to avoid name collision
11871061
m.add_wrapped(wrap_pyfunction!(var_pop))?;
11881062
m.add_wrapped(wrap_pyfunction!(var_sample))?;
1189-
m.add_wrapped(wrap_pyfunction!(window))?;
11901063
m.add_wrapped(wrap_pyfunction!(regr_avgx))?;
11911064
m.add_wrapped(wrap_pyfunction!(regr_avgy))?;
11921065
m.add_wrapped(wrap_pyfunction!(regr_count))?;

python/datafusion/functions.py

Lines changed: 1 addition & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from __future__ import annotations
2020

21-
from typing import TYPE_CHECKING, Any
21+
from typing import Any
2222

2323
import pyarrow as pa
2424

@@ -29,19 +29,11 @@
2929
Expr,
3030
SortExpr,
3131
SortKey,
32-
WindowFrame,
3332
expr_list_to_raw_expr_list,
3433
sort_list_to_raw_sort_list,
3534
sort_or_default,
3635
)
3736

38-
try:
39-
from warnings import deprecated # Python 3.13+
40-
except ImportError:
41-
from typing_extensions import deprecated # Python 3.12
42-
43-
if TYPE_CHECKING:
44-
from datafusion.context import SessionContext
4537
__all__ = [
4638
"abs",
4739
"acos",
@@ -339,8 +331,6 @@
339331
"var_sample",
340332
"version",
341333
"when",
342-
# Window Functions
343-
"window",
344334
]
345335

346336

@@ -664,49 +654,6 @@ def when(when: Expr, then: Expr) -> CaseBuilder:
664654
return CaseBuilder(f.when(when.expr, then.expr))
665655

666656

667-
@deprecated("Prefer to call Expr.over() instead")
668-
def window(
669-
name: str,
670-
args: list[Expr],
671-
partition_by: list[Expr] | Expr | None = None,
672-
order_by: list[SortKey] | SortKey | None = None,
673-
window_frame: WindowFrame | None = None,
674-
filter: Expr | None = None,
675-
distinct: bool = False,
676-
ctx: SessionContext | None = None,
677-
) -> Expr:
678-
"""Creates a new Window function expression.
679-
680-
This interface will soon be deprecated. Instead of using this interface,
681-
users should call the window functions directly. For example, to perform a
682-
lag use::
683-
684-
df.select(functions.lag(col("a")).partition_by(col("b")).build())
685-
686-
The ``order_by`` parameter accepts column names or expressions, e.g.::
687-
688-
window("lag", [col("a")], order_by="ts")
689-
"""
690-
args = [a.expr for a in args]
691-
partition_by_raw = expr_list_to_raw_expr_list(partition_by)
692-
order_by_raw = sort_list_to_raw_sort_list(order_by)
693-
window_frame = window_frame.window_frame if window_frame is not None else None
694-
ctx = ctx.ctx if ctx is not None else None
695-
filter_raw = filter.expr if filter is not None else None
696-
return Expr(
697-
f.window(
698-
name,
699-
args,
700-
partition_by=partition_by_raw,
701-
order_by=order_by_raw,
702-
window_frame=window_frame,
703-
ctx=ctx,
704-
filter=filter_raw,
705-
distinct=distinct,
706-
)
707-
)
708-
709-
710657
# scalar functions
711658
def abs(arg: Expr) -> Expr:
712659
"""Return the absolute value of a given number.

0 commit comments

Comments
 (0)