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