Skip to main content

risingwave_expr/expr/
expr_literal.rs

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