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

goldmedal 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 cb7ec85ee3 introduce information_schema.parameters table (#13341)
cb7ec85ee3 is described below

commit cb7ec85ee3a41e368563e60567104a77240fc7b4
Author: Jax Liu <[email protected]>
AuthorDate: Tue Nov 12 09:34:25 2024 +0800

    introduce information_schema.parameters table (#13341)
---
 .../core/src/catalog_common/information_schema.rs  | 243 ++++++++++++++++++++-
 .../sqllogictest/test_files/information_schema.slt |  57 +++++
 .../information_schema_multiple_catalogs.slt       |   4 +
 .../test_files/information_schema_table_types.slt  |   1 +
 4 files changed, 302 insertions(+), 3 deletions(-)

diff --git a/datafusion/core/src/catalog_common/information_schema.rs 
b/datafusion/core/src/catalog_common/information_schema.rs
index 53c1a8b11e..72f842d367 100644
--- a/datafusion/core/src/catalog_common/information_schema.rs
+++ b/datafusion/core/src/catalog_common/information_schema.rs
@@ -38,7 +38,7 @@ use arrow_array::builder::BooleanBuilder;
 use async_trait::async_trait;
 use datafusion_common::error::Result;
 use datafusion_common::DataFusionError;
-use datafusion_expr::{AggregateUDF, ScalarUDF, Signature, WindowUDF};
+use datafusion_expr::{AggregateUDF, ScalarUDF, Signature, TypeSignature, 
WindowUDF};
 use std::collections::{HashMap, HashSet};
 use std::fmt::Debug;
 use std::{any::Any, sync::Arc};
@@ -50,10 +50,18 @@ pub(crate) const COLUMNS: &str = "columns";
 pub(crate) const DF_SETTINGS: &str = "df_settings";
 pub(crate) const SCHEMATA: &str = "schemata";
 pub(crate) const ROUTINES: &str = "routines";
+pub(crate) const PARAMETERS: &str = "parameters";
 
 /// All information schema tables
-pub const INFORMATION_SCHEMA_TABLES: &[&str] =
-    &[TABLES, VIEWS, COLUMNS, DF_SETTINGS, SCHEMATA, ROUTINES];
+pub const INFORMATION_SCHEMA_TABLES: &[&str] = &[
+    TABLES,
+    VIEWS,
+    COLUMNS,
+    DF_SETTINGS,
+    SCHEMATA,
+    ROUTINES,
+    PARAMETERS,
+];
 
 /// Implements the `information_schema` virtual schema and tables
 ///
@@ -286,6 +294,102 @@ impl InformationSchemaConfig {
     fn is_deterministic(signature: &Signature) -> bool {
         signature.volatility == Volatility::Immutable
     }
+    fn make_parameters(
+        &self,
+        udfs: &HashMap<String, Arc<ScalarUDF>>,
+        udafs: &HashMap<String, Arc<AggregateUDF>>,
+        udwfs: &HashMap<String, Arc<WindowUDF>>,
+        config_options: &ConfigOptions,
+        builder: &mut InformationSchemaParametersBuilder,
+    ) -> Result<()> {
+        let catalog_name = &config_options.catalog.default_catalog;
+        let schema_name = &config_options.catalog.default_schema;
+        let mut add_parameters = |func_name: &str,
+                                  args: Option<&Vec<(String, String)>>,
+                                  arg_types: Vec<String>,
+                                  return_type: Option<String>,
+                                  is_variadic: bool| {
+            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()));
+                builder.add_parameter(
+                    catalog_name,
+                    schema_name,
+                    func_name,
+                    position as u64 + 1,
+                    "IN",
+                    param_name,
+                    type_name,
+                    None::<&str>,
+                    is_variadic,
+                );
+            }
+            if let Some(return_type) = return_type {
+                builder.add_parameter(
+                    catalog_name,
+                    schema_name,
+                    func_name,
+                    1,
+                    "OUT",
+                    None::<&str>,
+                    return_type.as_str(),
+                    None::<&str>,
+                    false,
+                );
+            }
+        };
+
+        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 {
+                add_parameters(
+                    func_name,
+                    args.as_ref(),
+                    arg_types,
+                    return_type,
+                    Self::is_variadic(udf.signature()),
+                );
+            }
+        }
+
+        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 {
+                add_parameters(
+                    func_name,
+                    args.as_ref(),
+                    arg_types,
+                    return_type,
+                    Self::is_variadic(udaf.signature()),
+                );
+            }
+        }
+
+        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 {
+                add_parameters(
+                    func_name,
+                    args.as_ref(),
+                    arg_types,
+                    return_type,
+                    Self::is_variadic(udwf.signature()),
+                );
+            }
+        }
+
+        Ok(())
+    }
+
+    fn is_variadic(signature: &Signature) -> bool {
+        matches!(
+            signature.type_signature,
+            TypeSignature::Variadic(_) | TypeSignature::VariadicAny
+        )
+    }
 }
 
 /// get the arguments and return types of a UDF
