diff --git a/datafusion/core/src/catalog_common/information_schema.rs b/datafusion/core/src/catalog_common/information_schema.rs index 1d4a3c15f7ca..ce3092acfdf1 100644 --- a/datafusion/core/src/catalog_common/information_schema.rs +++ b/datafusion/core/src/catalog_common/information_schema.rs @@ -34,7 +34,7 @@ use arrow::{ datatypes::{DataType, Field, Schema, SchemaRef}, record_batch::RecordBatch, }; -use arrow_array::builder::BooleanBuilder; +use arrow_array::builder::{BooleanBuilder, UInt8Builder}; use async_trait::async_trait; use datafusion_common::error::Result; use datafusion_common::DataFusionError; @@ -247,6 +247,7 @@ impl InformationSchemaConfig { return_type, "SCALAR", udf.documentation().map(|d| d.description.to_string()), + udf.documentation().map(|d| d.syntax_example.to_string()), ) } } @@ -266,6 +267,7 @@ impl InformationSchemaConfig { return_type, "AGGREGATE", udaf.documentation().map(|d| d.description.to_string()), + udaf.documentation().map(|d| d.syntax_example.to_string()), ) } } @@ -285,6 +287,7 @@ impl InformationSchemaConfig { return_type, "WINDOW", udwf.documentation().map(|d| d.description.to_string()), + udwf.documentation().map(|d| d.syntax_example.to_string()), ) } } @@ -308,7 +311,8 @@ impl InformationSchemaConfig { args: Option<&Vec<(String, String)>>, arg_types: Vec, return_type: Option, - is_variadic: bool| { + is_variadic: bool, + rid: u8| { for (position, type_name) in arg_types.iter().enumerate() { let param_name = args.and_then(|a| a.get(position).map(|arg| arg.0.as_str())); @@ -322,6 +326,7 @@ impl InformationSchemaConfig { type_name, None::<&str>, is_variadic, + rid, ); } if let Some(return_type) = return_type { @@ -335,6 +340,7 @@ impl InformationSchemaConfig { return_type.as_str(), None::<&str>, false, + rid, ); } }; @@ -342,13 +348,14 @@ impl InformationSchemaConfig { for (func_name, udf) in udfs { let args = udf.documentation().and_then(|d| d.arguments.clone()); let combinations = get_udf_args_and_return_types(udf)?; - for (arg_types, return_type) in combinations { + for (rid, (arg_types, return_type)) in combinations.into_iter().enumerate() { add_parameters( func_name, args.as_ref(), arg_types, return_type, Self::is_variadic(udf.signature()), + rid as u8, ); } } @@ -356,13 +363,14 @@ impl InformationSchemaConfig { for (func_name, udaf) in udafs { let args = udaf.documentation().and_then(|d| d.arguments.clone()); let combinations = get_udaf_args_and_return_types(udaf)?; - for (arg_types, return_type) in combinations { + for (rid, (arg_types, return_type)) in combinations.into_iter().enumerate() { add_parameters( func_name, args.as_ref(), arg_types, return_type, Self::is_variadic(udaf.signature()), + rid as u8, ); } } @@ -370,13 +378,14 @@ impl InformationSchemaConfig { for (func_name, udwf) in udwfs { let args = udwf.documentation().and_then(|d| d.arguments.clone()); let combinations = get_udwf_args_and_return_types(udwf)?; - for (arg_types, return_type) in combinations { + for (rid, (arg_types, return_type)) in combinations.into_iter().enumerate() { add_parameters( func_name, args.as_ref(), arg_types, return_type, Self::is_variadic(udwf.signature()), + rid as u8, ); } } @@ -1095,6 +1104,7 @@ impl InformationSchemaRoutines { Field::new("data_type", DataType::Utf8, true), Field::new("function_type", DataType::Utf8, true), Field::new("description", DataType::Utf8, true), + Field::new("syntax_example", DataType::Utf8, true), ])); Self { schema, config } @@ -1114,6 +1124,7 @@ impl InformationSchemaRoutines { data_type: StringBuilder::new(), function_type: StringBuilder::new(), description: StringBuilder::new(), + syntax_example: StringBuilder::new(), } } } @@ -1131,6 +1142,7 @@ struct InformationSchemaRoutinesBuilder { data_type: StringBuilder, function_type: StringBuilder, description: StringBuilder, + syntax_example: StringBuilder, } impl InformationSchemaRoutinesBuilder { @@ -1145,6 +1157,7 @@ impl InformationSchemaRoutinesBuilder { data_type: Option>, function_type: impl AsRef, description: Option>, + syntax_example: Option>, ) { self.specific_catalog.append_value(catalog_name.as_ref()); self.specific_schema.append_value(schema_name.as_ref()); @@ -1157,6 +1170,7 @@ impl InformationSchemaRoutinesBuilder { self.data_type.append_option(data_type.as_ref()); self.function_type.append_value(function_type.as_ref()); self.description.append_option(description); + self.syntax_example.append_option(syntax_example); } fn finish(&mut self) -> RecordBatch { @@ -1174,6 +1188,7 @@ impl InformationSchemaRoutinesBuilder { Arc::new(self.data_type.finish()), Arc::new(self.function_type.finish()), Arc::new(self.description.finish()), + Arc::new(self.syntax_example.finish()), ], ) .unwrap() @@ -1222,6 +1237,12 @@ impl InformationSchemaParameters { Field::new("data_type", DataType::Utf8, false), Field::new("parameter_default", DataType::Utf8, true), Field::new("is_variadic", DataType::Boolean, false), + // `rid` (short for `routine id`) is used to differentiate parameters from different signatures + // (It serves as the group-by key when generating the `SHOW FUNCTIONS` query). + // For example, the following signatures have different `rid` values: + // - `datetrunc(Utf8, Timestamp(Microsecond, Some("+TZ"))) -> Timestamp(Microsecond, Some("+TZ"))` + // - `datetrunc(Utf8View, Timestamp(Nanosecond, None)) -> Timestamp(Nanosecond, None)` + Field::new("rid", DataType::UInt8, false), ])); Self { schema, config } @@ -1239,7 +1260,7 @@ impl InformationSchemaParameters { data_type: StringBuilder::new(), parameter_default: StringBuilder::new(), is_variadic: BooleanBuilder::new(), - inserted: HashSet::new(), + rid: UInt8Builder::new(), } } } @@ -1255,8 +1276,7 @@ struct InformationSchemaParametersBuilder { data_type: StringBuilder, parameter_default: StringBuilder, is_variadic: BooleanBuilder, - // use HashSet to avoid duplicate rows. The key is (specific_name, ordinal_position, parameter_mode, data_type) - inserted: HashSet<(String, u64, String, String)>, + rid: UInt8Builder, } impl InformationSchemaParametersBuilder { @@ -1272,25 +1292,19 @@ impl InformationSchemaParametersBuilder { data_type: impl AsRef, parameter_default: Option>, is_variadic: bool, + rid: u8, ) { - let key = ( - specific_name.as_ref().to_string(), - ordinal_position, - parameter_mode.as_ref().to_string(), - data_type.as_ref().to_string(), - ); - if self.inserted.insert(key) { - self.specific_catalog - .append_value(specific_catalog.as_ref()); - self.specific_schema.append_value(specific_schema.as_ref()); - self.specific_name.append_value(specific_name.as_ref()); - self.ordinal_position.append_value(ordinal_position); - self.parameter_mode.append_value(parameter_mode.as_ref()); - self.parameter_name.append_option(parameter_name.as_ref()); - self.data_type.append_value(data_type.as_ref()); - self.parameter_default.append_option(parameter_default); - self.is_variadic.append_value(is_variadic); - } + self.specific_catalog + .append_value(specific_catalog.as_ref()); + self.specific_schema.append_value(specific_schema.as_ref()); + self.specific_name.append_value(specific_name.as_ref()); + self.ordinal_position.append_value(ordinal_position); + self.parameter_mode.append_value(parameter_mode.as_ref()); + self.parameter_name.append_option(parameter_name.as_ref()); + self.data_type.append_value(data_type.as_ref()); + self.parameter_default.append_option(parameter_default); + self.is_variadic.append_value(is_variadic); + self.rid.append_value(rid); } fn finish(&mut self) -> RecordBatch { @@ -1306,6 +1320,7 @@ impl InformationSchemaParametersBuilder { Arc::new(self.data_type.finish()), Arc::new(self.parameter_default.finish()), Arc::new(self.is_variadic.finish()), + Arc::new(self.rid.finish()), ], ) .unwrap() diff --git a/datafusion/sql/src/statement.rs b/datafusion/sql/src/statement.rs index 38695f98b5fe..12ed29a51559 100644 --- a/datafusion/sql/src/statement.rs +++ b/datafusion/sql/src/statement.rs @@ -699,6 +699,10 @@ impl SqlToRel<'_, S> { filter, } => self.show_columns_to_plan(extended, full, table_name, filter), + Statement::ShowFunctions { filter, .. } => { + self.show_functions_to_plan(filter) + } + Statement::Insert(Insert { or, into, @@ -1879,6 +1883,90 @@ impl SqlToRel<'_, S> { self.statement_to_plan(rewrite.pop_front().unwrap()) // length of rewrite is 1 } + /// Rewrite `SHOW FUNCTIONS` to another SQL query + /// The query is based on the `information_schema.routines` and `information_schema.parameters` tables + /// + /// The output columns: + /// - function_name: The name of function + /// - return_type: The return type of the function + /// - parameters: The name of parameters (ordered by the ordinal position) + /// - parameter_types: The type of parameters (ordered by the ordinal position) + /// - description: The description of the function (the description defined in the document) + /// - syntax_example: The syntax_example of the function (the syntax_example defined in the document) + fn show_functions_to_plan( + &self, + filter: Option, + ) -> Result { + let where_clause = if let Some(filter) = filter { + match filter { + ShowStatementFilter::Like(like) => { + format!("WHERE p.function_name like '{like}'") + } + _ => return plan_err!("Unsupported SHOW FUNCTIONS filter"), + } + } else { + "".to_string() + }; + + let query = format!( + r#" +SELECT DISTINCT + p.*, + r.function_type function_type, + r.description description, + r.syntax_example syntax_example +FROM + ( + SELECT + i.specific_name function_name, + o.data_type return_type, + array_agg(i.parameter_name ORDER BY i.ordinal_position ASC) parameters, + array_agg(i.data_type ORDER BY i.ordinal_position ASC) parameter_types + FROM ( + SELECT + specific_catalog, + specific_schema, + specific_name, + ordinal_position, + parameter_name, + data_type, + rid + FROM + information_schema.parameters + WHERE + parameter_mode = 'IN' + ) i + JOIN + ( + SELECT + specific_catalog, + specific_schema, + specific_name, + ordinal_position, + parameter_name, + data_type, + rid + FROM + information_schema.parameters + WHERE + parameter_mode = 'OUT' + ) o + ON i.specific_catalog = o.specific_catalog + AND i.specific_schema = o.specific_schema + AND i.specific_name = o.specific_name + AND i.rid = o.rid + GROUP BY 1, 2, i.rid + ) as p +JOIN information_schema.routines r +ON p.function_name = r.routine_name +{where_clause} + "# + ); + let mut rewrite = DFParser::parse_sql(&query)?; + assert_eq!(rewrite.len(), 1); + self.statement_to_plan(rewrite.pop_front().unwrap()) // length of rewrite is 1 + } + fn show_create_table_to_plan( &self, sql_table_name: ObjectName, diff --git a/datafusion/sqllogictest/test_files/information_schema.slt b/datafusion/sqllogictest/test_files/information_schema.slt index 4d51a61c8a52..827859edb254 100644 --- a/datafusion/sqllogictest/test_files/information_schema.slt +++ b/datafusion/sqllogictest/test_files/information_schema.slt @@ -625,19 +625,19 @@ select routine_name, data_type, function_type from information_schema.routines w string_agg LargeUtf8 AGGREGATE # test every function type are included in the result -query TTTTTTTBTTT rowsort -select * from information_schema.routines where routine_name = 'date_trunc' OR routine_name = 'string_agg' OR routine_name = 'rank'; ----- -datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Microsecond, None) SCALAR Truncates a timestamp value to a specified precision. -datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Microsecond, Some("+TZ")) SCALAR Truncates a timestamp value to a specified precision. -datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Millisecond, None) SCALAR Truncates a timestamp value to a specified precision. -datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Millisecond, Some("+TZ")) SCALAR Truncates a timestamp value to a specified precision. -datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Nanosecond, None) SCALAR Truncates a timestamp value to a specified precision. -datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Nanosecond, Some("+TZ")) SCALAR Truncates a timestamp value to a specified precision. -datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Second, None) SCALAR Truncates a timestamp value to a specified precision. -datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Second, Some("+TZ")) SCALAR Truncates a timestamp value to a specified precision. -datafusion public rank datafusion public rank FUNCTION true NULL WINDOW Returns the rank of the current row within its partition, allowing gaps between ranks. This function provides a ranking similar to `row_number`, but skips ranks for identical values. -datafusion public string_agg datafusion public string_agg FUNCTION true LargeUtf8 AGGREGATE Concatenates the values of string expressions and places separator values between them. +query TTTTTTTBTTTT rowsort +select * from information_schema.routines where routine_name = 'date_trunc' OR routine_name = 'string_agg' OR routine_name = 'rank' ORDER BY routine_name +---- +datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Microsecond, None) SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Microsecond, Some("+TZ")) SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Millisecond, None) SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Millisecond, Some("+TZ")) SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Nanosecond, None) SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Nanosecond, Some("+TZ")) SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Second, None) SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +datafusion public date_trunc datafusion public date_trunc FUNCTION true Timestamp(Second, Some("+TZ")) SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +datafusion public rank datafusion public rank FUNCTION true NULL WINDOW Returns the rank of the current row within its partition, allowing gaps between ranks. This function provides a ranking similar to `row_number`, but skips ranks for identical values. rank() +datafusion public string_agg datafusion public string_agg FUNCTION true LargeUtf8 AGGREGATE Concatenates the values of string expressions and places separator values between them. string_agg(expression, delimiter) query B select is_deterministic from information_schema.routines where routine_name = 'now'; @@ -645,51 +645,111 @@ select is_deterministic from information_schema.routines where routine_name = 'n false # test every function type are included in the result -query TTTITTTTB rowsort -select * from information_schema.parameters where specific_name = 'date_trunc' OR specific_name = 'string_agg' OR specific_name = 'rank'; ----- -datafusion public date_trunc 1 IN precision Utf8 NULL false -datafusion public date_trunc 1 IN precision Utf8View NULL false -datafusion public date_trunc 1 OUT NULL Timestamp(Microsecond, None) NULL false -datafusion public date_trunc 1 OUT NULL Timestamp(Microsecond, Some("+TZ")) NULL false -datafusion public date_trunc 1 OUT NULL Timestamp(Millisecond, None) NULL false -datafusion public date_trunc 1 OUT NULL Timestamp(Millisecond, Some("+TZ")) NULL false -datafusion public date_trunc 1 OUT NULL Timestamp(Nanosecond, None) NULL false -datafusion public date_trunc 1 OUT NULL Timestamp(Nanosecond, Some("+TZ")) NULL false -datafusion public date_trunc 1 OUT NULL Timestamp(Second, None) NULL false -datafusion public date_trunc 1 OUT NULL Timestamp(Second, Some("+TZ")) NULL false -datafusion public date_trunc 2 IN expression Timestamp(Microsecond, None) NULL false -datafusion public date_trunc 2 IN expression Timestamp(Microsecond, Some("+TZ")) NULL false -datafusion public date_trunc 2 IN expression Timestamp(Millisecond, None) NULL false -datafusion public date_trunc 2 IN expression Timestamp(Millisecond, Some("+TZ")) NULL false -datafusion public date_trunc 2 IN expression Timestamp(Nanosecond, None) NULL false -datafusion public date_trunc 2 IN expression Timestamp(Nanosecond, Some("+TZ")) NULL false -datafusion public date_trunc 2 IN expression Timestamp(Second, None) NULL false -datafusion public date_trunc 2 IN expression Timestamp(Second, Some("+TZ")) NULL false -datafusion public string_agg 1 IN expression LargeUtf8 NULL false -datafusion public string_agg 1 OUT NULL LargeUtf8 NULL false -datafusion public string_agg 2 IN delimiter LargeUtf8 NULL false -datafusion public string_agg 2 IN delimiter Null NULL false -datafusion public string_agg 2 IN delimiter Utf8 NULL false +query TTTITTTTBI +select * from information_schema.parameters where specific_name = 'date_trunc' OR specific_name = 'string_agg' OR specific_name = 'rank' ORDER BY specific_name, rid; +---- +datafusion public date_trunc 1 IN precision Utf8 NULL false 0 +datafusion public date_trunc 2 IN expression Timestamp(Nanosecond, None) NULL false 0 +datafusion public date_trunc 1 OUT NULL Timestamp(Nanosecond, None) NULL false 0 +datafusion public date_trunc 1 IN precision Utf8View NULL false 1 +datafusion public date_trunc 2 IN expression Timestamp(Nanosecond, None) NULL false 1 +datafusion public date_trunc 1 OUT NULL Timestamp(Nanosecond, None) NULL false 1 +datafusion public date_trunc 1 IN precision Utf8 NULL false 2 +datafusion public date_trunc 2 IN expression Timestamp(Nanosecond, Some("+TZ")) NULL false 2 +datafusion public date_trunc 1 OUT NULL Timestamp(Nanosecond, Some("+TZ")) NULL false 2 +datafusion public date_trunc 1 IN precision Utf8View NULL false 3 +datafusion public date_trunc 2 IN expression Timestamp(Nanosecond, Some("+TZ")) NULL false 3 +datafusion public date_trunc 1 OUT NULL Timestamp(Nanosecond, Some("+TZ")) NULL false 3 +datafusion public date_trunc 1 IN precision Utf8 NULL false 4 +datafusion public date_trunc 2 IN expression Timestamp(Microsecond, None) NULL false 4 +datafusion public date_trunc 1 OUT NULL Timestamp(Microsecond, None) NULL false 4 +datafusion public date_trunc 1 IN precision Utf8View NULL false 5 +datafusion public date_trunc 2 IN expression Timestamp(Microsecond, None) NULL false 5 +datafusion public date_trunc 1 OUT NULL Timestamp(Microsecond, None) NULL false 5 +datafusion public date_trunc 1 IN precision Utf8 NULL false 6 +datafusion public date_trunc 2 IN expression Timestamp(Microsecond, Some("+TZ")) NULL false 6 +datafusion public date_trunc 1 OUT NULL Timestamp(Microsecond, Some("+TZ")) NULL false 6 +datafusion public date_trunc 1 IN precision Utf8View NULL false 7 +datafusion public date_trunc 2 IN expression Timestamp(Microsecond, Some("+TZ")) NULL false 7 +datafusion public date_trunc 1 OUT NULL Timestamp(Microsecond, Some("+TZ")) NULL false 7 +datafusion public date_trunc 1 IN precision Utf8 NULL false 8 +datafusion public date_trunc 2 IN expression Timestamp(Millisecond, None) NULL false 8 +datafusion public date_trunc 1 OUT NULL Timestamp(Millisecond, None) NULL false 8 +datafusion public date_trunc 1 IN precision Utf8View NULL false 9 +datafusion public date_trunc 2 IN expression Timestamp(Millisecond, None) NULL false 9 +datafusion public date_trunc 1 OUT NULL Timestamp(Millisecond, None) NULL false 9 +datafusion public date_trunc 1 IN precision Utf8 NULL false 10 +datafusion public date_trunc 2 IN expression Timestamp(Millisecond, Some("+TZ")) NULL false 10 +datafusion public date_trunc 1 OUT NULL Timestamp(Millisecond, Some("+TZ")) NULL false 10 +datafusion public date_trunc 1 IN precision Utf8View NULL false 11 +datafusion public date_trunc 2 IN expression Timestamp(Millisecond, Some("+TZ")) NULL false 11 +datafusion public date_trunc 1 OUT NULL Timestamp(Millisecond, Some("+TZ")) NULL false 11 +datafusion public date_trunc 1 IN precision Utf8 NULL false 12 +datafusion public date_trunc 2 IN expression Timestamp(Second, None) NULL false 12 +datafusion public date_trunc 1 OUT NULL Timestamp(Second, None) NULL false 12 +datafusion public date_trunc 1 IN precision Utf8View NULL false 13 +datafusion public date_trunc 2 IN expression Timestamp(Second, None) NULL false 13 +datafusion public date_trunc 1 OUT NULL Timestamp(Second, None) NULL false 13 +datafusion public date_trunc 1 IN precision Utf8 NULL false 14 +datafusion public date_trunc 2 IN expression Timestamp(Second, Some("+TZ")) NULL false 14 +datafusion public date_trunc 1 OUT NULL Timestamp(Second, Some("+TZ")) NULL false 14 +datafusion public date_trunc 1 IN precision Utf8View NULL false 15 +datafusion public date_trunc 2 IN expression Timestamp(Second, Some("+TZ")) NULL false 15 +datafusion public date_trunc 1 OUT NULL Timestamp(Second, Some("+TZ")) NULL false 15 +datafusion public string_agg 1 IN expression LargeUtf8 NULL false 0 +datafusion public string_agg 2 IN delimiter Utf8 NULL false 0 +datafusion public string_agg 1 OUT NULL LargeUtf8 NULL false 0 +datafusion public string_agg 1 IN expression LargeUtf8 NULL false 1 +datafusion public string_agg 2 IN delimiter LargeUtf8 NULL false 1 +datafusion public string_agg 1 OUT NULL LargeUtf8 NULL false 1 +datafusion public string_agg 1 IN expression LargeUtf8 NULL false 2 +datafusion public string_agg 2 IN delimiter Null NULL false 2 +datafusion public string_agg 1 OUT NULL LargeUtf8 NULL false 2 # test variable length arguments -query TTTB rowsort -select specific_name, data_type, parameter_mode, is_variadic from information_schema.parameters where specific_name = 'concat'; +query TTTBI rowsort +select specific_name, data_type, parameter_mode, is_variadic, rid from information_schema.parameters where specific_name = 'concat'; ---- -concat LargeUtf8 IN true -concat LargeUtf8 OUT false -concat Utf8 IN true -concat Utf8 OUT false -concat Utf8View IN true -concat Utf8View OUT false +concat LargeUtf8 IN true 2 +concat LargeUtf8 OUT false 2 +concat Utf8 IN true 1 +concat Utf8 OUT false 1 +concat Utf8View IN true 0 +concat Utf8View OUT false 0 # test ceorcion signature -query TTIT rowsort -select specific_name, data_type, ordinal_position, parameter_mode from information_schema.parameters where specific_name = 'repeat'; ----- -repeat Int64 2 IN -repeat LargeUtf8 1 IN -repeat LargeUtf8 1 OUT -repeat Utf8 1 IN -repeat Utf8 1 OUT -repeat Utf8View 1 IN +query TTITI rowsort +select specific_name, data_type, ordinal_position, parameter_mode, rid from information_schema.parameters where specific_name = 'repeat'; +---- +repeat Int64 2 IN 0 +repeat Int64 2 IN 1 +repeat Int64 2 IN 2 +repeat LargeUtf8 1 IN 1 +repeat LargeUtf8 1 OUT 1 +repeat Utf8 1 IN 0 +repeat Utf8 1 OUT 0 +repeat Utf8 1 OUT 2 +repeat Utf8View 1 IN 2 + +query TT??TTT rowsort +show functions like 'date_trunc'; +---- +date_trunc Timestamp(Microsecond, None) [precision, expression] [Utf8, Timestamp(Microsecond, None)] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Microsecond, None) [precision, expression] [Utf8View, Timestamp(Microsecond, None)] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Microsecond, Some("+TZ")) [precision, expression] [Utf8, Timestamp(Microsecond, Some("+TZ"))] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Microsecond, Some("+TZ")) [precision, expression] [Utf8View, Timestamp(Microsecond, Some("+TZ"))] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Millisecond, None) [precision, expression] [Utf8, Timestamp(Millisecond, None)] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Millisecond, None) [precision, expression] [Utf8View, Timestamp(Millisecond, None)] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Millisecond, Some("+TZ")) [precision, expression] [Utf8, Timestamp(Millisecond, Some("+TZ"))] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Millisecond, Some("+TZ")) [precision, expression] [Utf8View, Timestamp(Millisecond, Some("+TZ"))] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Nanosecond, None) [precision, expression] [Utf8, Timestamp(Nanosecond, None)] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Nanosecond, None) [precision, expression] [Utf8View, Timestamp(Nanosecond, None)] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Nanosecond, Some("+TZ")) [precision, expression] [Utf8, Timestamp(Nanosecond, Some("+TZ"))] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Nanosecond, Some("+TZ")) [precision, expression] [Utf8View, Timestamp(Nanosecond, Some("+TZ"))] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Second, None) [precision, expression] [Utf8, Timestamp(Second, None)] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Second, None) [precision, expression] [Utf8View, Timestamp(Second, None)] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Second, Some("+TZ")) [precision, expression] [Utf8, Timestamp(Second, Some("+TZ"))] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) +date_trunc Timestamp(Second, Some("+TZ")) [precision, expression] [Utf8View, Timestamp(Second, Some("+TZ"))] SCALAR Truncates a timestamp value to a specified precision. date_trunc(precision, expression) + +statement ok +show functions