mz_expr/scalar/func/impls/
byte.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use mz_expr_derive::sqlfunc;
11use mz_ore::cast::CastFrom;
12use mz_repr::strconv;
13
14use crate::EvalError;
15
16#[sqlfunc(
17    sqlname = "bytea_to_text",
18    preserves_uniqueness = true,
19    inverse = to_unary!(super::CastStringToBytes)
20)]
21fn cast_bytes_to_string(a: &[u8]) -> String {
22    let mut buf = String::new();
23    strconv::format_bytes(&mut buf, a);
24    buf
25}
26
27#[sqlfunc(sqlname = "crc32_bytes")]
28fn crc32_bytes<'a>(a: &'a [u8]) -> u32 {
29    crc32fast::hash(a)
30}
31
32#[sqlfunc(sqlname = "crc32_string")]
33fn crc32_string<'a>(a: &'a str) -> u32 {
34    crc32_bytes(a.as_bytes())
35}
36
37#[sqlfunc(sqlname = "kafka_murmur2_bytes")]
38fn kafka_murmur2_bytes<'a>(a: &'a [u8]) -> i32 {
39    i32::from_ne_bytes((murmur2::murmur2(a, murmur2::KAFKA_SEED) & 0x7fffffff).to_ne_bytes())
40}
41
42#[sqlfunc(sqlname = "kafka_murmur2_string")]
43fn kafka_murmur2_string<'a>(a: &'a str) -> i32 {
44    kafka_murmur2_bytes(a.as_bytes())
45}
46
47#[sqlfunc(sqlname = "seahash_bytes")]
48fn seahash_bytes<'a>(a: &'a [u8]) -> u64 {
49    seahash::hash(a)
50}
51
52#[sqlfunc(sqlname = "seahash_string")]
53fn seahash_string<'a>(a: &'a str) -> u64 {
54    seahash_bytes(a.as_bytes())
55}
56
57#[sqlfunc(sqlname = "bit_count")]
58fn bit_count_bytes<'a>(a: &'a [u8]) -> Result<i64, EvalError> {
59    let count: u64 = a.iter().map(|b| u64::cast_from(b.count_ones())).sum();
60    i64::try_from(count).or_else(|_| Err(EvalError::Int64OutOfRange(count.to_string().into())))
61}
62
63#[sqlfunc(sqlname = "bit_length")]
64fn bit_length_bytes<'a>(a: &'a [u8]) -> Result<i32, EvalError> {
65    let val = a.len() * 8;
66    i32::try_from(val).or_else(|_| Err(EvalError::Int32OutOfRange(val.to_string().into())))
67}
68
69#[sqlfunc(sqlname = "octet_length")]
70fn byte_length_bytes<'a>(a: &'a [u8]) -> Result<i32, EvalError> {
71    let val = a.len();
72    i32::try_from(val).or_else(|_| Err(EvalError::Int32OutOfRange(val.to_string().into())))
73}