risingwave_frontend/expr/secret_ref.rs
1// Copyright 2026 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 risingwave_common::types::DataType;
16use risingwave_pb::expr::expr_node::{RexNode, Type};
17use risingwave_pb::expr::{ExprNode, SecretRefNode};
18use risingwave_pb::secret::secret_ref::RefAsType;
19
20use super::Expr;
21use crate::catalog::SecretId;
22
23/// A reference to a secret that is resolved at runtime on compute nodes.
24///
25/// The secret value is never stored in the plan — only the `secret_id` is serialized.
26/// At execution time, the expression is resolved to a literal via `LocalSecretManager`.
27#[derive(Debug, Clone)]
28pub struct SecretRef {
29 pub secret_id: SecretId,
30 pub ref_as: RefAsType,
31 /// Human-readable name for EXPLAIN output. Not serialized to proto.
32 /// Excluded from `PartialEq`/`Hash` since it's display-only and lost during proto round-trip.
33 pub secret_name: String,
34}
35
36impl PartialEq for SecretRef {
37 fn eq(&self, other: &Self) -> bool {
38 self.secret_id == other.secret_id && self.ref_as == other.ref_as
39 }
40}
41
42impl Eq for SecretRef {}
43
44impl std::hash::Hash for SecretRef {
45 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
46 self.secret_id.hash(state);
47 self.ref_as.hash(state);
48 }
49}
50
51impl Expr for SecretRef {
52 fn return_type(&self) -> DataType {
53 DataType::Varchar
54 }
55
56 fn try_to_expr_proto(&self) -> Result<ExprNode, String> {
57 Ok(ExprNode {
58 function_type: Type::Unspecified.into(),
59 return_type: Some(self.return_type().to_protobuf()),
60 rex_node: Some(RexNode::SecretRef(SecretRefNode {
61 secret_id: self.secret_id.as_raw_id(),
62 ref_as: self.ref_as.into(),
63 })),
64 })
65 }
66}