Skip to main content

datafusion_functions/core/
input_file_name.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! [`InputFileNameFunc`]: Implementation of the `input_file_name` function.
19
20use 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}