@@ -384,6 +488,7 @@ impl SchemaProvider for InformationSchemaProvider {
             DF_SETTINGS => Arc::new(InformationSchemaDfSettings::new(config)),
             SCHEMATA => Arc::new(InformationSchemata::new(config)),
             ROUTINES => Arc::new(InformationSchemaRoutines::new(config)),
+            PARAMETERS => Arc::new(InformationSchemaParameters::new(config)),
             _ => return Ok(None),
         };
 
@@ -1098,3 +1203,135 @@ impl PartitionStream for InformationSchemaRoutines {
         ))
     }
 }
+
+#[derive(Debug)]
+struct InformationSchemaParameters {
+    schema: SchemaRef,
+    config: InformationSchemaConfig,
+}
+
+impl InformationSchemaParameters {
+    fn new(config: InformationSchemaConfig) -> Self {
+        let schema = Arc::new(Schema::new(vec![
+            Field::new("specific_catalog", DataType::Utf8, false),
+            Field::new("specific_schema", DataType::Utf8, false),
+            Field::new("specific_name", DataType::Utf8, false),
+            Field::new("ordinal_position", DataType::UInt64, false),
+            Field::new("parameter_mode", DataType::Utf8, false),
+            Field::new("parameter_name", DataType::Utf8, true),
+            Field::new("data_type", DataType::Utf8, false),
+            Field::new("parameter_default", DataType::Utf8, true),
+            Field::new("is_variadic", DataType::Boolean, false),
+        ]));
+
+        Self { schema, config }
+    }
+
+    fn builder(&self) -> InformationSchemaParametersBuilder {
+        InformationSchemaParametersBuilder {
+            schema: self.schema.clone(),
+            specific_catalog: StringBuilder::new(),
+            specific_schema: StringBuilder::new(),
+            specific_name: StringBuilder::new(),
+            ordinal_position: UInt64Builder::new(),
+            parameter_mode: StringBuilder::new(),
+            parameter_name: StringBuilder::new(),
+            data_type: StringBuilder::new(),
+            parameter_default: StringBuilder::new(),
+            is_variadic: BooleanBuilder::new(),
+            inserted: HashSet::new(),
+        }
+    }
+}
+
+struct InformationSchemaParametersBuilder {
+    schema: SchemaRef,
+    specific_catalog: StringBuilder,
+    specific_schema: StringBuilder,
+    specific_name: StringBuilder,
+    ordinal_position: UInt64Builder,
+    parameter_mode: StringBuilder,
+    parameter_name: StringBuilder,
+    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)>,
+}
+
+impl InformationSchemaParametersBuilder {
+    #[allow(clippy::too_many_arguments)]
+    fn add_parameter(
+        &mut self,
+        specific_catalog: impl AsRef<str>,
+        specific_schema: impl AsRef<str>,
+        specific_name: impl AsRef<str>,
+        ordinal_position: u64,
+        parameter_mode: impl AsRef<str>,
+        parameter_name: Option<impl AsRef<str>>,
+        data_type: impl AsRef<str>,
+        parameter_default: Option<impl AsRef<str>>,
+        is_variadic: bool,
+    ) {
+        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);
+        }
+    }
+
+    fn finish(&mut self) -> RecordBatch {
+        RecordBatch::try_new(
+            self.schema.clone(),
+            vec![
+                Arc::new(self.specific_catalog.finish()),
+                Arc::new(self.specific_schema.finish()),
+                Arc::new(self.specific_name.finish()),
+                Arc::new(self.ordinal_position.finish()),
+                Arc::new(self.parameter_mode.finish()),
+                Arc::new(self.parameter_name.finish()),
+                Arc::new(self.data_type.finish()),
+                Arc::new(self.parameter_default.finish()),
+                Arc::new(self.is_variadic.finish()),
+            ],
+        )
+        .unwrap()
+    }
+}
+
+impl PartitionStream for InformationSchemaParameters {
+    fn schema(&self) -> &SchemaRef {
+        &self.schema
+    }
+
+    fn execute(&self, ctx: Arc<TaskContext>) -> SendableRecordBatchStream {
+        let config = self.config.clone();
+        let mut builder = self.builder();
+        Box::pin(RecordBatchStreamAdapter::new(
+            self.schema.clone(),
+            futures::stream::once(async move {
+                config.make_parameters(
+                    ctx.scalar_functions(),
+                    ctx.aggregate_functions(),
+                    ctx.window_functions(),
+                    ctx.session_config().options(),
+                    &mut builder,
+                )?;
+                Ok(builder.finish())
+            }),
+        ))
+    }
+}
diff --git a/datafusion/sqllogictest/test_files/information_schema.slt 
b/datafusion/sqllogictest/test_files/information_schema.slt
index dd5156cb53..4d51a61c8a 100644
--- a/datafusion/sqllogictest/test_files/information_schema.slt
+++ b/datafusion/sqllogictest/test_files/information_schema.slt
@@ -39,6 +39,7 @@ SELECT * from information_schema.tables;
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
@@ -84,6 +85,7 @@ SELECT * from information_schema.tables;
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
@@ -99,6 +101,7 @@ SELECT * from information_schema.tables;
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
@@ -111,6 +114,7 @@ SELECT * from information_schema.tables WHERE 
tables.table_schema='information_s
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
@@ -121,6 +125,7 @@ SELECT * from information_schema.tables WHERE 
information_schema.tables.table_sc
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
@@ -131,6 +136,7 @@ SELECT * from information_schema.tables WHERE 
datafusion.information_schema.tabl
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
@@ -454,6 +460,7 @@ SHOW TABLES
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
@@ -636,3 +643,53 @@ query B
 select is_deterministic from information_schema.routines where routine_name = 
