Skip to main content

risingwave_expr/expr/wrapper/
strict.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::{ArrayRef, DataChunk};
16use risingwave_common::row::OwnedRow;
17use risingwave_common::types::{DataType, Datum};
18
19use crate::ExprError;
20use crate::error::Result;
21use crate::expr::{AsyncExpression, ExpressionInfo, SyncExpression, ValueImpl};
22
23/// A wrapper of an expression that only keeps the first error if multiple errors are returned.
24pub(crate) struct Strict<E> {
25    inner: E,
26}
27
28impl<E> std::fmt::Debug for Strict<E>
29where
30    E: std::fmt::Debug,
31{
32    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33        f.debug_struct("Strict")
34            .field("inner", &self.inner)
35            .finish()
36    }
37}
38
39impl<E> Strict<E>
40where
41    E: ExpressionInfo,
42{
43    pub fn new(inner: E) -> Self {
44        Self { inner }
45    }
46}
47
48impl<E> ExpressionInfo for Strict<E>
49where
50    E: ExpressionInfo,
51{
52    fn return_type(&self) -> DataType {
53        self.inner.return_type()
54    }
55
56    fn input_ref_index(&self) -> Option<usize> {
57        self.inner.input_ref_index()
58    }
59}
60
61macro_rules! strict_eval {
62    ($mode:ident, $this:expr, $input:expr, $method:ident) => {
63        match forward!($mode, $this.inner, $method($input)) {
64            Err(ExprError::Multiple(_, errors)) => Err(errors.into_first()),
65            res => res,
66        }
67    };
68}
69
70impl<E> SyncExpression for Strict<E>
71where
72    E: SyncExpression,
73{
74    fn eval(&self, input: &DataChunk) -> Result<ArrayRef> {
75        strict_eval!(sync, self, input, eval)
76    }
77
78    fn eval_v2(&self, input: &DataChunk) -> Result<ValueImpl> {
79        strict_eval!(sync, self, input, eval_v2)
80    }
81
82    fn eval_row(&self, input: &OwnedRow) -> Result<Datum> {
83        self.inner.eval_row(input)
84    }
85
86    fn eval_const(&self) -> Result<Datum> {
87        self.inner.eval_const()
88    }
89}
90
91impl<E> AsyncExpression for Strict<E>
92where
93    E: AsyncExpression,
94{
95    async fn eval(&self, input: &DataChunk) -> Result<ArrayRef> {
96        strict_eval!(async, self, input, eval)
97    }
98
99    async fn eval_v2(&self, input: &DataChunk) -> Result<ValueImpl> {
100        strict_eval!(async, self, input, eval_v2)
101    }
102
103    async fn eval_row(&self, input: &OwnedRow) -> Result<Datum> {
104        self.inner.eval_row(input).await
105    }
106}