Skip to main content

datafusion_functions_window/
macros.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Convenience macros for defining a user-defined window function
19//! and associated expression API (fluent style).
20//!
21//! See [`define_udwf_and_expr!`] for usage examples.
22//!
23//! [`define_udwf_and_expr!`]: crate::define_udwf_and_expr!
24
25/// Lazily initializes a user-defined window function exactly once
26/// when called concurrently. Repeated calls return a reference to the
27/// same instance.
28///
29/// # Parameters
30///
31/// * `$UDWF`: The struct which defines the [`Signature`](datafusion_expr::Signature)
32///   of the user-defined window function.
33/// * `$OUT_FN_NAME`: The expression function name
34///   `UDWF_FN` : The unique function name
35/// * `$DOC`: Doc comments for UDWF.
36/// * (optional) `$CTOR`: Pass a custom constructor. When omitted it
37///   automatically resolves to `$UDWF::default()`.
38///
39/// # Example
40///
41/// ```
42/// use arrow::datatypes::FieldRef;
43/// # use datafusion_common::arrow::datatypes::{DataType, Field};
44/// # use datafusion_expr::{PartitionEvaluator, Signature, Volatility, WindowUDFImpl};
45/// #
46/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
47/// # use datafusion_functions_window::get_or_init_udwf;
48/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
49/// #
50/// /// Defines the `simple_udwf()` user-defined window function.
51/// get_or_init_udwf!(
52///     SimpleUDWF,
53///     simple,
54///     simple_udwf,
55///     "Simple user-defined window function doc comment."
56/// );
57/// #
58/// # assert_eq!(simple_udwf().name(), "simple_user_defined_window_function");
59/// #
60/// #  #[derive(Debug, PartialEq, Eq, Hash)]
61/// #  struct SimpleUDWF {
62/// #      signature: Signature,
63/// #  }
64/// #
65/// #  impl Default for SimpleUDWF {
66/// #      fn default() -> Self {
67/// #          Self {
68/// #             signature: Signature::any(0, Volatility::Immutable),
69/// #          }
70/// #      }
71/// #  }
72/// #
73/// #  impl WindowUDFImpl for SimpleUDWF {
74/// #      fn name(&self) -> &str {
75/// #          "simple_user_defined_window_function"
76/// #      }
77/// #      fn signature(&self) -> &Signature {
78/// #          &self.signature
79/// #      }
80/// #      fn partition_evaluator(
81/// #          &self,
82/// #         _partition_evaluator_args: PartitionEvaluatorArgs,
83/// #      ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
84/// #          unimplemented!()
85/// #      }
86/// #      fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<FieldRef> {
87/// #          Ok(Field::new(field_args.name(), DataType::Int64, false).into())
88/// #      }
89/// #  }
90/// #
91/// ```
92#[macro_export]
93macro_rules! get_or_init_udwf {
94    ($UDWF:ident, $OUT_FN_NAME:ident, $UDWF_FN:ident, $DOC:expr) => {
95        get_or_init_udwf!($UDWF, $OUT_FN_NAME, $UDWF_FN, $DOC, $UDWF::default);
96    };
97
98    ($UDWF:ident, $OUT_FN_NAME:ident, $UDWF_FN:ident, $DOC:expr, $CTOR:path) => {
99            #[doc = concat!(" Returns a [`WindowUDF`](datafusion_expr::WindowUDF) for [`", stringify!($OUT_FN_NAME), "`].")]
100            #[doc = ""]
101            #[doc = concat!(" ", $DOC)]
102            pub fn $UDWF_FN() -> std::sync::Arc<datafusion_expr::WindowUDF> {
103                // Singleton instance of UDWF, ensures it is only created once.
104                static INSTANCE: std::sync::LazyLock<std::sync::Arc<datafusion_expr::WindowUDF>> =
105                    std::sync::LazyLock::new(|| {
106                        std::sync::Arc::new(datafusion_expr::WindowUDF::from($CTOR()))
107                    });
108                std::sync::Arc::clone(&INSTANCE)
109            }
110    };
111}
112
113/// Create a [`WindowFunction`] expression that exposes a fluent API
114/// which you can use to build more complex expressions.
115///
116/// [`WindowFunction`]: datafusion_expr::Expr::WindowFunction
117///
118/// # Parameters
119///
120/// * `$UDWF`: The struct which defines the [`Signature`] of the
121///   user-defined window function.
122/// * `$OUT_FN_NAME`: The basename to generate a unique function name like
123///   `$OUT_FN_NAME_udwf`.
124/// * `$DOC`: Doc comments for UDWF.
125/// * (optional) `[$($PARAM:ident),+]`: An array of 1 or more parameters
126///   for the generated function. The type of parameters is [`Expr`].
127///   When omitted this creates a function with zero parameters.
128///
129/// [`Signature`]: datafusion_expr::Signature
130/// [`Expr`]: datafusion_expr::Expr
131///
132/// # Example
133///
134/// 1. With Zero Parameters
135/// ```
136/// use arrow::datatypes::FieldRef;
137/// # use datafusion_common::arrow::datatypes::{DataType, Field};
138/// # use datafusion_expr::{PartitionEvaluator, Signature, Volatility, WindowUDFImpl};
139/// # use datafusion_functions_window::{create_udwf_expr, get_or_init_udwf};
140/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
141/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
142///
143/// # get_or_init_udwf!(
144/// #     RowNumber,
145/// #     row_number,
146/// #     row_number_udwf,
147/// #     "Returns a unique row number for each row in window partition beginning at 1."
148/// # );
149/// /// Creates `row_number()` API which has zero parameters:
150/// ///
151/// ///     ```
152/// ///     /// Returns a unique row number for each row in window partition
153/// ///     /// beginning at 1.
154/// ///     pub fn row_number() -> datafusion_expr::Expr {
155/// ///        row_number_udwf().call(vec![])
156/// ///     }
157/// ///     ```
158/// create_udwf_expr!(
159///     RowNumber,
160///     row_number,
161///     row_number_udwf,
162///     "Returns a unique row number for each row in window partition beginning at 1."
163/// );
164/// #
165/// # assert_eq!(
166/// #     row_number().name_for_alias().unwrap(),
167/// #     "row_number() ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
168/// # );
169/// #
170/// # #[derive(Debug, PartialEq, Eq, Hash)]
171/// # struct RowNumber {
172/// #     signature: Signature,
173/// # }
174/// # impl Default for RowNumber {
175/// #     fn default() -> Self {
176/// #         Self {
177/// #             signature: Signature::any(0, Volatility::Immutable),
178/// #         }
179/// #     }
180/// # }
181/// # impl WindowUDFImpl for RowNumber {
182/// #     fn name(&self) -> &str {
183/// #         "row_number"
184/// #     }
185/// #     fn signature(&self) -> &Signature {
186/// #         &self.signature
187/// #     }
188/// #     fn partition_evaluator(
189/// #         &self,
190/// #         _partition_evaluator_args: PartitionEvaluatorArgs,
191/// #     ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
192/// #         unimplemented!()
193/// #     }
194/// #     fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<FieldRef> {
195/// #         Ok(Field::new(field_args.name(), DataType::UInt64, false).into())
196/// #     }
197/// # }
198/// ```
199///
200/// 2. With Multiple Parameters
201/// ```
202/// use arrow::datatypes::FieldRef;
203/// #
204/// # use datafusion_expr::{
205/// #     PartitionEvaluator, Signature, TypeSignature, Volatility, WindowUDFImpl,
206/// # };
207/// #
208/// # use datafusion_functions_window::{create_udwf_expr, get_or_init_udwf};
209/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
210/// #
211/// # use datafusion_common::arrow::datatypes::Field;
212/// # use datafusion_common::ScalarValue;
213/// # use datafusion_expr::{col, lit};
214/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
215/// #
216/// # get_or_init_udwf!(Lead, lead,lead_udwf, "user-defined window function");
217/// #
218/// /// Creates `lead(expr, offset, default)` with 3 parameters:
219/// ///
220/// ///     ```
221/// ///     /// Returns a value evaluated at the row that is offset rows
222/// ///     /// after the current row within the partition.
223/// ///     pub fn lead(
224/// ///         expr: datafusion_expr::Expr,
225/// ///         offset: datafusion_expr::Expr,
226/// ///         default: datafusion_expr::Expr,
227/// ///     ) -> datafusion_expr::Expr {
228/// ///         lead_udwf().call(vec![expr, offset, default])
229/// ///     }
230/// ///     ```
231/// create_udwf_expr!(
232///     Lead,
233///     lead,
234///     [expr, offset, default],
235///     lead_udwf,
236///     "Returns a value evaluated at the row that is offset rows after the current row within the partition."
237/// );
238/// #
239/// # assert_eq!(
240/// #     lead(col("a"), lit(1i64), lit(ScalarValue::Null))
241/// #         .name_for_alias()
242/// #         .unwrap(),
243/// #     "lead(a,Int64(1),NULL) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
244/// # );
245/// #
246/// # #[derive(Debug, PartialEq, Eq, Hash)]
247/// # struct Lead {
248/// #     signature: Signature,
249/// # }
250/// #
251/// # impl Default for Lead {
252/// #     fn default() -> Self {
253/// #         Self {
254/// #             signature: Signature::one_of(
255/// #                 vec![
256/// #                     TypeSignature::Any(1),
257/// #                     TypeSignature::Any(2),
258/// #                     TypeSignature::Any(3),
259/// #                 ],
260/// #                 Volatility::Immutable,
261/// #             ),
262/// #         }
263/// #     }
264/// # }
265/// #
266/// # impl WindowUDFImpl for Lead {
267/// #     fn name(&self) -> &str {
268/// #         "lead"
269/// #     }
270/// #     fn signature(&self) -> &Signature {
271/// #         &self.signature
272/// #     }
273/// #     fn partition_evaluator(
274/// #         &self,
275/// #         partition_evaluator_args: PartitionEvaluatorArgs,
276/// #     ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
277/// #         unimplemented!()
278/// #     }
279/// #     fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<FieldRef> {
280/// #         Ok(Field::new(
281/// #             field_args.name(),
282/// #             field_args.get_input_field(0).unwrap().data_type().clone(),
283/// #             false,
284/// #         ).into())
285/// #     }
286/// # }
287/// ```
288#[macro_export]
289macro_rules! create_udwf_expr {
290    // zero arguments
291    ($UDWF:ident, $OUT_FN_NAME:ident, $UDWF_FN:ident, $DOC:expr) => {
292            #[doc = " Create a [`WindowFunction`](datafusion_expr::Expr::WindowFunction) expression for"]
293            #[doc = concat!(" `", stringify!($UDWF), "` user-defined window function.")]
294            #[doc = ""]
295            #[doc = concat!(" ", $DOC)]
296            pub fn $OUT_FN_NAME() -> datafusion_expr::Expr {
297                $UDWF_FN().call(vec![])
298            }
299    };
300
301    // 1 or more arguments
302    ($UDWF:ident, $OUT_FN_NAME:ident, [$($PARAM:ident),+], $UDWF_FN:ident, $DOC:expr) => {
303            #[doc = " Create a [`WindowFunction`](datafusion_expr::Expr::WindowFunction) expression for"]
304            #[doc = concat!(" `", stringify!($UDWF), "` user-defined window function.")]
305            #[doc = ""]
306            #[doc = concat!(" ", $DOC)]
307            pub fn $OUT_FN_NAME(
308                $($PARAM: datafusion_expr::Expr),+
309            ) -> datafusion_expr::Expr {
310                $UDWF_FN()
311                    .call(vec![$($PARAM),+])
312            }
313    };
314}
315
316/// Defines a user-defined window function.
317///
318/// Combines [`get_or_init_udwf!`] and [`create_udwf_expr!`] into a
319/// single macro for convenience.
320///
321/// # Arguments
322///
323/// * `$UDWF`: The struct which defines the [`Signature`] of the
324///   user-defined window function.
325/// * `$OUT_FN_NAME`: The basename to generate a unique function name like
326///   `$OUT_FN_NAME_udwf`.
327/// * (optional) `[$($PARAM:ident),+]`: An array of 1 or more parameters
328///   for the generated function. The type of parameters is [`Expr`].
329///   When omitted this creates a function with zero parameters.
330/// * `$DOC`: Doc comments for UDWF.
331/// * (optional) `$CTOR`: Pass a custom constructor. When omitted it
332///   automatically resolves to `$UDWF::default()`.
333///
334/// [`Signature`]: datafusion_expr::Signature
335/// [`Expr`]: datafusion_expr::Expr
336///
337/// # Usage
338///
339/// ## Expression API With Zero parameters
340/// 1. Uses default constructor for UDWF.
341///
342/// ```
343/// use arrow::datatypes::FieldRef;
344/// # use datafusion_common::arrow::datatypes::{DataType, Field};
345/// # use datafusion_expr::{PartitionEvaluator, Signature, Volatility, WindowUDFImpl};
346/// #
347/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
348/// # use datafusion_functions_window::{define_udwf_and_expr, get_or_init_udwf, create_udwf_expr};
349/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
350/// #
351/// /// 1. Defines the `simple_udwf()` user-defined window function.
352/// ///
353/// /// 2. Defines the expression API:
354/// ///     ```
355/// ///     pub fn simple() -> datafusion_expr::Expr {
356/// ///         simple_udwf().call(vec![])
357/// ///     }
358/// ///     ```
359/// define_udwf_and_expr!(
360///     SimpleUDWF,
361///     simple,
362///     simple_udwf,
363///     "a simple user-defined window function"
364/// );
365/// #
366/// # assert_eq!(simple_udwf().name(), "simple_user_defined_window_function");
367/// #
368/// #  #[derive(Debug, PartialEq, Eq, Hash)]
369/// #  struct SimpleUDWF {
370/// #      signature: Signature,
371/// #  }
372/// #
373/// #  impl Default for SimpleUDWF {
374/// #      fn default() -> Self {
375/// #          Self {
376/// #             signature: Signature::any(0, Volatility::Immutable),
377/// #          }
378/// #      }
379/// #  }
380/// #
381/// #  impl WindowUDFImpl for SimpleUDWF {
382/// #      fn name(&self) -> &str {
383/// #          "simple_user_defined_window_function"
384/// #      }
385/// #      fn signature(&self) -> &Signature {
386/// #          &self.signature
387/// #      }
388/// #      fn partition_evaluator(
389/// #          &self,
390/// #          partition_evaluator_args: PartitionEvaluatorArgs,
391/// #      ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
392/// #          unimplemented!()
393/// #      }
394/// #      fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<FieldRef> {
395/// #          Ok(Field::new(field_args.name(), DataType::Int64, false).into())
396/// #      }
397/// #  }
398/// #
399/// ```
400///
401/// 2. Uses a custom constructor for UDWF.
402///
403/// ```
404/// use arrow::datatypes::FieldRef;
405/// # use datafusion_common::arrow::datatypes::{DataType, Field};
406/// # use datafusion_expr::{PartitionEvaluator, Signature, Volatility, WindowUDFImpl};
407/// # use datafusion_functions_window::{create_udwf_expr, define_udwf_and_expr, get_or_init_udwf};
408/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
409/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
410/// #
411/// /// 1. Defines the `row_number_udwf()` user-defined window function.
412/// ///
413/// /// 2. Defines the expression API:
414/// ///     ```
415/// ///     pub fn row_number() -> datafusion_expr::Expr {
416/// ///         row_number_udwf().call(vec![])
417/// ///     }
418/// ///     ```
419/// define_udwf_and_expr!(
420///     RowNumber,
421///     row_number,
422///     row_number_udwf,
423///     "Returns a unique row number for each row in window partition beginning at 1.",
424///     RowNumber::new // <-- custom constructor
425/// );
426/// #
427/// # assert_eq!(
428/// #     row_number().name_for_alias().unwrap(),
429/// #     "row_number() ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
430/// # );
431/// #
432/// # #[derive(Debug, PartialEq, Eq, Hash)]
433/// # struct RowNumber {
434/// #     signature: Signature,
435/// # }
436/// # impl RowNumber {
437/// #     fn new() -> Self {
438/// #         Self {
439/// #             signature: Signature::any(0, Volatility::Immutable),
440/// #         }
441/// #     }
442/// # }
443/// # impl WindowUDFImpl for RowNumber {
444/// #     fn name(&self) -> &str {
445/// #         "row_number"
446/// #     }
447/// #     fn signature(&self) -> &Signature {
448/// #         &self.signature
449/// #     }
450/// #     fn partition_evaluator(
451/// #         &self,
452/// #         _partition_evaluator_args: PartitionEvaluatorArgs,
453/// #     ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
454/// #         unimplemented!()
455/// #     }
456/// #     fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<FieldRef> {
457/// #         Ok(Field::new(field_args.name(), DataType::UInt64, false).into())
458/// #     }
459/// # }
460/// ```
461///
462/// ## Expression API With Multiple Parameters
463/// 3. Uses default constructor for UDWF
464///
465/// ```
466/// use arrow::datatypes::FieldRef;
467/// #
468/// # use datafusion_expr::{
469/// #     PartitionEvaluator, Signature, TypeSignature, Volatility, WindowUDFImpl,
470/// # };
471/// #
472/// # use datafusion_functions_window::{create_udwf_expr, define_udwf_and_expr, get_or_init_udwf};
473/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
474/// #
475/// # use datafusion_common::arrow::datatypes::Field;
476/// # use datafusion_common::ScalarValue;
477/// # use datafusion_expr::{col, lit};
478/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
479/// #
480/// /// 1. Defines the `lead_udwf()` user-defined window function.
481/// ///
482/// /// 2. Defines the expression API:
483/// ///     ```
484/// ///     pub fn lead(
485/// ///         expr: datafusion_expr::Expr,
486/// ///         offset: datafusion_expr::Expr,
487/// ///         default: datafusion_expr::Expr,
488/// ///     ) -> datafusion_expr::Expr {
489/// ///         lead_udwf().call(vec![expr, offset, default])
490/// ///     }
491/// ///     ```
492/// define_udwf_and_expr!(
493///     Lead,
494///     lead,
495///     [expr, offset, default],        // <- 3 parameters
496///     lead_udwf,
497///     "user-defined window function"
498/// );
499/// #
500/// # assert_eq!(
501/// #     lead(col("a"), lit(1i64), lit(ScalarValue::Null))
502/// #         .name_for_alias()
503/// #         .unwrap(),
504/// #     "lead(a,Int64(1),NULL) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
505/// # );
506/// #
507/// # #[derive(Debug, PartialEq, Eq, Hash)]
508/// # struct Lead {
509/// #     signature: Signature,
510/// # }
511/// #
512/// # impl Default for Lead {
513/// #     fn default() -> Self {
514/// #         Self {
515/// #             signature: Signature::one_of(
516/// #                 vec![
517/// #                     TypeSignature::Any(1),
518/// #                     TypeSignature::Any(2),
519/// #                     TypeSignature::Any(3),
520/// #                 ],
521/// #                 Volatility::Immutable,
522/// #             ),
523/// #         }
524/// #     }
525/// # }
526/// #
527/// # impl WindowUDFImpl for Lead {
528/// #     fn name(&self) -> &str {
529/// #         "lead"
530/// #     }
531/// #     fn signature(&self) -> &Signature {
532/// #         &self.signature
533/// #     }
534/// #     fn partition_evaluator(
535/// #         &self,
536/// #         _partition_evaluator_args: PartitionEvaluatorArgs,
537/// #     ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
538/// #         unimplemented!()
539/// #     }
540/// #     fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<FieldRef> {
541/// #         Ok(Field::new(
542/// #             field_args.name(),
543/// #             field_args.get_input_field(0).unwrap().data_type().clone(),
544/// #             false,
545/// #         ).into())
546/// #     }
547/// # }
548/// ```
549/// 4. Uses custom constructor for UDWF
550///
551/// ```
552/// use arrow::datatypes::FieldRef;
553/// #
554/// # use datafusion_expr::{
555/// #     PartitionEvaluator, Signature, TypeSignature, Volatility, WindowUDFImpl,
556/// # };
557/// #
558/// # use datafusion_functions_window::{create_udwf_expr, define_udwf_and_expr, get_or_init_udwf};
559/// # use datafusion_functions_window_common::field::WindowUDFFieldArgs;
560/// #
561/// # use datafusion_common::arrow::datatypes::Field;
562/// # use datafusion_common::ScalarValue;
563/// # use datafusion_expr::{col, lit};
564/// # use datafusion_functions_window_common::partition::PartitionEvaluatorArgs;
565/// #
566/// /// 1. Defines the `lead_udwf()` user-defined window function.
567/// ///
568/// /// 2. Defines the expression API:
569/// ///     ```
570/// ///     pub fn lead(
571/// ///         expr: datafusion_expr::Expr,
572/// ///         offset: datafusion_expr::Expr,
573/// ///         default: datafusion_expr::Expr,
574/// ///     ) -> datafusion_expr::Expr {
575/// ///         lead_udwf().call(vec![expr, offset, default])
576/// ///     }
577/// ///     ```
578/// define_udwf_and_expr!(
579///     Lead,
580///     lead,
581///     [expr, offset, default],        // <- 3 parameters
582///     lead_udwf,
583///     "user-defined window function",
584///     Lead::new                       // <- Custom constructor
585/// );
586/// #
587/// # assert_eq!(
588/// #     lead(col("a"), lit(1i64), lit(ScalarValue::Null))
589/// #         .name_for_alias()
590/// #         .unwrap(),
591/// #     "lead(a,Int64(1),NULL) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING"
592/// # );
593/// #
594/// # #[derive(Debug, PartialEq, Eq, Hash)]
595/// # struct Lead {
596/// #     signature: Signature,
597/// # }
598/// #
599/// # impl Lead {
600/// #     fn new() -> Self {
601/// #         Self {
602/// #             signature: Signature::one_of(
603/// #                 vec![
604/// #                     TypeSignature::Any(1),
605/// #                     TypeSignature::Any(2),
606/// #                     TypeSignature::Any(3),
607/// #                 ],
608/// #                 Volatility::Immutable,
609/// #             ),
610/// #         }
611/// #     }
612/// # }
613/// #
614/// # impl WindowUDFImpl for Lead {
615/// #     fn name(&self) -> &str {
616/// #         "lead"
617/// #     }
618/// #     fn signature(&self) -> &Signature {
619/// #         &self.signature
620/// #     }
621/// #     fn partition_evaluator(
622/// #         &self,
623/// #         _partition_evaluator_args: PartitionEvaluatorArgs,
624/// #     ) -> datafusion_common::Result<Box<dyn PartitionEvaluator>> {
625/// #         unimplemented!()
626/// #     }
627/// #     fn field(&self, field_args: WindowUDFFieldArgs) -> datafusion_common::Result<FieldRef> {
628/// #         Ok(Field::new(
629/// #             field_args.name(),
630/// #             field_args.get_input_field(0).unwrap().data_type().clone(),
631/// #             false,
632/// #         ).into())
633/// #     }
634/// # }
635/// ```
636#[macro_export]
637macro_rules! define_udwf_and_expr {
638    // Defines UDWF with default constructor
639    // Defines expression API with zero parameters
640    ($UDWF:ident, $OUT_FN_NAME:ident, $UDWF_FN:ident, $DOC:expr) => {
641        get_or_init_udwf!($UDWF, $OUT_FN_NAME,$UDWF_FN, $DOC);
642        create_udwf_expr!($UDWF, $OUT_FN_NAME, $UDWF_FN, $DOC);
643    };
644
645    // Defines UDWF by passing a custom constructor
646    // Defines expression API with zero parameters
647    ($UDWF:ident, $OUT_FN_NAME:ident, $UDWF_FN:ident, $DOC:expr, $CTOR:path) => {
648        get_or_init_udwf!($UDWF, $OUT_FN_NAME, $UDWF_FN, $DOC, $CTOR);
649        create_udwf_expr!($UDWF, $OUT_FN_NAME, $UDWF_FN, $DOC);
650    };
651
652    // Defines UDWF with default constructor
653    // Defines expression API with multiple parameters
654    ($UDWF:ident, $OUT_FN_NAME:ident, [$($PARAM:ident),+],$UDWF_FN:ident, $DOC:expr) => {
655        get_or_init_udwf!($UDWF, $OUT_FN_NAME, $UDWF_FN, $DOC);
656        create_udwf_expr!($UDWF, $OUT_FN_NAME, [$($PARAM),+], $UDWF_FN, $DOC);
657    };
658
659    // Defines UDWF by passing a custom constructor
660    // Defines expression API with multiple parameters
661    ($UDWF:ident, $OUT_FN_NAME:ident, [$($PARAM:ident),+], $UDWF_FN:ident, $DOC:expr, $CTOR:path) => {
662        get_or_init_udwf!($UDWF, $OUT_FN_NAME, $UDWF_FN, $DOC, $CTOR);
663        create_udwf_expr!($UDWF, $OUT_FN_NAME, [$($PARAM),+], $UDWF_FN, $DOC);
664    };
665}