1use itertools::Itertools;
16use risingwave_common::bail_not_implemented;
17use risingwave_common::types::{
18 DataType, DateTimeField, Decimal, Interval, MapType, ScalarImpl, StructType,
19};
20use risingwave_sqlparser::ast::{DateTimeField as AstDateTimeField, Expr, Value};
21use thiserror_ext::AsReport;
22
23use crate::binder::Binder;
24use crate::error::{ErrorCode, Result};
25use crate::expr::{Expr as _, ExprImpl, ExprType, FunctionCall, Literal, align_types};
26
27impl Binder {
28 pub fn bind_value(&mut self, value: &Value) -> Result<Literal> {
29 match value {
30 Value::Number(s) => self.bind_number(s.clone()),
31 Value::SingleQuotedString(s) => self.bind_string(s),
32 Value::CstyleEscapedString(s) => self.bind_string(&s.value),
33 Value::Boolean(b) => self.bind_bool(*b),
34 Value::Null => Ok(Literal::new_untyped(None)),
37 Value::Interval {
38 value,
39 leading_field,
40 leading_precision: None,
42 last_field: None,
43 fractional_seconds_precision: None,
44 } => self.bind_interval(value, *leading_field),
45 _ => bail_not_implemented!("value: {:?}", value),
46 }
47 }
48
49 pub(super) fn bind_string(&mut self, s: &str) -> Result<Literal> {
50 Ok(Literal::new_untyped(Some(s.to_owned())))
51 }
52
53 fn bind_bool(&mut self, b: bool) -> Result<Literal> {
54 Ok(Literal::new(Some(ScalarImpl::Bool(b)), DataType::Boolean))
55 }
56
57 fn bind_number(&mut self, mut s: String) -> Result<Literal> {
58 let prefix_start = match s.starts_with('-') {
59 true => 1,
60 false => 0,
61 };
62 let base = match prefix_start + 2 <= s.len() {
63 true => match &s[prefix_start..prefix_start + 2] {
64 "0x" => 16,
66 "0o" => 8,
67 "0b" => 2,
68 _ => 10,
69 },
70 false => 10,
71 };
72 if base != 10 {
73 s.replace_range(prefix_start..prefix_start + 2, "");
74 }
75
76 let (data, data_type) = if let Ok(int_32) = i32::from_str_radix(&s, base) {
77 (Some(ScalarImpl::Int32(int_32)), DataType::Int32)
78 } else if let Ok(int_64) = i64::from_str_radix(&s, base) {
79 (Some(ScalarImpl::Int64(int_64)), DataType::Int64)
80 } else if let Ok(decimal) = Decimal::from_str_radix(&s, base) {
81 (Some(ScalarImpl::Decimal(decimal)), DataType::Decimal)
83 } else if let Some(scientific) = Decimal::from_scientific(&s) {
84 (Some(ScalarImpl::Decimal(scientific)), DataType::Decimal)
85 } else {
86 return Err(ErrorCode::BindError(format!("Number {s} overflows")).into());
87 };
88 Ok(Literal::new(data, data_type))
89 }
90
91 fn bind_interval(
92 &mut self,
93 s: &str,
94 leading_field: Option<AstDateTimeField>,
95 ) -> Result<Literal> {
96 let interval =
97 Interval::parse_with_fields(s, leading_field.map(Self::bind_date_time_field))
98 .map_err(|e| ErrorCode::BindError(e.to_report_string()))?;
99 let datum = Some(ScalarImpl::Interval(interval));
100 let literal = Literal::new(datum, DataType::Interval);
101
102 Ok(literal)
103 }
104
105 pub(crate) fn bind_date_time_field(field: AstDateTimeField) -> DateTimeField {
106 match field {
109 AstDateTimeField::Year => DateTimeField::Year,
110 AstDateTimeField::Month => DateTimeField::Month,
111 AstDateTimeField::Day => DateTimeField::Day,
112 AstDateTimeField::Hour => DateTimeField::Hour,
113 AstDateTimeField::Minute => DateTimeField::Minute,
114 AstDateTimeField::Second => DateTimeField::Second,
115 }
116 }
117
118 pub(super) fn bind_array(&mut self, exprs: &[Expr]) -> Result<ExprImpl> {
120 if exprs.is_empty() {
121 return Err(ErrorCode::BindError("cannot determine type of empty array\nHINT: Explicitly cast to the desired type, for example ARRAY[]::integer[].".into()).into());
122 }
123 let mut exprs = exprs
124 .iter()
125 .map(|e| self.bind_expr_inner(e))
126 .collect::<Result<Vec<ExprImpl>>>()?;
127 let element_type = align_types(exprs.iter_mut())?;
128 let expr: ExprImpl = FunctionCall::new_unchecked(
129 ExprType::Array,
130 exprs,
131 DataType::List(Box::new(element_type)),
132 )
133 .into();
134 Ok(expr)
135 }
136
137 pub(super) fn bind_map(&mut self, entries: &[(Expr, Expr)]) -> Result<ExprImpl> {
138 if entries.is_empty() {
139 return Err(ErrorCode::BindError("cannot determine type of empty map\nHINT: Explicitly cast to the desired type, for example MAP{}::map(int,int).".into()).into());
140 }
141 let mut keys = Vec::with_capacity(entries.len());
142 let mut values = Vec::with_capacity(entries.len());
143 for (k, v) in entries {
144 keys.push(self.bind_expr_inner(k)?);
145 values.push(self.bind_expr_inner(v)?);
146 }
147 let key_type = align_types(keys.iter_mut())?;
148 let value_type = align_types(values.iter_mut())?;
149
150 let keys: ExprImpl = FunctionCall::new_unchecked(
151 ExprType::Array,
152 keys,
153 DataType::List(Box::new(key_type.clone())),
154 )
155 .into();
156 let values: ExprImpl = FunctionCall::new_unchecked(
157 ExprType::Array,
158 values,
159 DataType::List(Box::new(value_type.clone())),
160 )
161 .into();
162
163 let expr: ExprImpl = FunctionCall::new_unchecked(
164 ExprType::MapFromKeyValues,
165 vec![keys, values],
166 DataType::Map(MapType::from_kv(key_type, value_type)),
167 )
168 .into();
169 Ok(expr)
170 }
171
172 pub(super) fn bind_array_cast(
173 &mut self,
174 exprs: &[Expr],
175 element_type: &DataType,
176 ) -> Result<ExprImpl> {
177 let exprs = exprs
178 .iter()
179 .map(|e| self.bind_cast_inner(e, element_type))
180 .collect::<Result<Vec<ExprImpl>>>()?;
181
182 let expr: ExprImpl = FunctionCall::new_unchecked(
183 ExprType::Array,
184 exprs,
185 DataType::List(Box::new(element_type.clone())),
186 )
187 .into();
188 Ok(expr)
189 }
190
191 pub(super) fn bind_map_cast(
192 &mut self,
193 entries: &[(Expr, Expr)],
194 map_type: &MapType,
195 ) -> Result<ExprImpl> {
196 let mut keys = Vec::with_capacity(entries.len());
197 let mut values = Vec::with_capacity(entries.len());
198 for (k, v) in entries {
199 keys.push(self.bind_cast_inner(k, map_type.key())?);
200 values.push(self.bind_cast_inner(v, map_type.value())?);
201 }
202
203 let keys: ExprImpl = FunctionCall::new_unchecked(
204 ExprType::Array,
205 keys,
206 DataType::List(Box::new(map_type.key().clone())),
207 )
208 .into();
209 let values: ExprImpl = FunctionCall::new_unchecked(
210 ExprType::Array,
211 values,
212 DataType::List(Box::new(map_type.value().clone())),
213 )
214 .into();
215
216 let expr: ExprImpl = FunctionCall::new_unchecked(
217 ExprType::MapFromKeyValues,
218 vec![keys, values],
219 DataType::Map(map_type.clone()),
220 )
221 .into();
222 Ok(expr)
223 }
224
225 pub(super) fn bind_index(&mut self, obj: &Expr, index: &Expr) -> Result<ExprImpl> {
226 let obj = self.bind_expr_inner(obj)?;
227 match obj.return_type() {
228 DataType::List(return_type) => Ok(FunctionCall::new_unchecked(
229 ExprType::ArrayAccess,
230 vec![obj, self.bind_expr_inner(index)?],
231 *return_type,
232 )
233 .into()),
234 DataType::Map(m) => Ok(FunctionCall::new_unchecked(
235 ExprType::MapAccess,
236 vec![obj, self.bind_expr_inner(index)?],
237 m.value().clone(),
238 )
239 .into()),
240 data_type => Err(ErrorCode::BindError(format!(
241 "index operator applied to type {}, which is not a list or map",
242 data_type
243 ))
244 .into()),
245 }
246 }
247
248 pub(super) fn bind_array_range_index(
249 &mut self,
250 obj: &Expr,
251 start: Option<&Expr>,
252 end: Option<&Expr>,
253 ) -> Result<ExprImpl> {
254 let obj = self.bind_expr_inner(obj)?;
255 let start = match start {
256 None => ExprImpl::literal_int(1),
257 Some(expr) => self
258 .bind_expr_inner(expr)?
259 .cast_implicit(&DataType::Int32)?,
260 };
261 let end = match end {
264 None => ExprImpl::literal_int(i32::MAX),
265 Some(expr) => self
266 .bind_expr_inner(expr)?
267 .cast_implicit(&DataType::Int32)?,
268 };
269 match obj.return_type() {
270 DataType::List(return_type) => Ok(FunctionCall::new_unchecked(
271 ExprType::ArrayRangeAccess,
272 vec![obj, start, end],
273 DataType::List(return_type),
274 )
275 .into()),
276 data_type => Err(ErrorCode::BindError(format!(
277 "array range index applied to type {}, which is not a list",
278 data_type
279 ))
280 .into()),
281 }
282 }
283
284 pub(super) fn bind_row(&mut self, exprs: &[Expr]) -> Result<ExprImpl> {
286 let exprs = exprs
287 .iter()
288 .map(|e| self.bind_expr_inner(e))
289 .collect::<Result<Vec<ExprImpl>>>()?;
290 let data_type =
291 StructType::unnamed(exprs.iter().map(|e| e.return_type()).collect_vec()).into();
292 let expr: ExprImpl = FunctionCall::new_unchecked(ExprType::Row, exprs, data_type).into();
293 Ok(expr)
294 }
295}
296
297#[cfg(test)]
298mod tests {
299 use risingwave_common::types::test_utils::IntervalTestExt;
300 use risingwave_expr::expr::build_from_prost;
301 use risingwave_sqlparser::ast::Value::Number;
302
303 use super::*;
304 use crate::binder::test_utils::mock_binder;
305 use crate::expr::Expr;
306
307 #[tokio::test]
308 async fn test_bind_value() {
309 use std::str::FromStr;
310
311 let mut binder = mock_binder();
312 let values = [
313 "1",
314 "111111111111111",
315 "111111111.111111",
316 "111111111111111111111111",
317 "0.111111",
318 "-0.01",
319 ];
320 let data = [
321 Some(ScalarImpl::Int32(1)),
322 Some(ScalarImpl::Int64(111111111111111)),
323 Some(ScalarImpl::Decimal(
324 Decimal::from_str("111111111.111111").unwrap(),
325 )),
326 Some(ScalarImpl::Decimal(
327 Decimal::from_str("111111111111111111111111").unwrap(),
328 )),
329 Some(ScalarImpl::Decimal(Decimal::from_str("0.111111").unwrap())),
330 Some(ScalarImpl::Decimal(Decimal::from_str("-0.01").unwrap())),
331 ];
332 let data_type = [
333 DataType::Int32,
334 DataType::Int64,
335 DataType::Decimal,
336 DataType::Decimal,
337 DataType::Decimal,
338 DataType::Decimal,
339 ];
340
341 for i in 0..values.len() {
342 let value = Value::Number(String::from(values[i]));
343 let res = binder.bind_value(&value).unwrap();
344 let ans = Literal::new(data[i].clone(), data_type[i].clone());
345 assert_eq!(res, ans);
346 }
347 }
348
349 #[tokio::test]
350 async fn test_bind_radix() {
351 let mut binder = mock_binder();
352
353 for (input, expected) in [
354 ("0x42e3", ScalarImpl::Int32(0x42e3)),
355 ("-0x40", ScalarImpl::Int32(-0x40)),
356 ("0b1101", ScalarImpl::Int32(0b1101)),
357 ("-0b101", ScalarImpl::Int32(-0b101)),
358 ("0o664", ScalarImpl::Int32(0o664)),
359 ("-0o755", ScalarImpl::Int32(-0o755)),
360 ("2147483647", ScalarImpl::Int32(2147483647)),
361 ("2147483648", ScalarImpl::Int64(2147483648)),
362 ("-2147483648", ScalarImpl::Int32(-2147483648)),
363 ("0x7fffffff", ScalarImpl::Int32(0x7fffffff)),
364 ("0x80000000", ScalarImpl::Int64(0x80000000)),
365 ("-0x80000000", ScalarImpl::Int32(-0x80000000)),
366 ] {
367 let lit = binder.bind_number(input.into()).unwrap();
368 assert_eq!(lit.get_data().as_ref().unwrap(), &expected);
369 }
370 }
371
372 #[tokio::test]
373 async fn test_bind_scientific_number() {
374 use std::str::FromStr;
375
376 let mut binder = mock_binder();
377 let values = [
378 ("1e6"),
379 ("1.25e6"),
380 ("1.25e1"),
381 ("1e-2"),
382 ("1.25e-2"),
383 ("1e15"),
384 ];
385 let data = [
386 Some(ScalarImpl::Decimal(Decimal::from_str("1000000").unwrap())),
387 Some(ScalarImpl::Decimal(Decimal::from_str("1250000").unwrap())),
388 Some(ScalarImpl::Decimal(Decimal::from_str("12.5").unwrap())),
389 Some(ScalarImpl::Decimal(Decimal::from_str("0.01").unwrap())),
390 Some(ScalarImpl::Decimal(Decimal::from_str("0.0125").unwrap())),
391 Some(ScalarImpl::Decimal(
392 Decimal::from_str("1000000000000000").unwrap(),
393 )),
394 ];
395 let data_type = [
396 DataType::Decimal,
397 DataType::Decimal,
398 DataType::Decimal,
399 DataType::Decimal,
400 DataType::Decimal,
401 DataType::Decimal,
402 ];
403
404 for i in 0..values.len() {
405 let res = binder.bind_value(&Number(values[i].to_owned())).unwrap();
406 let ans = Literal::new(data[i].clone(), data_type[i].clone());
407 assert_eq!(res, ans);
408 }
409 }
410
411 #[test]
412 fn test_array_expr() {
413 let expr: ExprImpl = FunctionCall::new_unchecked(
414 ExprType::Array,
415 vec![ExprImpl::literal_int(11)],
416 DataType::List(Box::new(DataType::Int32)),
417 )
418 .into();
419 let expr_pb = expr.to_expr_proto();
420 let expr = build_from_prost(&expr_pb).unwrap();
421 match expr.return_type() {
422 DataType::List(datatype) => {
423 assert_eq!(datatype, Box::new(DataType::Int32));
424 }
425 _ => panic!("unexpected type"),
426 };
427 }
428
429 #[test]
430 fn test_array_index_expr() {
431 let array_expr = FunctionCall::new_unchecked(
432 ExprType::Array,
433 vec![ExprImpl::literal_int(11), ExprImpl::literal_int(22)],
434 DataType::List(Box::new(DataType::Int32)),
435 )
436 .into();
437
438 let expr: ExprImpl = FunctionCall::new_unchecked(
439 ExprType::ArrayAccess,
440 vec![array_expr, ExprImpl::literal_int(1)],
441 DataType::Int32,
442 )
443 .into();
444
445 let expr_pb = expr.to_expr_proto();
446 let expr = build_from_prost(&expr_pb).unwrap();
447 assert_eq!(expr.return_type(), DataType::Int32);
448 }
449
450 #[tokio::test]
451 async fn test_bind_interval() {
452 let mut binder = mock_binder();
453 let values = [
454 "1 hour",
455 "1 h",
456 "1 year",
457 "6 second",
458 "2 minutes",
459 "1 month",
460 ];
461 let data = vec![
462 Literal::new(
463 Some(ScalarImpl::Interval(Interval::from_minutes(60))),
464 DataType::Interval,
465 ),
466 Literal::new(
467 Some(ScalarImpl::Interval(Interval::from_minutes(60))),
468 DataType::Interval,
469 ),
470 Literal::new(
471 Some(ScalarImpl::Interval(Interval::from_ymd(1, 0, 0))),
472 DataType::Interval,
473 ),
474 Literal::new(
475 Some(ScalarImpl::Interval(Interval::from_millis(6 * 1000))),
476 DataType::Interval,
477 ),
478 Literal::new(
479 Some(ScalarImpl::Interval(Interval::from_minutes(2))),
480 DataType::Interval,
481 ),
482 Literal::new(
483 Some(ScalarImpl::Interval(Interval::from_month(1))),
484 DataType::Interval,
485 ),
486 ];
487
488 for i in 0..values.len() {
489 let value = Value::Interval {
490 value: values[i].to_owned(),
491 leading_field: None,
492 leading_precision: None,
493 last_field: None,
494 fractional_seconds_precision: None,
495 };
496 assert_eq!(binder.bind_value(&value).unwrap(), data[i]);
497 }
498 }
499}