This is an automated email from the ASF dual-hosted git repository.
comphead pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new 40d51580d4 doc-gen: migrate scalar functions (other, conditional, and
struct) documentation (#14163)
40d51580d4 is described below
commit 40d51580d432e6f8b5f0cb661870febe727889d3
Author: Ian Lai <[email protected]>
AuthorDate: Sat Jan 18 00:42:47 2025 +0800
doc-gen: migrate scalar functions (other, conditional, and struct)
documentation (#14163)
---
datafusion/functions/src/core/arrow_cast.rs | 58 ++++++++---------
datafusion/functions/src/core/arrowtypeof.rs | 48 ++++++--------
datafusion/functions/src/core/coalesce.rs | 47 ++++++--------
datafusion/functions/src/core/getfield.rs | 94 ++++++++++++---------------
datafusion/functions/src/core/greatest.rs | 46 ++++++-------
datafusion/functions/src/core/least.rs | 46 ++++++-------
datafusion/functions/src/core/named_struct.rs | 75 ++++++++++-----------
datafusion/functions/src/core/nullif.rs | 70 +++++++++-----------
datafusion/functions/src/core/nvl.rs | 70 +++++++++-----------
datafusion/functions/src/core/nvl2.rs | 77 ++++++++++------------
datafusion/functions/src/core/struct.rs | 93 ++++++++++++--------------
datafusion/functions/src/core/version.rs | 42 +++++-------
12 files changed, 336 insertions(+), 430 deletions(-)
diff --git a/datafusion/functions/src/core/arrow_cast.rs
b/datafusion/functions/src/core/arrow_cast.rs
index 3853737d7b..8e4ae36c9a 100644
--- a/datafusion/functions/src/core/arrow_cast.rs
+++ b/datafusion/functions/src/core/arrow_cast.rs
@@ -23,14 +23,13 @@ use datafusion_common::{
ExprSchema, Result, ScalarValue,
};
use std::any::Any;
-use std::sync::OnceLock;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_OTHER;
use datafusion_expr::simplify::{ExprSimplifyResult, SimplifyInfo};
use datafusion_expr::{
ColumnarValue, Documentation, Expr, ExprSchemable, ScalarUDFImpl,
Signature,
Volatility,
};
+use datafusion_macros::user_doc;
/// Implements casting to arbitrary arrow types (rather than SQL types)
///
@@ -53,6 +52,31 @@ use datafusion_expr::{
/// ```sql
/// select arrow_cast(column_x, 'Float64')
/// ```
+#[user_doc(
+ doc_section(label = "Other Functions"),
+ description = "Casts a value to a specific Arrow data type.",
+ syntax_example = "arrow_cast(expression, datatype)",
+ sql_example = r#"```sql
+> select arrow_cast(-5, 'Int8') as a,
+ arrow_cast('foo', 'Dictionary(Int32, Utf8)') as b,
+ arrow_cast('bar', 'LargeUtf8') as c,
+ arrow_cast('2023-01-02T12:53:02', 'Timestamp(Microsecond, Some("+08:00"))')
as d
+ ;
++----+-----+-----+---------------------------+
+| a | b | c | d |
++----+-----+-----+---------------------------+
+| -5 | foo | bar | 2023-01-02T12:53:02+08:00 |
++----+-----+-----+---------------------------+
+```"#,
+ argument(
+ name = "expression",
+ description = "Expression to cast. The expression can be a constant,
column, or function, and any combination of operators."
+ ),
+ argument(
+ name = "datatype",
+ description = "[Arrow data
type](https://docs.rs/arrow/latest/arrow/datatypes/enum.DataType.html) name to
cast to, as a string. The format is the same as that returned by
[`arrow_typeof`]"
+ )
+)]
#[derive(Debug)]
pub struct ArrowCastFunc {
signature: Signature,
@@ -139,38 +163,10 @@ impl ScalarUDFImpl for ArrowCastFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_arrow_cast_doc())
+ self.doc()
}
}
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_arrow_cast_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_OTHER,
- "Casts a value to a specific Arrow data type.",
- "arrow_cast(expression, datatype)")
- .with_sql_example(
- r#"```sql
-> select arrow_cast(-5, 'Int8') as a,
- arrow_cast('foo', 'Dictionary(Int32, Utf8)') as b,
- arrow_cast('bar', 'LargeUtf8') as c,
- arrow_cast('2023-01-02T12:53:02', 'Timestamp(Microsecond, Some("+08:00"))')
as d
- ;
-+----+-----+-----+---------------------------+
-| a | b | c | d |
-+----+-----+-----+---------------------------+
-| -5 | foo | bar | 2023-01-02T12:53:02+08:00 |
-+----+-----+-----+---------------------------+
-```"#,
- )
- .with_argument("expression", "Expression to cast. The expression
can be a constant, column, or function, and any combination of operators.")
- .with_argument("datatype", "[Arrow data
type](https://docs.rs/arrow/latest/arrow/datatypes/enum.DataType.html) name to
cast to, as a string. The format is the same as that returned by
[`arrow_typeof`]")
- .build()
- })
-}
-
/// Returns the requested type from the arguments
fn data_type_from_args(args: &[Expr]) -> Result<DataType> {
if args.len() != 2 {
diff --git a/datafusion/functions/src/core/arrowtypeof.rs
b/datafusion/functions/src/core/arrowtypeof.rs
index 54684c6f0b..8a282beb1d 100644
--- a/datafusion/functions/src/core/arrowtypeof.rs
+++ b/datafusion/functions/src/core/arrowtypeof.rs
@@ -17,12 +17,29 @@
use arrow::datatypes::DataType;
use datafusion_common::{exec_err, Result, ScalarValue};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_OTHER;
use datafusion_expr::{ColumnarValue, Documentation};
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
use std::any::Any;
-use std::sync::OnceLock;
+#[user_doc(
+ doc_section(label = "Other Functions"),
+ description = "Returns the name of the underlying [Arrow data
type](https://docs.rs/arrow/latest/arrow/datatypes/enum.DataType.html) of the
expression.",
+ syntax_example = "arrow_typeof(expression)",
+ sql_example = r#"```sql
+> select arrow_typeof('foo'), arrow_typeof(1);
++---------------------------+------------------------+
+| arrow_typeof(Utf8("foo")) | arrow_typeof(Int64(1)) |
++---------------------------+------------------------+
+| Utf8 | Int64 |
++---------------------------+------------------------+
+```
+"#,
+ argument(
+ name = "expression",
+ description = "Expression to evaluate. The expression can be a
constant, column, or function, and any combination of operators."
+ )
+)]
#[derive(Debug)]
pub struct ArrowTypeOfFunc {
signature: Signature,
@@ -77,31 +94,6 @@ impl ScalarUDFImpl for ArrowTypeOfFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_arrowtypeof_doc())
+ self.doc()
}
}
-
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_arrowtypeof_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_OTHER,
- "Returns the name of the underlying [Arrow data
type](https://docs.rs/arrow/latest/arrow/datatypes/enum.DataType.html) of the
expression.",
-
- "arrow_typeof(expression)")
- .with_sql_example(
- r#"```sql
-> select arrow_typeof('foo'), arrow_typeof(1);
-+---------------------------+------------------------+
-| arrow_typeof(Utf8("foo")) | arrow_typeof(Int64(1)) |
-+---------------------------+------------------------+
-| Utf8 | Int64 |
-+---------------------------+------------------------+
-```
-"#,
- )
- .with_argument("expression", "Expression to evaluate. The
expression can be a constant, column, or function, and any combination of
operators.")
- .build()
- })
-}
diff --git a/datafusion/functions/src/core/coalesce.rs
b/datafusion/functions/src/core/coalesce.rs
index 4f9e83fbf0..bfd69bab66 100644
--- a/datafusion/functions/src/core/coalesce.rs
+++ b/datafusion/functions/src/core/coalesce.rs
@@ -21,13 +21,29 @@ use arrow::compute::{and, is_not_null, is_null};
use arrow::datatypes::DataType;
use datafusion_common::{exec_err, ExprSchema, Result};
use datafusion_expr::binary::try_type_union_resolution;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_CONDITIONAL;
use datafusion_expr::{ColumnarValue, Documentation, Expr, ExprSchemable};
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
use itertools::Itertools;
use std::any::Any;
-use std::sync::OnceLock;
+#[user_doc(
+ doc_section(label = "Conditional Functions"),
+ description = "Returns the first of its arguments that is not _null_.
Returns _null_ if all arguments are _null_. This function is often used to
substitute a default value for _null_ values.",
+ syntax_example = "coalesce(expression1[, ..., expression_n])",
+ sql_example = r#"```sql
+> select coalesce(null, null, 'datafusion');
++----------------------------------------+
+| coalesce(NULL,NULL,Utf8("datafusion")) |
++----------------------------------------+
+| datafusion |
++----------------------------------------+
+```"#,
+ argument(
+ name = "expression1, expression_n",
+ description = "Expression to use if previous expressions are _null_.
Can be a constant, column, or function, and any combination of arithmetic
operators. Pass as many expression arguments as necessary."
+ )
+)]
#[derive(Debug)]
pub struct CoalesceFunc {
signature: Signature,
@@ -146,35 +162,10 @@ impl ScalarUDFImpl for CoalesceFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_coalesce_doc())
+ self.doc()
}
}
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_coalesce_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_CONDITIONAL,
- "Returns the first of its arguments that is not _null_. Returns
_null_ if all arguments are _null_. This function is often used to substitute a
default value for _null_ values.",
- "coalesce(expression1[, ..., expression_n])")
- .with_sql_example(r#"```sql
-> select coalesce(null, null, 'datafusion');
-+----------------------------------------+
-| coalesce(NULL,NULL,Utf8("datafusion")) |
-+----------------------------------------+
-| datafusion |
-+----------------------------------------+
-```"#,
- )
- .with_argument(
- "expression1, expression_n",
- "Expression to use if previous expressions are _null_. Can be
a constant, column, or function, and any combination of arithmetic operators.
Pass as many expression arguments as necessary."
- )
- .build()
- })
-}
-
#[cfg(test)]
mod test {
use arrow::datatypes::DataType;
diff --git a/datafusion/functions/src/core/getfield.rs
b/datafusion/functions/src/core/getfield.rs
index 5c8e1e803e..f9e700b5db 100644
--- a/datafusion/functions/src/core/getfield.rs
+++ b/datafusion/functions/src/core/getfield.rs
@@ -23,12 +23,52 @@ use datafusion_common::cast::{as_map_array,
as_struct_array};
use datafusion_common::{
exec_err, plan_datafusion_err, plan_err, ExprSchema, Result, ScalarValue,
};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_OTHER;
use datafusion_expr::{ColumnarValue, Documentation, Expr, ExprSchemable};
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
+#[user_doc(
+ doc_section(label = "Other Functions"),
+ description = r#"Returns a field within a map or a struct with the given
key.
+ Note: most users invoke `get_field` indirectly via field access
+ syntax such as `my_struct_col['field_name']` which results in a call to
+ `get_field(my_struct_col, 'field_name')`."#,
+ syntax_example = "get_field(expression1, expression2)",
+ sql_example = r#"```sql
+> create table t (idx varchar, v varchar) as values ('data','fusion'),
('apache', 'arrow');
+> select struct(idx, v) from t as c;
++-------------------------+
+| struct(c.idx,c.v) |
++-------------------------+
+| {c0: data, c1: fusion} |
+| {c0: apache, c1: arrow} |
++-------------------------+
+> select get_field((select struct(idx, v) from t), 'c0');
++-----------------------+
+| struct(t.idx,t.v)[c0] |
++-----------------------+
+| data |
+| apache |
++-----------------------+
+> select get_field((select struct(idx, v) from t), 'c1');
++-----------------------+
+| struct(t.idx,t.v)[c1] |
++-----------------------+
+| fusion |
+| arrow |
++-----------------------+
+```"#,
+ argument(
+ name = "expression1",
+ description = "The map or struct to retrieve a field for."
+ ),
+ argument(
+ name = "expression2",
+ description = "The field name in the map or struct to retrieve data
for. Must evaluate to a string."
+ )
+)]
#[derive(Debug)]
pub struct GetFieldFunc {
signature: Signature,
@@ -241,54 +281,6 @@ impl ScalarUDFImpl for GetFieldFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_getfield_doc())
+ self.doc()
}
}
-
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_getfield_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_OTHER,
- r#"Returns a field within a map or a struct with the given key.
-Note: most users invoke `get_field` indirectly via field access
-syntax such as `my_struct_col['field_name']` which results in a call to
-`get_field(my_struct_col, 'field_name')`."#,
- "get_field(expression1, expression2)")
- .with_sql_example(r#"```sql
-> create table t (idx varchar, v varchar) as values ('data','fusion'),
('apache', 'arrow');
-> select struct(idx, v) from t as c;
-+-------------------------+
-| struct(c.idx,c.v) |
-+-------------------------+
-| {c0: data, c1: fusion} |
-| {c0: apache, c1: arrow} |
-+-------------------------+
-> select get_field((select struct(idx, v) from t), 'c0');
-+-----------------------+
-| struct(t.idx,t.v)[c0] |
-+-----------------------+
-| data |
-| apache |
-+-----------------------+
-> select get_field((select struct(idx, v) from t), 'c1');
-+-----------------------+
-| struct(t.idx,t.v)[c1] |
-+-----------------------+
-| fusion |
-| arrow |
-+-----------------------+
-```
- "#)
- .with_argument(
- "expression1",
- "The map or struct to retrieve a field for."
- )
- .with_argument(
- "expression2",
- "The field name in the map or struct to retrieve data for.
Must evaluate to a string."
- )
- .build()
- })
-}
diff --git a/datafusion/functions/src/core/greatest.rs
b/datafusion/functions/src/core/greatest.rs
index 654b2a2987..7ad8c73728 100644
--- a/datafusion/functions/src/core/greatest.rs
+++ b/datafusion/functions/src/core/greatest.rs
@@ -23,11 +23,10 @@ use arrow::datatypes::DataType;
use arrow_buffer::BooleanBuffer;
use datafusion_common::{internal_err, Result, ScalarValue};
use datafusion_doc::Documentation;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_CONDITIONAL;
use datafusion_expr::ColumnarValue;
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
use std::any::Any;
-use std::sync::OnceLock;
const SORT_OPTIONS: SortOptions = SortOptions {
// We want greatest first
@@ -37,6 +36,23 @@ const SORT_OPTIONS: SortOptions = SortOptions {
nulls_first: true,
};
+#[user_doc(
+ doc_section(label = "Conditional Functions"),
+ description = "Returns the greatest value in a list of expressions.
Returns _null_ if all expressions are _null_.",
+ syntax_example = "greatest(expression1[, ..., expression_n])",
+ sql_example = r#"```sql
+> select greatest(4, 7, 5);
++---------------------------+
+| greatest(4,7,5) |
++---------------------------+
+| 7 |
++---------------------------+
+```"#,
+ argument(
+ name = "expression1, expression_n",
+ description = "Expressions to compare and return the greatest value..
Can be a constant, column, or function, and any combination of arithmetic
operators. Pass as many expression arguments as necessary."
+ )
+)]
#[derive(Debug)]
pub struct GreatestFunc {
signature: Signature,
@@ -139,33 +155,9 @@ impl ScalarUDFImpl for GreatestFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_greatest_doc())
+ self.doc()
}
}
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_greatest_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_CONDITIONAL,
- "Returns the greatest value in a list of expressions. Returns
_null_ if all expressions are _null_.",
- "greatest(expression1[, ..., expression_n])")
- .with_sql_example(r#"```sql
-> select greatest(4, 7, 5);
-+---------------------------+
-| greatest(4,7,5) |
-+---------------------------+
-| 7 |
-+---------------------------+
-```"#,
- )
- .with_argument(
- "expression1, expression_n",
- "Expressions to compare and return the greatest value.. Can be
a constant, column, or function, and any combination of arithmetic operators.
Pass as many expression arguments as necessary."
- )
- .build()
- })
-}
#[cfg(test)]
mod test {
diff --git a/datafusion/functions/src/core/least.rs
b/datafusion/functions/src/core/least.rs
index 0850907277..02299feb9b 100644
--- a/datafusion/functions/src/core/least.rs
+++ b/datafusion/functions/src/core/least.rs
@@ -23,11 +23,10 @@ use arrow::datatypes::DataType;
use arrow_buffer::BooleanBuffer;
use datafusion_common::{internal_err, Result, ScalarValue};
use datafusion_doc::Documentation;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_CONDITIONAL;
use datafusion_expr::ColumnarValue;
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
use std::any::Any;
-use std::sync::OnceLock;
const SORT_OPTIONS: SortOptions = SortOptions {
// Having the smallest result first
@@ -37,6 +36,23 @@ const SORT_OPTIONS: SortOptions = SortOptions {
nulls_first: false,
};
+#[user_doc(
+ doc_section(label = "Conditional Functions"),
+ description = "Returns the smallest value in a list of expressions.
Returns _null_ if all expressions are _null_.",
+ syntax_example = "least(expression1[, ..., expression_n])",
+ sql_example = r#"```sql
+> select least(4, 7, 5);
++---------------------------+
+| least(4,7,5) |
++---------------------------+
+| 4 |
++---------------------------+
+```"#,
+ argument(
+ name = "expression1, expression_n",
+ description = "Expressions to compare and return the smallest value.
Can be a constant, column, or function, and any combination of arithmetic
operators. Pass as many expression arguments as necessary."
+ )
+)]
#[derive(Debug)]
pub struct LeastFunc {
signature: Signature,
@@ -152,33 +168,9 @@ impl ScalarUDFImpl for LeastFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_smallest_doc())
+ self.doc()
}
}
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_smallest_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_CONDITIONAL,
- "Returns the smallest value in a list of expressions. Returns
_null_ if all expressions are _null_.",
- "least(expression1[, ..., expression_n])")
- .with_sql_example(r#"```sql
-> select least(4, 7, 5);
-+---------------------------+
-| least(4,7,5) |
-+---------------------------+
-| 4 |
-+---------------------------+
-```"#,
- )
- .with_argument(
- "expression1, expression_n",
- "Expressions to compare and return the smallest value. Can be
a constant, column, or function, and any combination of arithmetic operators.
Pass as many expression arguments as necessary."
- )
- .build()
- })
-}
#[cfg(test)]
mod test {
diff --git a/datafusion/functions/src/core/named_struct.rs
b/datafusion/functions/src/core/named_struct.rs
index 556cad1de1..527ec48fcc 100644
--- a/datafusion/functions/src/core/named_struct.rs
+++ b/datafusion/functions/src/core/named_struct.rs
@@ -18,11 +18,11 @@
use arrow::array::StructArray;
use arrow::datatypes::{DataType, Field, Fields};
use datafusion_common::{exec_err, internal_err, HashSet, Result, ScalarValue};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRUCT;
use datafusion_expr::{ColumnarValue, Documentation, Expr, ExprSchemable};
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
/// Put values in a struct array.
fn named_struct_expr(args: &[ColumnarValue]) -> Result<ColumnarValue> {
@@ -83,6 +83,38 @@ fn named_struct_expr(args: &[ColumnarValue]) ->
Result<ColumnarValue> {
Ok(ColumnarValue::Array(Arc::new(struct_array)))
}
+#[user_doc(
+ doc_section(label = "Struct Functions"),
+ description = "Returns an Arrow struct using the specified name and input
expressions pairs.",
+ syntax_example = "named_struct(expression1_name, expression1_input[, ...,
expression_n_name, expression_n_input])",
+ sql_example = r#"
+For example, this query converts two columns `a` and `b` to a single column
with
+a struct type of fields `field_a` and `field_b`:
+```sql
+> select * from t;
++---+---+
+| a | b |
++---+---+
+| 1 | 2 |
+| 3 | 4 |
++---+---+
+> select named_struct('field_a', a, 'field_b', b) from t;
++-------------------------------------------------------+
+| named_struct(Utf8("field_a"),t.a,Utf8("field_b"),t.b) |
++-------------------------------------------------------+
+| {field_a: 1, field_b: 2} |
+| {field_a: 3, field_b: 4} |
++-------------------------------------------------------+
+```"#,
+ argument(
+ name = "expression_n_name",
+ description = "Name of the column field. Must be a constant string."
+ ),
+ argument(
+ name = "expression_n_input",
+ description = "Expression to include in the output struct. Can be a
constant, column, or function, and any combination of arithmetic or string
operators."
+ )
+)]
#[derive(Debug)]
pub struct NamedStructFunc {
signature: Signature,
@@ -167,43 +199,6 @@ impl ScalarUDFImpl for NamedStructFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_named_struct_doc())
+ self.doc()
}
}
-
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_named_struct_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_STRUCT,
- "Returns an Arrow struct using the specified name and input
expressions pairs.",
- "named_struct(expression1_name, expression1_input[, ...,
expression_n_name, expression_n_input])")
- .with_sql_example(r#"
-For example, this query converts two columns `a` and `b` to a single column
with
-a struct type of fields `field_a` and `field_b`:
-```sql
-> select * from t;
-+---+---+
-| a | b |
-+---+---+
-| 1 | 2 |
-| 3 | 4 |
-+---+---+
-> select named_struct('field_a', a, 'field_b', b) from t;
-+-------------------------------------------------------+
-| named_struct(Utf8("field_a"),t.a,Utf8("field_b"),t.b) |
-+-------------------------------------------------------+
-| {field_a: 1, field_b: 2} |
-| {field_a: 3, field_b: 4} |
-+-------------------------------------------------------+
-```
-"#)
- .with_argument(
- "expression_n_name",
- "Name of the column field. Must be a constant string."
- )
- .with_argument("expression_n_input", "Expression to include in the
output struct. Can be a constant, column, or function, and any combination of
arithmetic or string operators.")
- .build()
- })
-}
diff --git a/datafusion/functions/src/core/nullif.rs
b/datafusion/functions/src/core/nullif.rs
index 7c86047a02..9dd4898267 100644
--- a/datafusion/functions/src/core/nullif.rs
+++ b/datafusion/functions/src/core/nullif.rs
@@ -22,11 +22,37 @@ use datafusion_expr::{ColumnarValue, Documentation};
use arrow::compute::kernels::cmp::eq;
use arrow::compute::kernels::nullif::nullif;
use datafusion_common::ScalarValue;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_CONDITIONAL;
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
use std::any::Any;
-use std::sync::OnceLock;
-
+#[user_doc(
+ doc_section(label = "Conditional Functions"),
+ description = "Returns _null_ if _expression1_ equals _expression2_;
otherwise it returns _expression1_.
+This can be used to perform the inverse operation of [`coalesce`](#coalesce).",
+ syntax_example = "nullif(expression1, expression2)",
+ sql_example = r#"```sql
+> select nullif('datafusion', 'data');
++-----------------------------------------+
+| nullif(Utf8("datafusion"),Utf8("data")) |
++-----------------------------------------+
+| datafusion |
++-----------------------------------------+
+> select nullif('datafusion', 'datafusion');
++-----------------------------------------------+
+| nullif(Utf8("datafusion"),Utf8("datafusion")) |
++-----------------------------------------------+
+| |
++-----------------------------------------------+
+```"#,
+ argument(
+ name = "expression1",
+ description = "Expression to compare and return if equal to
expression2. Can be a constant, column, or function, and any combination of
operators."
+ ),
+ argument(
+ name = "expression2",
+ description = "Expression to compare to expression1. Can be a
constant, column, or function, and any combination of operators."
+ )
+)]
#[derive(Debug)]
pub struct NullIfFunc {
signature: Signature,
@@ -84,46 +110,10 @@ impl ScalarUDFImpl for NullIfFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_nullif_doc())
+ self.doc()
}
}
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_nullif_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_CONDITIONAL,
- "Returns _null_ if _expression1_ equals _expression2_; otherwise
it returns _expression1_.
-This can be used to perform the inverse operation of [`coalesce`](#coalesce).",
- "nullif(expression1, expression2)")
- .with_sql_example(r#"```sql
-> select nullif('datafusion', 'data');
-+-----------------------------------------+
-| nullif(Utf8("datafusion"),Utf8("data")) |
-+-----------------------------------------+
-| datafusion |
-+-----------------------------------------+
-> select nullif('datafusion', 'datafusion');
-+-----------------------------------------------+
-| nullif(Utf8("datafusion"),Utf8("datafusion")) |
-+-----------------------------------------------+
-| |
-+-----------------------------------------------+
-```
-"#)
- .with_argument(
- "expression1",
- "Expression to compare and return if equal to expression2. Can
be a constant, column, or function, and any combination of operators."
- )
- .with_argument(
- "expression2",
- "Expression to compare to expression1. Can be a constant,
column, or function, and any combination of operators."
- )
- .build()
- })
-}
-
/// Implements NULLIF(expr1, expr2)
/// Args: 0 - left expr is any array
/// 1 - if the left is equal to this expr2, then the result is NULL,
otherwise left value is passed.
diff --git a/datafusion/functions/src/core/nvl.rs
b/datafusion/functions/src/core/nvl.rs
index eb8c926060..bcd4b3908d 100644
--- a/datafusion/functions/src/core/nvl.rs
+++ b/datafusion/functions/src/core/nvl.rs
@@ -20,12 +20,39 @@ use arrow::compute::is_not_null;
use arrow::compute::kernels::zip::zip;
use arrow::datatypes::DataType;
use datafusion_common::{internal_err, Result};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_CONDITIONAL;
use datafusion_expr::{
ColumnarValue, Documentation, ScalarUDFImpl, Signature, Volatility,
};
-use std::sync::{Arc, OnceLock};
-
+use datafusion_macros::user_doc;
+use std::sync::Arc;
+#[user_doc(
+ doc_section(label = "Conditional Functions"),
+ description = "Returns _expression2_ if _expression1_ is NULL otherwise it
returns _expression1_.",
+ syntax_example = "nvl(expression1, expression2)",
+ sql_example = r#"```sql
+> select nvl(null, 'a');
++---------------------+
+| nvl(NULL,Utf8("a")) |
++---------------------+
+| a |
++---------------------+\
+> select nvl('b', 'a');
++--------------------------+
+| nvl(Utf8("b"),Utf8("a")) |
++--------------------------+
+| b |
++--------------------------+
+```
+"#,
+ argument(
+ name = "expression1",
+ description = "Expression to return if not null. Can be a constant,
column, or function, and any combination of operators."
+ ),
+ argument(
+ name = "expression2",
+ description = "Expression to return if expr1 is null. Can be a
constant, column, or function, and any combination of operators."
+ )
+)]
#[derive(Debug)]
pub struct NVLFunc {
signature: Signature,
@@ -101,45 +128,10 @@ impl ScalarUDFImpl for NVLFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_nvl_doc())
+ self.doc()
}
}
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_nvl_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_CONDITIONAL,
- "Returns _expression2_ if _expression1_ is NULL otherwise it
returns _expression1_.",
- "nvl(expression1, expression2)")
- .with_sql_example(r#"```sql
-> select nvl(null, 'a');
-+---------------------+
-| nvl(NULL,Utf8("a")) |
-+---------------------+
-| a |
-+---------------------+\
-> select nvl('b', 'a');
-+--------------------------+
-| nvl(Utf8("b"),Utf8("a")) |
-+--------------------------+
-| b |
-+--------------------------+
-```
-"#)
- .with_argument(
- "expression1",
- "Expression to return if not null. Can be a constant, column,
or function, and any combination of operators."
- )
- .with_argument(
- "expression2",
- "Expression to return if expr1 is null. Can be a constant,
column, or function, and any combination of operators."
- )
- .build()
- })
-}
-
fn nvl_func(args: &[ColumnarValue]) -> Result<ColumnarValue> {
if args.len() != 2 {
return internal_err!(
diff --git a/datafusion/functions/src/core/nvl2.rs
b/datafusion/functions/src/core/nvl2.rs
index a372926832..70b762a49c 100644
--- a/datafusion/functions/src/core/nvl2.rs
+++ b/datafusion/functions/src/core/nvl2.rs
@@ -20,13 +20,45 @@ use arrow::compute::is_not_null;
use arrow::compute::kernels::zip::zip;
use arrow::datatypes::DataType;
use datafusion_common::{exec_err, internal_err, Result};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_CONDITIONAL;
use datafusion_expr::{
type_coercion::binary::comparison_coercion, ColumnarValue, Documentation,
ScalarUDFImpl, Signature, Volatility,
};
-use std::sync::{Arc, OnceLock};
+use datafusion_macros::user_doc;
+use std::sync::Arc;
+#[user_doc(
+ doc_section(label = "Conditional Functions"),
+ description = "Returns _expression2_ if _expression1_ is not NULL;
otherwise it returns _expression3_.",
+ syntax_example = "nvl2(expression1, expression2, expression3)",
+ sql_example = r#"```sql
+> select nvl2(null, 'a', 'b');
++--------------------------------+
+| nvl2(NULL,Utf8("a"),Utf8("b")) |
++--------------------------------+
+| b |
++--------------------------------+
+> select nvl2('data', 'a', 'b');
++----------------------------------------+
+| nvl2(Utf8("data"),Utf8("a"),Utf8("b")) |
++----------------------------------------+
+| a |
++----------------------------------------+
+```
+"#,
+ argument(
+ name = "expression1",
+ description = "Expression to test for null. Can be a constant, column,
or function, and any combination of operators."
+ ),
+ argument(
+ name = "expression2",
+ description = "Expression to return if expr1 is not null. Can be a
constant, column, or function, and any combination of operators."
+ ),
+ argument(
+ name = "expression3",
+ description = "Expression to return if expr1 is null. Can be a
constant, column, or function, and any combination of operators."
+ )
+)]
#[derive(Debug)]
pub struct NVL2Func {
signature: Signature,
@@ -97,49 +129,10 @@ impl ScalarUDFImpl for NVL2Func {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_nvl2_doc())
+ self.doc()
}
}
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_nvl2_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_CONDITIONAL,
- "Returns _expression2_ if _expression1_ is not NULL; otherwise it
returns _expression3_.",
- "nvl2(expression1, expression2, expression3)")
- .with_sql_example(r#"```sql
-> select nvl2(null, 'a', 'b');
-+--------------------------------+
-| nvl2(NULL,Utf8("a"),Utf8("b")) |
-+--------------------------------+
-| b |
-+--------------------------------+
-> select nvl2('data', 'a', 'b');
-+----------------------------------------+
-| nvl2(Utf8("data"),Utf8("a"),Utf8("b")) |
-+----------------------------------------+
-| a |
-+----------------------------------------+
-```
-"#)
- .with_argument(
- "expression1",
- "Expression to test for null. Can be a constant, column, or
function, and any combination of operators."
- )
- .with_argument(
- "expression2",
- "Expression to return if expr1 is not null. Can be a constant,
column, or function, and any combination of operators."
- )
- .with_argument(
- "expression3",
- "Expression to return if expr1 is null. Can be a constant,
column, or function, and any combination of operators."
- )
- .build()
- })
-}
-
fn nvl2_func(args: &[ColumnarValue]) -> Result<ColumnarValue> {
if args.len() != 3 {
return internal_err!(
diff --git a/datafusion/functions/src/core/struct.rs
b/datafusion/functions/src/core/struct.rs
index b7579ba5e4..f5bff2cc72 100644
--- a/datafusion/functions/src/core/struct.rs
+++ b/datafusion/functions/src/core/struct.rs
@@ -18,11 +18,11 @@
use arrow::array::{ArrayRef, StructArray};
use arrow::datatypes::{DataType, Field, Fields};
use datafusion_common::{exec_err, Result};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRUCT;
use datafusion_expr::{ColumnarValue, Documentation};
use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
fn array_struct(args: &[ArrayRef]) -> Result<ArrayRef> {
// do not accept 0 arguments.
@@ -55,6 +55,46 @@ fn struct_expr(args: &[ColumnarValue]) ->
Result<ColumnarValue> {
Ok(ColumnarValue::Array(array_struct(arrays.as_slice())?))
}
+#[user_doc(
+ doc_section(label = "Struct Functions"),
+ description = "Returns an Arrow struct using the specified input
expressions optionally named.
+Fields in the returned struct use the optional name or the `cN` naming
convention.
+For example: `c0`, `c1`, `c2`, etc.",
+ syntax_example = "struct(expression1[, ..., expression_n])",
+ sql_example = r#"For example, this query converts two columns `a` and `b`
to a single column with
+a struct type of fields `field_a` and `c1`:
+```sql
+> select * from t;
++---+---+
+| a | b |
++---+---+
+| 1 | 2 |
+| 3 | 4 |
++---+---+
+
+-- use default names `c0`, `c1`
+> select struct(a, b) from t;
++-----------------+
+| struct(t.a,t.b) |
++-----------------+
+| {c0: 1, c1: 2} |
+| {c0: 3, c1: 4} |
++-----------------+
+
+-- name the first field `field_a`
+select struct(a as field_a, b) from t;
++--------------------------------------------------+
+| named_struct(Utf8("field_a"),t.a,Utf8("c1"),t.b) |
++--------------------------------------------------+
+| {field_a: 1, c1: 2} |
+| {field_a: 3, c1: 4} |
++--------------------------------------------------+
+```"#,
+ argument(
+ name = "expression1, expression_n",
+ description = "Expression to include in the output struct. Can be a
constant, column, or function, any combination of arithmetic or string
operators."
+ )
+)]
#[derive(Debug)]
pub struct StructFunc {
signature: Signature,
@@ -110,53 +150,6 @@ impl ScalarUDFImpl for StructFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_struct_doc())
+ self.doc()
}
}
-
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_struct_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_STRUCT,
- "Returns an Arrow struct using the specified input expressions
optionally named.
-Fields in the returned struct use the optional name or the `cN` naming
convention.
-For example: `c0`, `c1`, `c2`, etc.",
- "struct(expression1[, ..., expression_n])")
- .with_sql_example(r#"For example, this query converts two columns
`a` and `b` to a single column with
-a struct type of fields `field_a` and `c1`:
-```sql
-> select * from t;
-+---+---+
-| a | b |
-+---+---+
-| 1 | 2 |
-| 3 | 4 |
-+---+---+
-
--- use default names `c0`, `c1`
-> select struct(a, b) from t;
-+-----------------+
-| struct(t.a,t.b) |
-+-----------------+
-| {c0: 1, c1: 2} |
-| {c0: 3, c1: 4} |
-+-----------------+
-
--- name the first field `field_a`
-select struct(a as field_a, b) from t;
-+--------------------------------------------------+
-| named_struct(Utf8("field_a"),t.a,Utf8("c1"),t.b) |
-+--------------------------------------------------+
-| {field_a: 1, c1: 2} |
-| {field_a: 3, c1: 4} |
-+--------------------------------------------------+
-```
-"#)
- .with_argument(
- "expression1, expression_n",
- "Expression to include in the output struct. Can be a
constant, column, or function, any combination of arithmetic or string
operators.")
- .build()
- })
-}
diff --git a/datafusion/functions/src/core/version.rs
b/datafusion/functions/src/core/version.rs
index bfc87f28eb..9085407314 100644
--- a/datafusion/functions/src/core/version.rs
+++ b/datafusion/functions/src/core/version.rs
@@ -19,13 +19,24 @@
use arrow::datatypes::DataType;
use datafusion_common::{internal_err, plan_err, Result, ScalarValue};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_OTHER;
use datafusion_expr::{
ColumnarValue, Documentation, ScalarUDFImpl, Signature, Volatility,
};
+use datafusion_macros::user_doc;
use std::any::Any;
-use std::sync::OnceLock;
-
+#[user_doc(
+ doc_section(label = "Other Functions"),
+ description = "Returns the version of DataFusion.",
+ syntax_example = "version()",
+ sql_example = r#"```sql
+> select version();
++--------------------------------------------+
+| version() |
++--------------------------------------------+
+| Apache DataFusion 42.0.0, aarch64 on macos |
++--------------------------------------------+
+```"#
+)]
#[derive(Debug)]
pub struct VersionFunc {
signature: Signature,
@@ -86,33 +97,10 @@ impl ScalarUDFImpl for VersionFunc {
}
fn documentation(&self) -> Option<&Documentation> {
- Some(get_version_doc())
+ self.doc()
}
}
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_version_doc() -> &'static Documentation {
- DOCUMENTATION.get_or_init(|| {
- Documentation::builder(
- DOC_SECTION_OTHER,
- "Returns the version of DataFusion.",
- "version()",
- )
- .with_sql_example(
- r#"```sql
-> select version();
-+--------------------------------------------+
-| version() |
-+--------------------------------------------+
-| Apache DataFusion 42.0.0, aarch64 on macos |
-+--------------------------------------------+
-```"#,
- )
- .build()
- })
-}
-
#[cfg(test)]
mod test {
use super::*;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]