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}