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}