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