risingwave_frontend/expr/
literal.rs1use risingwave_common::types::{DataType, Datum, ToText, literal_type_match};
16use risingwave_common::util::value_encoding::{DatumFromProtoExt, DatumToProtoExt};
17use risingwave_pb::expr::expr_node::RexNode;
18
19use super::Expr;
20use crate::expr::ExprType;
21#[derive(Clone, Eq, PartialEq, Hash)]
22pub struct Literal {
23 data: Datum,
24 data_type: Option<DataType>,
26}
27
28impl std::fmt::Debug for Literal {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 if f.alternate() {
31 f.debug_struct("Literal")
32 .field("data", &self.data)
33 .field("data_type", &self.data_type)
34 .finish()
35 } else {
36 let data_type = self.return_type();
37 match &self.data {
38 None => write!(f, "null"),
39 Some(v) => match data_type {
40 DataType::Boolean => write!(f, "{}", v.as_bool()),
41 DataType::Int16
42 | DataType::Int32
43 | DataType::Int64
44 | DataType::Serial
45 | DataType::Decimal
46 | DataType::Float32
47 | DataType::Float64 => write!(f, "{}", v.as_scalar_ref_impl().to_text()),
48 DataType::Varchar
49 | DataType::Bytea
50 | DataType::Date
51 | DataType::Timestamp
52 | DataType::Timestamptz
53 | DataType::Time
54 | DataType::Interval
55 | DataType::Jsonb
56 | DataType::Variant
57 | DataType::Int256
58 | DataType::Struct(_)
59 | DataType::Map(_)
60 | DataType::Vector(_) => write!(
61 f,
62 "'{}'",
63 v.as_scalar_ref_impl().to_text_with_type(&data_type)
64 ),
65 DataType::List { .. } => write!(f, "{}", v.as_list().display_for_explain()),
66 },
67 }?;
68 write!(f, ":{:?}", data_type)
69 }
70 }
71}
72
73impl Literal {
74 pub fn new(data: Datum, data_type: DataType) -> Self {
75 assert!(
76 literal_type_match(&data_type, data.as_ref()),
77 "data_type: {:?}, data: {:?}",
78 data_type,
79 data
80 );
81 Literal {
82 data,
83 data_type: Some(data_type),
84 }
85 }
86
87 pub fn new_untyped(data: Option<String>) -> Self {
88 Literal {
89 data: data.map(Into::into),
90 data_type: None,
91 }
92 }
93
94 pub fn get_data(&self) -> &Datum {
95 &self.data
96 }
97
98 pub fn get_data_type(&self) -> &Option<DataType> {
99 &self.data_type
100 }
101
102 pub fn is_untyped(&self) -> bool {
103 self.data_type.is_none()
104 }
105
106 pub(super) fn from_expr_proto(
107 proto: &risingwave_pb::expr::ExprNode,
108 ) -> crate::error::Result<Self> {
109 let data_type = proto.get_return_type()?;
110 Ok(Self {
111 data: value_encoding_to_literal(&proto.rex_node, &data_type.into())?,
112 data_type: Some(data_type.into()),
113 })
114 }
115}
116
117impl Expr for Literal {
118 fn return_type(&self) -> DataType {
119 self.data_type.clone().unwrap_or(DataType::Varchar)
120 }
121
122 fn try_to_expr_proto(&self) -> Result<risingwave_pb::expr::ExprNode, String> {
123 use risingwave_pb::expr::*;
124
125 Ok(ExprNode {
126 function_type: ExprType::Unspecified as i32,
127 return_type: Some(self.return_type().to_protobuf()),
128 rex_node: Some(literal_to_value_encoding(self.get_data())),
129 })
130 }
131}
132
133pub fn literal_to_value_encoding(d: &Datum) -> RexNode {
135 RexNode::Constant(d.to_protobuf())
136}
137
138fn value_encoding_to_literal(
140 proto: &Option<RexNode>,
141 ty: &DataType,
142) -> crate::error::Result<Datum> {
143 if let Some(rex_node) = proto {
144 if let RexNode::Constant(prost_datum) = rex_node {
145 let datum = Datum::from_protobuf(prost_datum, ty)?;
146 Ok(datum)
147 } else {
148 unreachable!()
149 }
150 } else {
151 Ok(None)
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use risingwave_common::array::{ListValue, StructValue};
158 use risingwave_common::types::{DataType, Datum, ScalarImpl, StructType};
159 use risingwave_common::util::value_encoding::DatumFromProtoExt;
160 use risingwave_pb::expr::expr_node::RexNode;
161
162 use crate::expr::literal::literal_to_value_encoding;
163
164 #[test]
165 fn test_struct_to_value_encoding() {
166 let value = StructValue::new(vec![
167 Some(ScalarImpl::Utf8("".into())),
168 Some(2.into()),
169 Some(3.into()),
170 ]);
171 let data = Some(ScalarImpl::Struct(value.clone()));
172 let node = literal_to_value_encoding(&data);
173 if let RexNode::Constant(prost) = node {
174 let data2 = Datum::from_protobuf(
175 &prost,
176 &StructType::unnamed(vec![DataType::Varchar, DataType::Int32, DataType::Int32])
177 .into(),
178 )
179 .unwrap()
180 .unwrap();
181 assert_eq!(ScalarImpl::Struct(value), data2);
182 }
183 }
184
185 #[test]
186 fn test_list_to_value_encoding() {
187 let value = ListValue::from_iter(["1", "2", ""]);
188 let data = Some(ScalarImpl::List(value.clone()));
189 let node = literal_to_value_encoding(&data);
190 if let RexNode::Constant(prost) = node {
191 let data2 = Datum::from_protobuf(&prost, &DataType::Varchar.list())
192 .unwrap()
193 .unwrap();
194 assert_eq!(ScalarImpl::List(value), data2);
195 }
196 }
197}