diff --git a/crates/rayexec_execution/src/functions/documentation.rs b/crates/rayexec_execution/src/functions/documentation.rs index 54662ea1f..2116d04ae 100644 --- a/crates/rayexec_execution/src/functions/documentation.rs +++ b/crates/rayexec_execution/src/functions/documentation.rs @@ -9,6 +9,8 @@ pub enum Category { Interval, List, String, + Regexp, + Binary, } /// Documentation for a single function variant. diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/ascii.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/ascii.rs index 1dcb81327..e43b386fb 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/ascii.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/ascii.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::UnaryExecutor; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, plan_check_num_args, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -23,6 +24,15 @@ impl FunctionInfo for Ascii { positional_args: &[DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Int32, + doc: Some(&Documentation { + category: Category::String, + description: "Get the ascii code of the first character of the argument.", + arguments: &["string"], + example: Some(Example { + example: "ascii('h')", + output: "104", + }), + }), }] } } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/case.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/case.rs index 7fa3a76ac..2b7966c27 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/case.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/case.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::UnaryExecutor; use rayexec_error::{RayexecError, Result}; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, plan_check_num_args, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -23,6 +24,15 @@ impl FunctionInfo for Lower { positional_args: &[DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation { + category: Category::String, + description: "Convert the string to lowercase.", + arguments: &["string"], + example: Some(Example { + example: "lower('ABC')", + output: "abc", + }), + }), }] } } @@ -69,6 +79,15 @@ impl FunctionInfo for Upper { positional_args: &[DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation { + category: Category::String, + description: "Convert the string to uppercase.", + arguments: &["string"], + example: Some(Example { + example: "lower('abc')", + output: "ABC", + }), + }), }] } } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/concat.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/concat.rs index 1aa93b78d..1b123081f 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/concat.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/concat.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::{BinaryExecutor, UniformExecutor}; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -26,6 +27,15 @@ impl FunctionInfo for Concat { positional_args: &[], variadic_arg: Some(DataTypeId::Utf8), return_type: DataTypeId::Utf8, + doc: Some(&Documentation { + category: Category::String, + description: "Concatenate many strings into a single string.", + arguments: &["var_args"], + example: Some(Example { + example: "concat('cat', 'dog', 'mouse')", + output: "catdogmouse", + }), + }), }] } } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/contains.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/contains.rs index dc62fcac7..13fcd879a 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/contains.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/contains.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::{BinaryExecutor, UnaryExecutor}; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -25,6 +26,15 @@ impl FunctionInfo for Contains { positional_args: &[DataTypeId::Utf8, DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Boolean, + doc: Some(&Documentation { + category: Category::String, + description: "Check if string contains a search string.", + arguments: &["string", "search"], + example: Some(Example { + example: "contains('house', 'ou')", + output: "true", + }), + }), }] } } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/ends_with.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/ends_with.rs index 733b96db7..a640db94c 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/ends_with.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/ends_with.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::{BinaryExecutor, UnaryExecutor}; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -29,6 +30,15 @@ impl FunctionInfo for EndsWith { positional_args: &[DataTypeId::Utf8, DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Boolean, + doc: Some(&Documentation { + category: Category::String, + description: "Check if a string ends with a given suffix.", + arguments: &["string", "suffix"], + example: Some(Example { + example: "ends_with('house', 'se')", + output: "true", + }), + }), }] } } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/length.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/length.rs index e6cce5a7d..fde69ec5b 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/length.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/length.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::UnaryExecutor; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, plan_check_num_args, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -27,6 +28,15 @@ impl FunctionInfo for Length { positional_args: &[DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Int64, + doc: Some(&Documentation { + category: Category::String, + description: "Get the number of characters in a string.", + arguments: &["string"], + example: Some(Example { + example: "length('tschüß')", + output: "6", + }), + }), }] } } @@ -87,11 +97,26 @@ impl FunctionInfo for ByteLength { positional_args: &[DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Int64, + doc: Some(&Documentation { + category: Category::String, + description: "Get the number of bytes in a string.", + arguments: &["string"], + example: Some(Example { + example: "byte_length('tschüß')", + output: "6", + }), + }), }, Signature { positional_args: &[DataTypeId::Binary], variadic_arg: None, return_type: DataTypeId::Int64, + doc: Some(&Documentation { + category: Category::String, + description: "Get the number of bytes in a binary blob.", + arguments: &["blob"], + example: None, + }), }, ] } @@ -149,11 +174,26 @@ impl FunctionInfo for BitLength { positional_args: &[DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Int64, + doc: Some(&Documentation { + category: Category::String, + description: "Get the number of bits in a string.", + arguments: &["string"], + example: Some(Example { + example: "bit_length('tschüß')", + output: "64", + }), + }), }, Signature { positional_args: &[DataTypeId::Binary], variadic_arg: None, return_type: DataTypeId::Int64, + doc: Some(&Documentation { + category: Category::String, + description: "Get the number of bits in a binary blob.", + arguments: &["blob"], + example: None, + }), }, ] } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/like.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/like.rs index d46b63f01..4f6fd8e35 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/like.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/like.rs @@ -7,6 +7,7 @@ use rayexec_error::{Result, ResultExt}; use regex::{escape, Regex}; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -28,6 +29,15 @@ impl FunctionInfo for Like { positional_args: &[DataTypeId::Utf8, DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Boolean, + doc: Some(&Documentation { + category: Category::String, + description: "Check if a string matches the given pattern.", + arguments: &["string", "pattern"], + example: Some(Example { + example: "like('hello, world', '%world')", + output: "true", + }), + }), }, ] } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/pad.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/pad.rs index 753504531..fbf20db71 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/pad.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/pad.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::{BinaryExecutor, TernaryExecutor}; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{ invalid_input_types_error, @@ -29,11 +30,29 @@ impl FunctionInfo for LeftPad { positional_args: &[DataTypeId::Utf8, DataTypeId::Int64], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation{ + category: Category::String, + description: "Left pad a string with spaces until the resulting string contains 'count' characters.", + arguments: &["string", "count"], + example: Some(Example{ + example: "lpad('house', 8)", + output: " house", + }), + }), }, Signature { positional_args: &[DataTypeId::Utf8, DataTypeId::Int64, DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation{ + category: Category::String, + description: "Left pad a string with another string until the resulting string contains 'count' characters.", + arguments: &["string", "count", "pad"], + example: Some(Example{ + example: "lpad('house', 8, '_')", + output: "___house", + }), + }), }, ] } @@ -123,11 +142,30 @@ impl FunctionInfo for RightPad { positional_args: &[DataTypeId::Utf8, DataTypeId::Int64], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation{ + category: Category::String, + description: "Right pad a string with spaces until the resulting string contains 'count' characters.", + arguments: &["string", "count"], + example: Some(Example{ + example: "rpad('house', 8)", + output: "house ", + }), + }), }, Signature { positional_args: &[DataTypeId::Utf8, DataTypeId::Int64, DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation{ + category: Category::String, + description: "Right pad a string with another string until the resulting string contains 'count' characters.", + arguments: &["string", "count", "pad"], + example: Some(Example{ + example: "rpad('house', 8, '_')", + output: "house___", + }), + }), + }, ] } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/regexp_replace.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/regexp_replace.rs index d15d92ef0..817b19f2e 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/regexp_replace.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/regexp_replace.rs @@ -7,6 +7,7 @@ use rayexec_error::{Result, ResultExt}; use regex::Regex; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, plan_check_num_args, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -26,6 +27,15 @@ impl FunctionInfo for RegexpReplace { positional_args: &[DataTypeId::Utf8, DataTypeId::Utf8, DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation { + category: Category::Regexp, + description: "Replace the first regular expression match in a string.", + arguments: &["string", "regexp", "replacement"], + example: Some(Example { + example: "regexp_replace('alphabet', '[ae]', 'DOG')", + output: "DOGlphabet", + }), + }), }] } } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/repeat.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/repeat.rs index 5b9bbb33d..597a4a02f 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/repeat.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/repeat.rs @@ -8,6 +8,7 @@ use rayexec_bullet::executor::scalar::BinaryExecutor; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, plan_check_num_args, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -25,6 +26,15 @@ impl FunctionInfo for Repeat { positional_args: &[DataTypeId::Utf8, DataTypeId::Int64], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation { + category: Category::String, + description: "Repeat a string some number of times.", + arguments: &["string", "count"], + example: Some(Example { + example: "repeat('abc', 3)", + output: "abcabcabc", + }), + }), }] } } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/starts_with.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/starts_with.rs index f171f69d8..93708edc5 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/starts_with.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/starts_with.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::{BinaryExecutor, UnaryExecutor}; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{invalid_input_types_error, plan_check_num_args, FunctionInfo, Signature}; use crate::logical::binder::table_list::TableList; @@ -29,6 +30,15 @@ impl FunctionInfo for StartsWith { positional_args: &[DataTypeId::Utf8, DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Boolean, + doc: Some(&Documentation { + category: Category::String, + description: "Check if a string starts with a prefix.", + arguments: &["string", "prefix"], + example: Some(Example { + example: "starts_with('hello', 'he')", + output: "true", + }), + }), }] } } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/substring.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/substring.rs index b1c444ef4..8dc1ee71d 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/substring.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/substring.rs @@ -6,6 +6,7 @@ use rayexec_bullet::executor::scalar::{BinaryExecutor, TernaryExecutor}; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{ invalid_input_types_error, @@ -34,12 +35,30 @@ impl FunctionInfo for Substring { positional_args: &[DataTypeId::Utf8, DataTypeId::Int64, DataTypeId::Int64], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation{ + category: Category::String, + description: "Get a substring of a string starting at an index for some number of characters. The index is 1-based.", + arguments: &["string", "index", "for"], + example: Some(Example{ + example: "substring('alphabet', 3, 2)", + output: "ph", + }) + }) }, // substring(, ) Signature { positional_args: &[DataTypeId::Utf8, DataTypeId::Int64], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(&Documentation{ + category: Category::String, + description: "Get a substring of a string starting at an index until the end of the string. The index is 1-based.", + arguments: &["string", "index"], + example: Some(Example{ + example: "substring('alphabet', 3)", + output: "phabet", + }), + }), }, ] } diff --git a/crates/rayexec_execution/src/functions/scalar/builtin/string/trim.rs b/crates/rayexec_execution/src/functions/scalar/builtin/string/trim.rs index df17a94c9..938302966 100644 --- a/crates/rayexec_execution/src/functions/scalar/builtin/string/trim.rs +++ b/crates/rayexec_execution/src/functions/scalar/builtin/string/trim.rs @@ -9,6 +9,7 @@ use rayexec_bullet::executor::scalar::{BinaryExecutor, UnaryExecutor}; use rayexec_error::Result; use crate::expr::Expression; +use crate::functions::documentation::{Category, Documentation, Example}; use crate::functions::scalar::{PlannedScalarFunction, ScalarFunction, ScalarFunctionImpl}; use crate::functions::{ invalid_input_types_error, @@ -26,6 +27,9 @@ pub trait StringTrimOp: Sync + Send + Debug + Clone + Copy + PartialEq + Eq + 's const NAME: &'static str; const ALIASES: &'static [&'static str]; + const DOC_ONE_ARG: &'static Documentation; + const DOC_TWO_ARGS: &'static Documentation; + fn trim_func<'a>(input: &'a str, pattern: &str) -> &'a str; } @@ -36,6 +40,26 @@ impl StringTrimOp for BothTrimOp { const NAME: &'static str = "btrim"; const ALIASES: &'static [&'static str] = &["trim"]; + const DOC_ONE_ARG: &'static Documentation = &Documentation { + category: Category::String, + description: "Trim whitespace from both sides of the string.", + arguments: &["string"], + example: Some(Example { + example: "trim(' hello ')", + output: "hello", + }), + }; + + const DOC_TWO_ARGS: &'static Documentation = &Documentation { + category: Category::String, + description: "Trim matching characters from both sides of the string.", + arguments: &["string", "characters"], + example: Some(Example { + example: "trim('->hello<', '<>-')", + output: "hello", + }), + }; + fn trim_func<'a>(input: &'a str, pattern: &str) -> &'a str { input.trim_matches(|c| pattern.contains(c)) } @@ -48,6 +72,26 @@ impl StringTrimOp for LeftTrimOp { const NAME: &'static str = "ltrim"; const ALIASES: &'static [&'static str] = &[]; + const DOC_ONE_ARG: &'static Documentation = &Documentation { + category: Category::String, + description: "Trim whitespace from the left side of the string.", + arguments: &["string"], + example: Some(Example { + example: "ltrim(' hello ')", + output: "hello ", + }), + }; + + const DOC_TWO_ARGS: &'static Documentation = &Documentation { + category: Category::String, + description: "Trim matching characters from the left side of the string.", + arguments: &["string", "characters"], + example: Some(Example { + example: "ltrim('->hello<', '<>-')", + output: "hello<", + }), + }; + fn trim_func<'a>(input: &'a str, pattern: &str) -> &'a str { input.trim_start_matches(|c| pattern.contains(c)) } @@ -60,6 +104,26 @@ impl StringTrimOp for RightTrimOp { const NAME: &'static str = "rtrim"; const ALIASES: &'static [&'static str] = &[]; + const DOC_ONE_ARG: &'static Documentation = &Documentation { + category: Category::String, + description: "Trim whitespace from the right side of the string.", + arguments: &["string"], + example: Some(Example { + example: "rtrim(' hello ')", + output: " hello", + }), + }; + + const DOC_TWO_ARGS: &'static Documentation = &Documentation { + category: Category::String, + description: "Trim matching characters from the right side of the string.", + arguments: &["string", "characters"], + example: Some(Example { + example: "rtrim('->hello<', '<>-')", + output: "->hello", + }), + }; + fn trim_func<'a>(input: &'a str, pattern: &str) -> &'a str { input.trim_end_matches(|c| pattern.contains(c)) } @@ -97,11 +161,13 @@ impl FunctionInfo for Trim { positional_args: &[DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(F::DOC_ONE_ARG), }, Signature { positional_args: &[DataTypeId::Utf8, DataTypeId::Utf8], variadic_arg: None, return_type: DataTypeId::Utf8, + doc: Some(F::DOC_TWO_ARGS), }, ] }