This is an automated email from the ASF dual-hosted git repository.

mneumann 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 e59045d9ed doc-gen: migrate scalar functions (string) documentation 
2/4 (#13925)
e59045d9ed is described below

commit e59045d9edee509bff325160d0e110ab013253a9
Author: Ian Lai <[email protected]>
AuthorDate: Fri Jan 3 20:39:27 2025 +0800

    doc-gen: migrate scalar functions (string) documentation 2/4 (#13925)
    
    * doc-gen: migrate scalar functions (string) documentation 2/4
    
    * doc-gen: update function docs
    
    * doc: fix related udf order for upper function in documentation
    
    * Update datafusion/functions/src/string/concat_ws.rs
    
    * Update datafusion/functions/src/string/concat_ws.rs
    
    * Update datafusion/functions/src/string/concat_ws.rs
    
    * doc-gen: update function docs
    
    ---------
    
    Co-authored-by: Cheng-Yuan-Lai <a186235@g,ail.com>
    Co-authored-by: Oleks V <[email protected]>
---
 datafusion/functions/src/string/concat.rs      | 51 +++++++++------------
 datafusion/functions/src/string/concat_ws.rs   | 62 ++++++++++++--------------
 datafusion/functions/src/string/ends_with.rs   | 58 ++++++++++--------------
 datafusion/functions/src/string/levenshtein.rs | 49 ++++++++++----------
 datafusion/functions/src/string/lower.rs       | 46 ++++++++-----------
 datafusion/functions/src/string/overlay.rs     | 53 +++++++++++-----------
 datafusion/functions/src/string/upper.rs       | 47 ++++++++-----------
 datafusion/functions/src/unicode/initcap.rs    | 50 +++++++++------------
 8 files changed, 181 insertions(+), 235 deletions(-)

diff --git a/datafusion/functions/src/string/concat.rs 
b/datafusion/functions/src/string/concat.rs
index f4848c1315..87ac979bc0 100644
--- a/datafusion/functions/src/string/concat.rs
+++ b/datafusion/functions/src/string/concat.rs
@@ -19,7 +19,7 @@ use arrow::array::{as_largestring_array, Array};
 use arrow::datatypes::DataType;
 use datafusion_expr::sort_properties::ExprProperties;
 use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
 
 use crate::string::concat;
 use crate::strings::{
@@ -28,11 +28,30 @@ use crate::strings::{
 use datafusion_common::cast::{as_string_array, as_string_view_array};
 use datafusion_common::{internal_err, plan_err, Result, ScalarValue};
 use datafusion_expr::expr::ScalarFunction;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRING;
 use datafusion_expr::simplify::{ExprSimplifyResult, SimplifyInfo};
 use datafusion_expr::{lit, ColumnarValue, Documentation, Expr, Volatility};
 use datafusion_expr::{ScalarUDFImpl, Signature};
+use datafusion_macros::user_doc;
 
+#[user_doc(
+    doc_section(label = "String Functions"),
+    description = "Concatenates multiple strings together.",
+    syntax_example = "concat(str[, ..., str_n])",
+    sql_example = r#"```sql
+> select concat('data', 'f', 'us', 'ion');
++-------------------------------------------------------+
+| concat(Utf8("data"),Utf8("f"),Utf8("us"),Utf8("ion")) |
++-------------------------------------------------------+
+| datafusion                                            |
++-------------------------------------------------------+
+```"#,
+    standard_argument(name = "str", prefix = "String"),
+    argument(
+        name = "str_n",
+        description = "Subsequent string expressions to concatenate."
+    ),
+    related_udf(name = "concat_ws")
+)]
 #[derive(Debug)]
 pub struct ConcatFunc {
     signature: Signature,
@@ -264,7 +283,7 @@ impl ScalarUDFImpl for ConcatFunc {
     }
 
     fn documentation(&self) -> Option<&Documentation> {
-        Some(get_concat_doc())
+        self.doc()
     }
 
     fn preserves_lex_ordering(&self, _inputs: &[ExprProperties]) -> 
Result<bool> {
@@ -272,32 +291,6 @@ impl ScalarUDFImpl for ConcatFunc {
     }
 }
 
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_concat_doc() -> &'static Documentation {
-    DOCUMENTATION.get_or_init(|| {
-        Documentation::builder(
-            DOC_SECTION_STRING,
-            "Concatenates multiple strings together.",
-            "concat(str[, ..., str_n])",
-        )
-        .with_sql_example(
-            r#"```sql
-> select concat('data', 'f', 'us', 'ion');
-+-------------------------------------------------------+
-| concat(Utf8("data"),Utf8("f"),Utf8("us"),Utf8("ion")) |
-+-------------------------------------------------------+
-| datafusion                                            |
-+-------------------------------------------------------+
-```"#,
-        )
-        .with_standard_argument("str", Some("String"))
-        .with_argument("str_n", "Subsequent string expressions to 
concatenate.")
-        .with_related_udf("concat_ws")
-        .build()
-    })
-}
-
 pub fn simplify_concat(args: Vec<Expr>) -> Result<ExprSimplifyResult> {
     let mut new_args = Vec::with_capacity(args.len());
     let mut contiguous_scalar = "".to_string();
diff --git a/datafusion/functions/src/string/concat_ws.rs 
b/datafusion/functions/src/string/concat_ws.rs
index 7db8dbec4a..821bb48a8c 100644
--- a/datafusion/functions/src/string/concat_ws.rs
+++ b/datafusion/functions/src/string/concat_ws.rs
@@ -17,7 +17,7 @@
 
 use arrow::array::{as_largestring_array, Array, StringArray};
 use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
 
 use arrow::datatypes::DataType;
 
@@ -27,11 +27,37 @@ use crate::strings::{ColumnarValueRef, StringArrayBuilder};
 use datafusion_common::cast::{as_string_array, as_string_view_array};
 use datafusion_common::{exec_err, internal_err, plan_err, Result, ScalarValue};
 use datafusion_expr::expr::ScalarFunction;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRING;
 use datafusion_expr::simplify::{ExprSimplifyResult, SimplifyInfo};
 use datafusion_expr::{lit, ColumnarValue, Documentation, Expr, Volatility};
 use datafusion_expr::{ScalarUDFImpl, Signature};
+use datafusion_macros::user_doc;
 
+#[user_doc(
+    doc_section(label = "String Functions"),
+    description = "Concatenates multiple strings together with a specified 
separator.",
+    syntax_example = "concat_ws(separator, str[, ..., str_n])",
+    sql_example = r#"```sql
+> select concat_ws('_', 'data', 'fusion');
++--------------------------------------------------+
+| concat_ws(Utf8("_"),Utf8("data"),Utf8("fusion")) |
++--------------------------------------------------+
+| data_fusion                                      |
++--------------------------------------------------+
+```"#,
+    argument(
+        name = "separator",
+        description = "Separator to insert between concatenated strings."
+    ),
+    argument(
+        name = "str",
+        description = "String expression to operate on. Can be a constant, 
column, or function, and any combination of operators."
+    ),
+    argument(
+        name = "str_n",
+        description = "Subsequent string expressions to concatenate."
+    ),
+    related_udf(name = "concat")
+)]
 #[derive(Debug)]
 pub struct ConcatWsFunc {
     signature: Signature,
@@ -271,40 +297,10 @@ impl ScalarUDFImpl for ConcatWsFunc {
     }
 
     fn documentation(&self) -> Option<&Documentation> {
-        Some(get_concat_ws_doc())
+        self.doc()
     }
 }
 
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_concat_ws_doc() -> &'static Documentation {
-    DOCUMENTATION.get_or_init(|| {
-        Documentation::builder(
-            DOC_SECTION_STRING,
-            "Concatenates multiple strings together with a specified 
separator.",
-            "concat_ws(separator, str[, ..., str_n])",
-        )
-        .with_sql_example(
-            r#"```sql
-> select concat_ws('_', 'data', 'fusion');
-+--------------------------------------------------+
-| concat_ws(Utf8("_"),Utf8("data"),Utf8("fusion")) |
-+--------------------------------------------------+
-| data_fusion                                      |
-+--------------------------------------------------+
-```"#,
-        )
-        .with_argument(
-            "separator",
-            "Separator to insert between concatenated strings.",
-        )
-        .with_standard_argument("str", Some("String"))
-        .with_argument("str_n", "Subsequent string expressions to 
concatenate.")
-        .with_related_udf("concat")
-        .build()
-    })
-}
-
 fn simplify_concat_ws(delimiter: &Expr, args: &[Expr]) -> 
Result<ExprSimplifyResult> {
     match delimiter {
         Expr::Literal(
diff --git a/datafusion/functions/src/string/ends_with.rs 
b/datafusion/functions/src/string/ends_with.rs
index 1632fdd994..0a77ec9ebd 100644
--- a/datafusion/functions/src/string/ends_with.rs
+++ b/datafusion/functions/src/string/ends_with.rs
@@ -16,17 +16,38 @@
 // under the License.
 
 use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
 
 use arrow::array::ArrayRef;
 use arrow::datatypes::DataType;
 
 use crate::utils::make_scalar_function;
 use datafusion_common::{internal_err, Result};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRING;
 use datafusion_expr::{ColumnarValue, Documentation, Volatility};
 use datafusion_expr::{ScalarUDFImpl, Signature};
+use datafusion_macros::user_doc;
 
+#[user_doc(
+    doc_section(label = "String Functions"),
+    description = "Tests if a string ends with a substring.",
+    syntax_example = "ends_with(str, substr)",
+    sql_example = r#"```sql
+>  select ends_with('datafusion', 'soin');
++--------------------------------------------+
+| ends_with(Utf8("datafusion"),Utf8("soin")) |
++--------------------------------------------+
+| false                                      |
++--------------------------------------------+
+> select ends_with('datafusion', 'sion');
++--------------------------------------------+
+| ends_with(Utf8("datafusion"),Utf8("sion")) |
++--------------------------------------------+
+| true                                       |
++--------------------------------------------+
+```"#,
+    standard_argument(name = "str", prefix = "String"),
+    argument(name = "substr", description = "Substring to test for.")
+)]
 #[derive(Debug)]
 pub struct EndsWithFunc {
     signature: Signature,
@@ -79,41 +100,10 @@ impl ScalarUDFImpl for EndsWithFunc {
     }
 
     fn documentation(&self) -> Option<&Documentation> {
-        Some(get_ends_with_doc())
+        self.doc()
     }
 }
 
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_ends_with_doc() -> &'static Documentation {
-    DOCUMENTATION.get_or_init(|| {
-        Documentation::builder(
-            DOC_SECTION_STRING,
-            "Tests if a string ends with a substring.",
-            "ends_with(str, substr)",
-        )
-        .with_sql_example(
-            r#"```sql
->  select ends_with('datafusion', 'soin');
-+--------------------------------------------+
-| ends_with(Utf8("datafusion"),Utf8("soin")) |
-+--------------------------------------------+
-| false                                      |
-+--------------------------------------------+
-> select ends_with('datafusion', 'sion');
-+--------------------------------------------+
-| ends_with(Utf8("datafusion"),Utf8("sion")) |
-+--------------------------------------------+
-| true                                       |
-+--------------------------------------------+
-```"#,
-        )
-        .with_standard_argument("str", Some("String"))
-        .with_argument("substr", "Substring to test for.")
-        .build()
-    })
-}
-
 /// Returns true if string ends with suffix.
 /// ends_with('alphabet', 'abet') = 't'
 pub fn ends_with(args: &[ArrayRef]) -> Result<ArrayRef> {
diff --git a/datafusion/functions/src/string/levenshtein.rs 
b/datafusion/functions/src/string/levenshtein.rs
index 51ff428055..57392c114d 100644
--- a/datafusion/functions/src/string/levenshtein.rs
+++ b/datafusion/functions/src/string/levenshtein.rs
@@ -16,7 +16,7 @@
 // under the License.
 
 use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
 
 use arrow::array::{ArrayRef, Int32Array, Int64Array, OffsetSizeTrait};
 use arrow::datatypes::DataType;
@@ -25,10 +25,31 @@ use crate::utils::{make_scalar_function, utf8_to_int_type};
 use datafusion_common::cast::{as_generic_string_array, as_string_view_array};
 use datafusion_common::utils::datafusion_strsim;
 use datafusion_common::{exec_err, Result};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRING;
 use datafusion_expr::{ColumnarValue, Documentation};
 use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
 
+#[user_doc(
+    doc_section(label = "String Functions"),
+    description = "Returns the [`Levenshtein 
distance`](https://en.wikipedia.org/wiki/Levenshtein_distance) between the two 
given strings.",
+    syntax_example = "levenshtein(str1, str2)",
+    sql_example = r#"```sql
+> select levenshtein('kitten', 'sitting');
++---------------------------------------------+
+| levenshtein(Utf8("kitten"),Utf8("sitting")) |
++---------------------------------------------+
+| 3                                           |
++---------------------------------------------+
+```"#,
+    argument(
+        name = "str1",
+        description = "String expression to compute Levenshtein distance with 
str2."
+    ),
+    argument(
+        name = "str2",
+        description = "String expression to compute Levenshtein distance with 
str1."
+    )
+)]
 #[derive(Debug)]
 pub struct LevenshteinFunc {
     signature: Signature,
@@ -82,32 +103,10 @@ impl ScalarUDFImpl for LevenshteinFunc {
     }
 
     fn documentation(&self) -> Option<&Documentation> {
-        Some(get_levenshtein_doc())
+        self.doc()
     }
 }
 
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_levenshtein_doc() -> &'static Documentation {
-    DOCUMENTATION.get_or_init(|| {
-        Documentation::builder(
-            DOC_SECTION_STRING,
-            "Returns the [`Levenshtein 
distance`](https://en.wikipedia.org/wiki/Levenshtein_distance) between the two 
given strings.",
-            "levenshtein(str1, str2)")
-            .with_sql_example(r#"```sql
-> select levenshtein('kitten', 'sitting');
-+---------------------------------------------+
-| levenshtein(Utf8("kitten"),Utf8("sitting")) |
-+---------------------------------------------+
-| 3                                           |
-+---------------------------------------------+
-```"#)
-            .with_argument("str1", "String expression to compute Levenshtein 
distance with str2.")
-            .with_argument("str2", "String expression to compute Levenshtein 
distance with str1.")
-            .build()
-    })
-}
-
 ///Returns the Levenshtein distance between the two given strings.
 /// LEVENSHTEIN('kitten', 'sitting') = 3
 pub fn levenshtein<T: OffsetSizeTrait>(args: &[ArrayRef]) -> Result<ArrayRef> {
diff --git a/datafusion/functions/src/string/lower.rs 
b/datafusion/functions/src/string/lower.rs
index 67c80cb785..e90c3804b1 100644
--- a/datafusion/functions/src/string/lower.rs
+++ b/datafusion/functions/src/string/lower.rs
@@ -17,15 +17,30 @@
 
 use arrow::datatypes::DataType;
 use std::any::Any;
-use std::sync::OnceLock;
 
 use crate::string::common::to_lower;
 use crate::utils::utf8_to_str_type;
 use datafusion_common::Result;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRING;
 use datafusion_expr::{ColumnarValue, Documentation};
 use datafusion_expr::{ScalarUDFImpl, Signature, Volatility};
+use datafusion_macros::user_doc;
 
+#[user_doc(
+    doc_section(label = "String Functions"),
+    description = "Converts a string to lower-case.",
+    syntax_example = "lower(str)",
+    sql_example = r#"```sql
+> select lower('Ångström');
++-------------------------+
+| lower(Utf8("Ångström")) |
++-------------------------+
+| ångström                |
++-------------------------+
+```"#,
+    standard_argument(name = "str", prefix = "String"),
+    related_udf(name = "initcap"),
+    related_udf(name = "upper")
+)]
 #[derive(Debug)]
 pub struct LowerFunc {
     signature: Signature,
@@ -71,35 +86,10 @@ impl ScalarUDFImpl for LowerFunc {
     }
 
     fn documentation(&self) -> Option<&Documentation> {
-        Some(get_lower_doc())
+        self.doc()
     }
 }
 
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_lower_doc() -> &'static Documentation {
-    DOCUMENTATION.get_or_init(|| {
-        Documentation::builder(
-            DOC_SECTION_STRING,
-            "Converts a string to lower-case.",
-            "lower(str)",
-        )
-        .with_sql_example(
-            r#"```sql
-> select lower('Ångström');
-+-------------------------+
-| lower(Utf8("Ångström")) |
-+-------------------------+
-| ångström                |
-+-------------------------+
-```"#,
-        )
-        .with_standard_argument("str", Some("String"))
-        .with_related_udf("initcap")
-        .with_related_udf("upper")
-        .build()
-    })
-}
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/datafusion/functions/src/string/overlay.rs 
b/datafusion/functions/src/string/overlay.rs
index ced2634568..3389da0968 100644
--- a/datafusion/functions/src/string/overlay.rs
+++ b/datafusion/functions/src/string/overlay.rs
@@ -16,7 +16,7 @@
 // under the License.
 
 use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
 
 use arrow::array::{ArrayRef, GenericStringArray, OffsetSizeTrait};
 use arrow::datatypes::DataType;
@@ -26,10 +26,33 @@ use datafusion_common::cast::{
     as_generic_string_array, as_int64_array, as_string_view_array,
 };
 use datafusion_common::{exec_err, Result};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRING;
 use datafusion_expr::{ColumnarValue, Documentation, TypeSignature, Volatility};
 use datafusion_expr::{ScalarUDFImpl, Signature};
+use datafusion_macros::user_doc;
 
+#[user_doc(
+    doc_section(label = "String Functions"),
+    description = "Returns the string which is replaced by another string from 
the specified position and specified count length.",
+    syntax_example = "overlay(str PLACING substr FROM pos [FOR count])",
+    sql_example = r#"```sql
+> select overlay('Txxxxas' placing 'hom' from 2 for 4);
++--------------------------------------------------------+
+| overlay(Utf8("Txxxxas"),Utf8("hom"),Int64(2),Int64(4)) |
++--------------------------------------------------------+
+| Thomas                                                 |
++--------------------------------------------------------+
+```"#,
+    standard_argument(name = "str", prefix = "String"),
+    argument(name = "substr", description = "Substring to replace in str."),
+    argument(
+        name = "pos",
+        description = "The start position to start the replace in str."
+    ),
+    argument(
+        name = "count",
+        description = "The count of characters to be replaced from start 
position of str. If not specified, will use substr length instead."
+    )
+)]
 #[derive(Debug)]
 pub struct OverlayFunc {
     signature: Signature,
@@ -92,34 +115,10 @@ impl ScalarUDFImpl for OverlayFunc {
     }
 
     fn documentation(&self) -> Option<&Documentation> {
-        Some(get_overlay_doc())
+        self.doc()
     }
 }
 
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_overlay_doc() -> &'static Documentation {
-    DOCUMENTATION.get_or_init(|| {
-        Documentation::builder(
-            DOC_SECTION_STRING,
-            "Returns the string which is replaced by another string from the 
specified position and specified count length.",
-            "overlay(str PLACING substr FROM pos [FOR count])")
-            .with_sql_example(r#"```sql
-> select overlay('Txxxxas' placing 'hom' from 2 for 4);
-+--------------------------------------------------------+
-| overlay(Utf8("Txxxxas"),Utf8("hom"),Int64(2),Int64(4)) |
-+--------------------------------------------------------+
-| Thomas                                                 |
-+--------------------------------------------------------+
-```"#)
-            .with_standard_argument("str", Some("String"))
-            .with_argument("substr", "Substring to replace in str.")
-            .with_argument("pos", "The start position to start the replace in 
str.")
-            .with_argument("count", "The count of characters to be replaced 
from start position of str. If not specified, will use substr length instead.")
-            .build()
-    })
-}
-
 macro_rules! process_overlay {
     // For the three-argument case
     ($string_array:expr, $characters_array:expr, $pos_num:expr) => {{
diff --git a/datafusion/functions/src/string/upper.rs 
b/datafusion/functions/src/string/upper.rs
index 1d05c42394..7bab33e68a 100644
--- a/datafusion/functions/src/string/upper.rs
+++ b/datafusion/functions/src/string/upper.rs
@@ -19,12 +19,27 @@ use crate::string::common::to_upper;
 use crate::utils::utf8_to_str_type;
 use arrow::datatypes::DataType;
 use datafusion_common::Result;
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRING;
 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 = "String Functions"),
+    description = "Converts a string to upper-case.",
+    syntax_example = "upper(str)",
+    sql_example = r#"```sql
+> select upper('dataFusion');
++---------------------------+
+| upper(Utf8("dataFusion")) |
++---------------------------+
+| DATAFUSION                |
++---------------------------+
+```"#,
+    standard_argument(name = "str", prefix = "String"),
+    related_udf(name = "initcap"),
+    related_udf(name = "lower")
+)]
 #[derive(Debug)]
 pub struct UpperFunc {
     signature: Signature,
@@ -70,36 +85,10 @@ impl ScalarUDFImpl for UpperFunc {
     }
 
     fn documentation(&self) -> Option<&Documentation> {
-        Some(get_upper_doc())
+        self.doc()
     }
 }
 
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_upper_doc() -> &'static Documentation {
-    DOCUMENTATION.get_or_init(|| {
-        Documentation::builder(
-            DOC_SECTION_STRING,
-            "Converts a string to upper-case.",
-            "upper(str)",
-        )
-        .with_sql_example(
-            r#"```sql
-> select upper('dataFusion');
-+---------------------------+
-| upper(Utf8("dataFusion")) |
-+---------------------------+
-| DATAFUSION                |
-+---------------------------+
-```"#,
-        )
-        .with_standard_argument("str", Some("String"))
-        .with_related_udf("initcap")
-        .with_related_udf("lower")
-        .build()
-    })
-}
-
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/datafusion/functions/src/unicode/initcap.rs 
b/datafusion/functions/src/unicode/initcap.rs
index c21fb77c9e..03314bb249 100644
--- a/datafusion/functions/src/unicode/initcap.rs
+++ b/datafusion/functions/src/unicode/initcap.rs
@@ -16,7 +16,7 @@
 // under the License.
 
 use std::any::Any;
-use std::sync::{Arc, OnceLock};
+use std::sync::Arc;
 
 use arrow::array::{
     Array, ArrayRef, GenericStringBuilder, OffsetSizeTrait, StringViewBuilder,
@@ -26,10 +26,27 @@ use arrow::datatypes::DataType;
 use crate::utils::{make_scalar_function, utf8_to_str_type};
 use datafusion_common::cast::{as_generic_string_array, as_string_view_array};
 use datafusion_common::{exec_err, Result};
-use datafusion_expr::scalar_doc_sections::DOC_SECTION_STRING;
 use datafusion_expr::{ColumnarValue, Documentation, Volatility};
 use datafusion_expr::{ScalarUDFImpl, Signature};
+use datafusion_macros::user_doc;
 
+#[user_doc(
+    doc_section(label = "String Functions"),
+    description = "Capitalizes the first character in each word in the input 
string. \
+            Words are delimited by non-alphanumeric characters.",
+    syntax_example = "initcap(str)",
+    sql_example = r#"```sql
+> select initcap('apache datafusion');
++------------------------------------+
+| initcap(Utf8("apache datafusion")) |
++------------------------------------+
+| Apache Datafusion                  |
++------------------------------------+
+```"#,
+    standard_argument(name = "str", prefix = "String"),
+    related_udf(name = "lower"),
+    related_udf(name = "upper")
+)]
 #[derive(Debug)]
 pub struct InitcapFunc {
     signature: Signature,
@@ -86,37 +103,10 @@ impl ScalarUDFImpl for InitcapFunc {
     }
 
     fn documentation(&self) -> Option<&Documentation> {
-        Some(get_initcap_doc())
+        self.doc()
     }
 }
 
-static DOCUMENTATION: OnceLock<Documentation> = OnceLock::new();
-
-fn get_initcap_doc() -> &'static Documentation {
-    DOCUMENTATION.get_or_init(|| {
-        Documentation::builder(
-            DOC_SECTION_STRING,
-            "Capitalizes the first character in each word in the input string. 
\
-            Words are delimited by non-alphanumeric characters.",
-            "initcap(str)",
-        )
-        .with_sql_example(
-            r#"```sql
-> select initcap('apache datafusion');
-+------------------------------------+
-| initcap(Utf8("apache datafusion")) |
-+------------------------------------+
-| Apache Datafusion                  |
-+------------------------------------+
-```"#,
-        )
-        .with_standard_argument("str", Some("String"))
-        .with_related_udf("lower")
-        .with_related_udf("upper")
-        .build()
-    })
-}
-
 /// Converts the first letter of each word to upper case and the rest to lower
 /// case. Words are sequences of alphanumeric characters separated by
 /// non-alphanumeric characters.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to