risingwave_expr_impl/scalar/
md5.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use md5::{Digest as _, Md5};
16use risingwave_expr::function;
17
18#[function("md5(varchar) -> varchar")]
19pub fn md5(s: &str, writer: &mut impl std::fmt::Write) {
20    write!(writer, "{:x}", Md5::digest(s)).unwrap();
21}
22
23#[function("md5(bytea) -> varchar")]
24pub fn md5_from_bytea(s: &[u8], writer: &mut impl std::fmt::Write) {
25    writer.write_str(&::hex::encode(Md5::digest(s))).unwrap();
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31
32    #[test]
33    fn test_md5() {
34        let cases = [
35            ("hello world", "5eb63bbbe01eeed093cb22bb8f5acdc3"),
36            ("hello RUST", "917b821a0a5f23ab0cfdb36056d2eb9d"),
37            (
38                "abcdefghijklmnopqrstuvwxyz",
39                "c3fcd3d76192e4007dfb496cca67e13b",
40            ),
41        ];
42
43        for (s, expected) in cases {
44            let mut writer = String::new();
45            md5(s, &mut writer);
46            assert_eq!(writer, expected);
47        }
48    }
49
50    #[test]
51    fn test_md5_bytea() {
52        let cases = [
53            ("hello world".as_bytes(), "5eb63bbbe01eeed093cb22bb8f5acdc3"),
54            ("hello RUST".as_bytes(), "917b821a0a5f23ab0cfdb36056d2eb9d"),
55            (
56                "abcdefghijklmnopqrstuvwxyz".as_bytes(),
57                "c3fcd3d76192e4007dfb496cca67e13b",
58            ),
59        ];
60
61        for (s, expected) in cases {
62            let mut writer = String::new();
63            md5_from_bytea(s, &mut writer);
64            assert_eq!(writer, expected);
65        }
66    }
67}