datafusion_functions/crypto/
digest.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//! "crypto" DataFusion functions
19use super::basic::{digest, utf8_or_binary_to_binary_type};
20use arrow::datatypes::DataType;
21use datafusion_common::Result;
22use datafusion_expr::{
23    ColumnarValue, Documentation, ScalarFunctionArgs, ScalarUDFImpl, Signature,
24    TypeSignature::*, Volatility,
25};
26use datafusion_macros::user_doc;
27use std::any::Any;
28
29#[user_doc(
30    doc_section(label = "Hashing Functions"),
31    description = "Computes the binary hash of an expression using the specified algorithm.",
32    syntax_example = "digest(expression, algorithm)",
33    sql_example = r#"```sql
34> select digest('foo', 'sha256');
35+------------------------------------------+
36| digest(Utf8("foo"), Utf8("sha256"))      |
37+------------------------------------------+
38| <binary_hash_result>                     |
39+------------------------------------------+
40```"#,
41    standard_argument(name = "expression", prefix = "String"),
42    argument(
43        name = "algorithm",
44        description = "String expression specifying algorithm to use. Must be one of:       
45    - md5
46    - sha224
47    - sha256
48    - sha384
49    - sha512
50    - blake2s
51    - blake2b
52    - blake3"
53    )
54)]
55#[derive(Debug)]
56pub struct DigestFunc {
57    signature: Signature,
58}
59impl Default for DigestFunc {
60    fn default() -> Self {
61        Self::new()
62    }
63}
64
65impl DigestFunc {
66    pub fn new() -> Self {
67        use DataType::*;
68        Self {
69            signature: Signature::one_of(
70                vec![
71                    Exact(vec![Utf8View, Utf8View]),
72                    Exact(vec![Utf8, Utf8]),
73                    Exact(vec![LargeUtf8, Utf8]),
74                    Exact(vec![Binary, Utf8]),
75                    Exact(vec![LargeBinary, Utf8]),
76                ],
77                Volatility::Immutable,
78            ),
79        }
80    }
81}
82impl ScalarUDFImpl for DigestFunc {
83    fn as_any(&self) -> &dyn Any {
84        self
85    }
86
87    fn name(&self) -> &str {
88        "digest"
89    }
90
91    fn signature(&self) -> &Signature {
92        &self.signature
93    }
94
95    fn return_type(&self, arg_types: &[DataType]) -> Result<DataType> {
96        utf8_or_binary_to_binary_type(&arg_types[0], self.name())
97    }
98    fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> {
99        digest(&args.args)
100    }
101
102    fn documentation(&self) -> Option<&Documentation> {
103        self.doc()
104    }
105}