risingwave_frontend/binder/expr/
binary_op.rs1use risingwave_common::bail_not_implemented;
16use risingwave_common::types::{DataType, JsonbVal};
17use risingwave_sqlparser::ast::{BinaryOperator, Expr};
18
19use crate::binder::Binder;
20use crate::error::{ErrorCode, Result};
21use crate::expr::{Expr as _, ExprImpl, ExprType, FunctionCall};
22
23impl Binder {
24 pub(super) fn bind_binary_op(
25 &mut self,
26 left: Expr,
27 op: BinaryOperator,
28 mut right: Expr,
29 ) -> Result<ExprImpl> {
30 let bound_left = self.bind_expr_inner(left)?;
31
32 let mut func_types = vec![];
33
34 right = match right {
35 Expr::SomeOp(expr) => {
36 func_types.push(ExprType::Some);
37 *expr
38 }
39 Expr::AllOp(expr) => {
40 func_types.push(ExprType::All);
41 *expr
42 }
43 right => right,
44 };
45
46 let bound_right = self.bind_expr_inner(right)?;
47
48 if matches!(op, BinaryOperator::PathMatch | BinaryOperator::PathExists) {
49 return Ok(FunctionCall::new_unchecked(
52 match op {
53 BinaryOperator::PathMatch => ExprType::JsonbPathMatch,
54 BinaryOperator::PathExists => ExprType::JsonbPathExists,
55 _ => unreachable!(),
56 },
57 vec![
58 bound_left,
59 bound_right,
60 ExprImpl::literal_jsonb(JsonbVal::empty_object()), ExprImpl::literal_bool(true), ],
63 DataType::Boolean,
64 )
65 .into());
66 }
67
68 func_types.extend(Self::resolve_binary_operator(
69 op,
70 &bound_left,
71 &bound_right,
72 )?);
73
74 FunctionCall::new_binary_op_func(func_types, vec![bound_left, bound_right])
75 }
76
77 fn resolve_binary_operator(
78 op: BinaryOperator,
79 bound_left: &ExprImpl,
80 bound_right: &ExprImpl,
81 ) -> Result<Vec<ExprType>> {
82 let mut func_types = vec![];
83 let final_type = match op {
84 BinaryOperator::Plus => ExprType::Add,
85 BinaryOperator::Minus => ExprType::Subtract,
86 BinaryOperator::Multiply => ExprType::Multiply,
87 BinaryOperator::Divide => ExprType::Divide,
88 BinaryOperator::Modulo => ExprType::Modulus,
89 BinaryOperator::NotEq => ExprType::NotEqual,
90 BinaryOperator::Eq => ExprType::Equal,
91 BinaryOperator::Lt => ExprType::LessThan,
92 BinaryOperator::LtEq => ExprType::LessThanOrEqual,
93 BinaryOperator::Gt => ExprType::GreaterThan,
94 BinaryOperator::GtEq => ExprType::GreaterThanOrEqual,
95 BinaryOperator::And => ExprType::And,
96 BinaryOperator::Or => ExprType::Or,
97 BinaryOperator::PGLikeMatch => ExprType::Like,
98 BinaryOperator::PGNotLikeMatch => {
99 func_types.push(ExprType::Not);
100 ExprType::Like
101 }
102 BinaryOperator::PGILikeMatch => ExprType::ILike,
103 BinaryOperator::PGNotILikeMatch => {
104 func_types.push(ExprType::Not);
105 ExprType::ILike
106 }
107 BinaryOperator::BitwiseOr => ExprType::BitwiseOr,
108 BinaryOperator::BitwiseAnd => ExprType::BitwiseAnd,
109 BinaryOperator::BitwiseXor => ExprType::Pow,
110 BinaryOperator::PGBitwiseXor => ExprType::BitwiseXor,
111 BinaryOperator::PGBitwiseShiftLeft => ExprType::BitwiseShiftLeft,
112 BinaryOperator::PGBitwiseShiftRight => ExprType::BitwiseShiftRight,
113 BinaryOperator::Arrow => ExprType::JsonbAccess,
114 BinaryOperator::LongArrow => ExprType::JsonbAccessStr,
115 BinaryOperator::HashMinus => ExprType::JsonbDeletePath,
116 BinaryOperator::HashArrow => ExprType::JsonbExtractPathVariadic,
117 BinaryOperator::HashLongArrow => ExprType::JsonbExtractPathTextVariadic,
118 BinaryOperator::Prefix => ExprType::StartsWith,
119 BinaryOperator::Contains => {
120 let left_type = (!bound_left.is_untyped()).then(|| bound_left.return_type());
121 let right_type = (!bound_right.is_untyped()).then(|| bound_right.return_type());
122 match (left_type, right_type) {
123 (Some(DataType::List { .. }), Some(DataType::List { .. }))
124 | (Some(DataType::List { .. }), None)
125 | (None, Some(DataType::List { .. })) => ExprType::ArrayContains,
126 (Some(DataType::Jsonb), Some(DataType::Jsonb))
127 | (Some(DataType::Jsonb), None)
128 | (None, Some(DataType::Jsonb)) => ExprType::JsonbContains,
129 (left, right) => {
130 return Err(ErrorCode::BindError(format!(
131 "operator does not exist: {} @> {}",
132 left.map_or_else(|| String::from("unknown"), |x| x.to_string()),
133 right.map_or_else(|| String::from("unknown"), |x| x.to_string()),
134 ))
135 .into());
136 }
137 }
138 }
139 BinaryOperator::Contained => {
140 let left_type = (!bound_left.is_untyped()).then(|| bound_left.return_type());
141 let right_type = (!bound_right.is_untyped()).then(|| bound_right.return_type());
142 match (left_type, right_type) {
143 (Some(DataType::List { .. }), Some(DataType::List { .. }))
144 | (Some(DataType::List { .. }), None)
145 | (None, Some(DataType::List { .. })) => ExprType::ArrayContained,
146 (Some(DataType::Jsonb), Some(DataType::Jsonb))
147 | (Some(DataType::Jsonb), None)
148 | (None, Some(DataType::Jsonb)) => ExprType::JsonbContained,
149 (left, right) => {
150 return Err(ErrorCode::BindError(format!(
151 "operator does not exist: {} <@ {}",
152 left.map_or_else(|| String::from("unknown"), |x| x.to_string()),
153 right.map_or_else(|| String::from("unknown"), |x| x.to_string()),
154 ))
155 .into());
156 }
157 }
158 }
159 BinaryOperator::Exists => ExprType::JsonbExists,
160 BinaryOperator::ExistsAny => ExprType::JsonbExistsAny,
161 BinaryOperator::ExistsAll => ExprType::JsonbExistsAll,
162 BinaryOperator::Concat => {
163 let left_type = (!bound_left.is_untyped()).then(|| bound_left.return_type());
164 let right_type = (!bound_right.is_untyped()).then(|| bound_right.return_type());
165 match (left_type, right_type) {
166 (Some(DataType::List { .. }), Some(DataType::List { .. }))
168 | (Some(DataType::List { .. }), None)
169 | (None, Some(DataType::List { .. })) => ExprType::ArrayCat,
170 (Some(DataType::List { .. }), Some(_)) => ExprType::ArrayAppend,
171 (Some(_), Some(DataType::List { .. })) => ExprType::ArrayPrepend,
172
173 (Some(DataType::Varchar), _) | (_, Some(DataType::Varchar)) => {
175 ExprType::ConcatOp
176 }
177
178 (Some(DataType::Jsonb), Some(DataType::Jsonb))
179 | (Some(DataType::Jsonb), None)
180 | (None, Some(DataType::Jsonb)) => ExprType::JsonbConcat,
181
182 (Some(t @ DataType::Bytea), Some(DataType::Bytea))
184 | (Some(t @ DataType::Bytea), None)
185 | (None, Some(t @ DataType::Bytea)) => {
186 return Err(ErrorCode::BindError(format!(
187 "operator not implemented yet: {t} || {t}"
188 ))
189 .into());
190 }
191
192 (None, _) | (_, None) => ExprType::ConcatOp,
194
195 (Some(left_type), Some(right_type)) => {
197 return Err(ErrorCode::BindError(format!(
198 "operator does not exist: {} || {}",
199 left_type, right_type
200 ))
201 .into());
202 }
203 }
204 }
205 BinaryOperator::PGRegexMatch => ExprType::RegexpEq,
206 BinaryOperator::PGRegexNotMatch => {
207 func_types.push(ExprType::Not);
208 ExprType::RegexpEq
209 }
210 _ => bail_not_implemented!(issue = 112, "binary op: {:?}", op),
211 };
212 func_types.push(final_type);
213 Ok(func_types)
214 }
215}