risingwave_expr/expr/
expr_literal.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 risingwave_common::array::DataChunk;
16use risingwave_common::row::OwnedRow;
17use risingwave_common::types::{DataType, Datum, literal_type_match};
18use risingwave_common::util::value_encoding::DatumFromProtoExt;
19use risingwave_pb::expr::ExprNode;
20
21use super::{Build, ValueImpl};
22use crate::expr::Expression;
23use crate::{ExprError, Result};
24
25/// A literal expression.
26#[derive(Clone, Debug)]
27pub struct LiteralExpression {
28    return_type: DataType,
29    literal: Datum,
30}
31
32#[async_trait::async_trait]
33impl Expression for LiteralExpression {
34    fn return_type(&self) -> DataType {
35        self.return_type.clone()
36    }
37
38    async fn eval_v2(&self, input: &DataChunk) -> Result<ValueImpl> {
39        Ok(ValueImpl::Scalar {
40            value: self.literal.clone(),
41            capacity: input.capacity(),
42        })
43    }
44
45    async fn eval_row(&self, _input: &OwnedRow) -> Result<Datum> {
46        Ok(self.literal.as_ref().cloned())
47    }
48
49    fn eval_const(&self) -> Result<Datum> {
50        Ok(self.literal.clone())
51    }
52}
53
54impl LiteralExpression {
55    pub fn new(return_type: DataType, literal: Datum) -> Self {
56        assert!(literal_type_match(&return_type, literal.as_ref()));
57        LiteralExpression {
58            return_type,
59            literal,
60        }
61    }
62
63    pub fn literal(&self) -> Datum {
64        self.literal.clone()
65    }
66}
67
68impl Build for LiteralExpression {
69    fn build(
70        prost: &ExprNode,
71        _build_child: impl Fn(&ExprNode) -> Result<super::BoxedExpression>,
72    ) -> Result<Self> {
73        let ret_type = DataType::from(prost.get_return_type().unwrap());
74
75        let prost_value = prost.get_rex_node().unwrap().as_constant().unwrap();
76
77        let value = Datum::from_protobuf(
78            prost_value,
79            &DataType::from(prost.get_return_type().unwrap()),
80        )
81        .map_err(|e| ExprError::Internal(e.into()))?;
82        Ok(Self {
83            return_type: ret_type,
84            literal: value,
85        })
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use risingwave_common::array::{I32Array, StructValue};
92    use risingwave_common::types::test_utils::IntervalTestExt;
93    use risingwave_common::types::{Decimal, Interval, IntoOrdered, Scalar, ScalarImpl};
94    use risingwave_common::util::value_encoding::{DatumToProtoExt, serialize_datum};
95    use risingwave_pb::data::data_type::{IntervalType, TypeName};
96    use risingwave_pb::data::{PbDataType, PbDatum};
97    use risingwave_pb::expr::expr_node::RexNode::{self, Constant};
98    use risingwave_pb::expr::expr_node::Type;
99
100    use super::*;
101
102    #[test]
103    fn test_struct_expr_literal_from() {
104        let value = StructValue::new(vec![
105            Some(ScalarImpl::Utf8("12222".into())),
106            Some(2.into()),
107            None,
108        ]);
109        let pb_datum = Some(value.clone().to_scalar_value()).to_protobuf();
110        let expr = ExprNode {
111            function_type: Type::Unspecified as i32,
112            return_type: Some(PbDataType {
113                type_name: TypeName::Struct as i32,
114                field_type: vec![
115                    PbDataType {
116                        type_name: TypeName::Varchar as i32,
117                        ..Default::default()
118                    },
119                    PbDataType {
120                        type_name: TypeName::Int32 as i32,
121                        ..Default::default()
122                    },
123                    PbDataType {
124                        type_name: TypeName::Int32 as i32,
125                        ..Default::default()
126                    },
127                ],
128                ..Default::default()
129            }),
130            rex_node: Some(Constant(pb_datum)),
131        };
132        let expr = LiteralExpression::build_for_test(&expr).unwrap();
133        assert_eq!(value.to_scalar_value(), expr.literal().unwrap());
134    }
135
136    #[test]
137    fn test_expr_literal_from() {
138        let v = true;
139        let t = TypeName::Boolean;
140        let bytes = serialize_datum(Some(v.to_scalar_value()).as_ref());
141
142        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
143        assert_eq!(v.to_scalar_value(), expr.literal().unwrap());
144
145        let v = 1i16;
146        let t = TypeName::Int16;
147        let bytes = serialize_datum(Some(v.to_scalar_value()).as_ref());
148
149        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
150        assert_eq!(v.to_scalar_value(), expr.literal().unwrap());
151
152        let v = 1i32;
153        let t = TypeName::Int32;
154        let bytes = serialize_datum(Some(v.to_scalar_value()).as_ref());
155        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
156        assert_eq!(v.to_scalar_value(), expr.literal().unwrap());
157
158        let v = 1i64;
159        let t = TypeName::Int64;
160        let bytes = serialize_datum(Some(v.to_scalar_value()).as_ref());
161        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
162        assert_eq!(v.to_scalar_value(), expr.literal().unwrap());
163
164        let v = 1f32.into_ordered();
165        let t = TypeName::Float;
166        let bytes = serialize_datum(Some(v.to_scalar_value()).as_ref());
167        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
168        assert_eq!(v.to_scalar_value(), expr.literal().unwrap());
169
170        let v = 1f64.into_ordered();
171        let t = TypeName::Double;
172        let bytes = serialize_datum(Some(v.to_scalar_value()).as_ref());
173        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
174        assert_eq!(v.to_scalar_value(), expr.literal().unwrap());
175
176        let v = None;
177        let t = TypeName::Float;
178        let bytes = serialize_datum(Datum::None);
179        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
180        assert_eq!(v, expr.literal());
181
182        let v: Box<str> = "varchar".into();
183        let t = TypeName::Varchar;
184        let bytes = serialize_datum(Some(v.clone().to_scalar_value()).as_ref());
185        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
186        assert_eq!(v.to_scalar_value(), expr.literal().unwrap());
187
188        let v = Decimal::from_i128_with_scale(3141, 3);
189        let t = TypeName::Decimal;
190        let bytes = serialize_datum(Some(v.to_scalar_value()).as_ref());
191        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
192        assert_eq!(v.to_scalar_value(), expr.literal().unwrap());
193
194        let v = 32i32;
195        let t = TypeName::Interval;
196        let bytes = serialize_datum(Some(Interval::from_month(v).to_scalar_value()).as_ref());
197        let expr = LiteralExpression::build_for_test(&make_expression(bytes, t)).unwrap();
198        assert_eq!(
199            Interval::from_month(v).to_scalar_value(),
200            expr.literal().unwrap()
201        );
202    }
203
204    fn make_expression(bytes: Vec<u8>, data_type: TypeName) -> ExprNode {
205        ExprNode {
206            function_type: Type::Unspecified as i32,
207            return_type: Some(PbDataType {
208                type_name: data_type as i32,
209                interval_type: IntervalType::Month as i32,
210                ..Default::default()
211            }),
212            rex_node: Some(RexNode::Constant(PbDatum { body: bytes })),
213        }
214    }
215
216    #[tokio::test]
217    async fn test_literal_eval_dummy_chunk() {
218        let literal = LiteralExpression::new(DataType::Int32, Some(1.into()));
219        let result = literal.eval(&DataChunk::new_dummy(1)).await.unwrap();
220        assert_eq!(*result, I32Array::from_iter([1]).into());
221    }
222
223    #[tokio::test]
224    async fn test_literal_eval_row_dummy_chunk() {
225        let literal = LiteralExpression::new(DataType::Int32, Some(1.into()));
226        let result = literal.eval_row(&OwnedRow::new(vec![])).await.unwrap();
227        assert_eq!(result, Some(1.into()))
228    }
229}