datafusion_functions/core/
input_file_name.rs1use arrow::datatypes::DataType;
21use datafusion_common::{exec_err, utils::take_function_args};
22use datafusion_doc::Documentation;
23use datafusion_expr::{
24 ColumnarValue, ExpressionPlacement, ScalarFunctionArgs, ScalarUDFImpl, Signature,
25 Volatility,
26};
27use datafusion_macros::user_doc;
28
29#[user_doc(
30 doc_section(label = "Other Functions"),
31 description = r#"Returns the path of the input file that produced the current row.
32
33Note: file paths/URIs may be sensitive metadata depending on your environment.
34
35This function is intended to be rewritten at file-scan time (when the file is
36known). If the input file is not known (for example, if this function is
37evaluated outside a file scan, or was not pushed down into one), direct evaluation returns an error.
38"#,
39 syntax_example = "input_file_name()",
40 sql_example = r#"```sql
41SELECT input_file_name() FROM t;
42```"#
43)]
44#[derive(Debug, PartialEq, Eq, Hash)]
45pub struct InputFileNameFunc {
46 signature: Signature,
47}
48
49impl Default for InputFileNameFunc {
50 fn default() -> Self {
51 Self::new()
52 }
53}
54
55impl InputFileNameFunc {
56 pub fn new() -> Self {
57 Self {
58 signature: Signature::nullary(Volatility::Volatile),
59 }
60 }
61}
62
63impl ScalarUDFImpl for InputFileNameFunc {
64 fn name(&self) -> &str {
65 "input_file_name"
66 }
67
68 fn signature(&self) -> &Signature {
69 &self.signature
70 }
71
72 fn return_type(&self, arg_types: &[DataType]) -> datafusion_common::Result<DataType> {
73 let [] = take_function_args(self.name(), arg_types)?;
74 Ok(DataType::Utf8)
75 }
76
77 fn invoke_with_args(
78 &self,
79 args: ScalarFunctionArgs,
80 ) -> datafusion_common::Result<ColumnarValue> {
81 let [] = take_function_args(self.name(), args.args)?;
82
83 exec_err!(
84 "input_file_name() is source dependent and cannot be evaluated directly"
85 )
86 }
87
88 fn placement(&self, _args: &[ExpressionPlacement]) -> ExpressionPlacement {
89 ExpressionPlacement::MoveTowardsLeafNodes
90 }
91
92 fn documentation(&self) -> Option<&Documentation> {
93 self.doc()
94 }
95}