'now';
 ----
 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
+
+# test variable length arguments
+query TTTB rowsort
+select specific_name, data_type, parameter_mode, is_variadic 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
+
+# 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
diff --git 
a/datafusion/sqllogictest/test_files/information_schema_multiple_catalogs.slt 
b/datafusion/sqllogictest/test_files/information_schema_multiple_catalogs.slt
index 988a4275c6..0594aa7cfc 100644
--- 
a/datafusion/sqllogictest/test_files/information_schema_multiple_catalogs.slt
+++ 
b/datafusion/sqllogictest/test_files/information_schema_multiple_catalogs.slt
@@ -35,6 +35,7 @@ SELECT * from information_schema.tables;
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
@@ -81,12 +82,14 @@ SELECT * from information_schema.tables;
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW
 datafusion information_schema views VIEW
 my_catalog information_schema columns VIEW
 my_catalog information_schema df_settings VIEW
+my_catalog information_schema parameters VIEW
 my_catalog information_schema routines VIEW
 my_catalog information_schema schemata VIEW
 my_catalog information_schema tables VIEW
@@ -95,6 +98,7 @@ my_catalog my_schema t1 BASE TABLE
 my_catalog my_schema t2 BASE TABLE
 my_other_catalog information_schema columns VIEW
 my_other_catalog information_schema df_settings VIEW
+my_other_catalog information_schema parameters VIEW
 my_other_catalog information_schema routines VIEW
 my_other_catalog information_schema schemata VIEW
 my_other_catalog information_schema tables VIEW
diff --git 
a/datafusion/sqllogictest/test_files/information_schema_table_types.slt 
b/datafusion/sqllogictest/test_files/information_schema_table_types.slt
index 8a1a94c6a0..5650d537b0 100644
--- a/datafusion/sqllogictest/test_files/information_schema_table_types.slt
+++ b/datafusion/sqllogictest/test_files/information_schema_table_types.slt
@@ -36,6 +36,7 @@ SELECT * from information_schema.tables;
 ----
 datafusion information_schema columns VIEW
 datafusion information_schema df_settings VIEW
+datafusion information_schema parameters VIEW
 datafusion information_schema routines VIEW
 datafusion information_schema schemata VIEW
 datafusion information_schema tables VIEW


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

Reply via email to