1use std::str::FromStr;
16
17use common_time::Timestamp;
18use common_time::timezone::Timezone;
19use datatypes::prelude::ConcreteDataType;
20use datatypes::schema::ColumnDefaultConstraint;
21use datatypes::types::{parse_string_to_json_type_value, parse_string_to_vector_type_value};
22use datatypes::value::{OrderedF32, OrderedF64, Value};
23use snafu::{OptionExt, ResultExt, ensure};
24pub use sqlparser::ast::{
25 BinaryOperator, ColumnDef, ColumnOption, ColumnOptionDef, DataType, Expr, Function,
26 FunctionArg, FunctionArgExpr, FunctionArguments, Ident, ObjectName, SqlOption, TableConstraint,
27 TimezoneInfo, UnaryOperator, Value as SqlValue, Visit, VisitMut, Visitor, VisitorMut,
28 visit_expressions_mut, visit_statements_mut,
29};
30
31use crate::error::{
32 ColumnTypeMismatchSnafu, ConvertSqlValueSnafu, ConvertStrSnafu, DatatypeSnafu,
33 DeserializeSnafu, InvalidCastSnafu, InvalidSqlValueSnafu, InvalidUnaryOpSnafu,
34 ParseSqlValueSnafu, Result, TimestampOverflowSnafu, UnsupportedUnaryOpSnafu,
35};
36
37fn parse_sql_number<R: FromStr + std::fmt::Debug>(n: &str) -> Result<R>
38where
39 <R as FromStr>::Err: std::fmt::Debug,
40{
41 match n.parse::<R>() {
42 Ok(n) => Ok(n),
43 Err(e) => ParseSqlValueSnafu {
44 msg: format!("Fail to parse number {n}, {e:?}"),
45 }
46 .fail(),
47 }
48}
49
50macro_rules! parse_number_to_value {
51 ($data_type: expr, $n: ident, $(($Type: ident, $PrimitiveType: ident, $Target: ident)), +) => {
52 match $data_type {
53 $(
54 ConcreteDataType::$Type(_) => {
55 let n = parse_sql_number::<$PrimitiveType>($n)?;
56 Ok(Value::$Type($Target::from(n)))
57 },
58 )+
59 ConcreteDataType::Timestamp(t) => {
60 let n = parse_sql_number::<i64>($n)?;
61 let timestamp = Timestamp::new(n, t.unit());
62
63 if Timestamp::is_overflow(n, t.unit()) {
65 return TimestampOverflowSnafu {
66 timestamp,
67 target_unit: t.unit(),
68 }.fail();
69 }
70
71 Ok(Value::Timestamp(timestamp))
72 },
73 ConcreteDataType::Decimal128(_) => {
77 if let Ok(val) = common_decimal::Decimal128::from_str($n) {
78 Ok(Value::Decimal128(val))
79 } else {
80 ParseSqlValueSnafu {
81 msg: format!("Fail to parse number {}, invalid column type: {:?}",
82 $n, $data_type)
83 }.fail()
84 }
85 }
86 ConcreteDataType::Boolean(_) => {
88 match $n {
89 "0" => Ok(Value::Boolean(false)),
90 "1" => Ok(Value::Boolean(true)),
91 _ => ParseSqlValueSnafu {
92 msg: format!("Failed to parse number '{}' to boolean column type", $n)}.fail(),
93 }
94 }
95 _ => ParseSqlValueSnafu {
96 msg: format!("Fail to parse number {}, invalid column type: {:?}",
97 $n, $data_type
98 )}.fail(),
99 }
100 }
101}
102
103pub(crate) fn sql_number_to_value(data_type: &ConcreteDataType, n: &str) -> Result<Value> {
105 parse_number_to_value!(
106 data_type,
107 n,
108 (UInt8, u8, u8),
109 (UInt16, u16, u16),
110 (UInt32, u32, u32),
111 (UInt64, u64, u64),
112 (Int8, i8, i8),
113 (Int16, i16, i16),
114 (Int32, i32, i32),
115 (Int64, i64, i64),
116 (Float64, f64, OrderedF64),
117 (Float32, f32, OrderedF32)
118 )
119 }
121
122pub fn sql_value_to_value(
126 column_name: &str,
127 data_type: &ConcreteDataType,
128 sql_val: &SqlValue,
129 timezone: Option<&Timezone>,
130 unary_op: Option<UnaryOperator>,
131 auto_string_to_numeric: bool,
132) -> Result<Value> {
133 let mut value = match sql_val {
134 SqlValue::Number(n, _) => sql_number_to_value(data_type, n)?,
135 SqlValue::Null => Value::Null,
136 SqlValue::Boolean(b) => {
137 ensure!(
138 data_type.is_boolean(),
139 ColumnTypeMismatchSnafu {
140 column_name,
141 expect: data_type.clone(),
142 actual: ConcreteDataType::boolean_datatype(),
143 }
144 );
145
146 (*b).into()
147 }
148 SqlValue::DoubleQuotedString(s) | SqlValue::SingleQuotedString(s) => parse_string_to_value(
149 column_name,
150 s.clone(),
151 data_type,
152 timezone,
153 auto_string_to_numeric,
154 )?,
155 SqlValue::HexStringLiteral(s) => {
156 ensure!(
158 !matches!(data_type, ConcreteDataType::Json(_)),
159 ColumnTypeMismatchSnafu {
160 column_name,
161 expect: ConcreteDataType::binary_datatype(),
162 actual: ConcreteDataType::json_datatype(),
163 }
164 );
165
166 parse_hex_string(s)?
167 }
168 SqlValue::Placeholder(s) => return InvalidSqlValueSnafu { value: s }.fail(),
169
170 _ => {
172 return ConvertSqlValueSnafu {
173 value: sql_val.clone(),
174 datatype: data_type.clone(),
175 }
176 .fail();
177 }
178 };
179
180 if let Some(unary_op) = unary_op {
181 match unary_op {
182 UnaryOperator::Plus | UnaryOperator::Minus | UnaryOperator::Not => {}
183 _ => {
184 return UnsupportedUnaryOpSnafu { unary_op }.fail();
185 }
186 }
187
188 match value {
189 Value::Null => {}
190 Value::Boolean(bool) => match unary_op {
191 UnaryOperator::Not => value = Value::Boolean(!bool),
192 _ => {
193 return InvalidUnaryOpSnafu { unary_op, value }.fail();
194 }
195 },
196 Value::UInt8(_)
197 | Value::UInt16(_)
198 | Value::UInt32(_)
199 | Value::UInt64(_)
200 | Value::Int8(_)
201 | Value::Int16(_)
202 | Value::Int32(_)
203 | Value::Int64(_)
204 | Value::Float32(_)
205 | Value::Float64(_)
206 | Value::Decimal128(_)
207 | Value::Date(_)
208 | Value::Timestamp(_)
209 | Value::Time(_)
210 | Value::Duration(_)
211 | Value::IntervalYearMonth(_)
212 | Value::IntervalDayTime(_)
213 | Value::IntervalMonthDayNano(_) => match unary_op {
214 UnaryOperator::Plus => {}
215 UnaryOperator::Minus => {
216 value = value
217 .try_negative()
218 .with_context(|| InvalidUnaryOpSnafu { unary_op, value })?;
219 }
220 _ => return InvalidUnaryOpSnafu { unary_op, value }.fail(),
221 },
222
223 Value::String(_) | Value::Binary(_) | Value::List(_) => {
224 return InvalidUnaryOpSnafu { unary_op, value }.fail();
225 }
226 }
227 }
228
229 if value.data_type() != *data_type {
230 datatypes::types::cast(value, data_type).with_context(|_| InvalidCastSnafu {
231 sql_value: sql_val.clone(),
232 datatype: data_type,
233 })
234 } else {
235 Ok(value)
236 }
237}
238
239pub(crate) fn parse_string_to_value(
240 column_name: &str,
241 s: String,
242 data_type: &ConcreteDataType,
243 timezone: Option<&Timezone>,
244 auto_string_to_numeric: bool,
245) -> Result<Value> {
246 if auto_string_to_numeric && let Some(value) = auto_cast_to_numeric(&s, data_type)? {
247 return Ok(value);
248 }
249
250 ensure!(
251 data_type.is_stringifiable(),
252 ColumnTypeMismatchSnafu {
253 column_name,
254 expect: data_type.clone(),
255 actual: ConcreteDataType::string_datatype(),
256 }
257 );
258
259 match data_type {
260 ConcreteDataType::String(_) => Ok(Value::String(s.into())),
261 ConcreteDataType::Date(_) => {
262 if let Ok(date) = common_time::date::Date::from_str(&s, timezone) {
263 Ok(Value::Date(date))
264 } else {
265 ParseSqlValueSnafu {
266 msg: format!("Failed to parse {s} to Date value"),
267 }
268 .fail()
269 }
270 }
271 ConcreteDataType::Timestamp(t) => {
272 if let Ok(ts) = Timestamp::from_str(&s, timezone) {
273 Ok(Value::Timestamp(ts.convert_to(t.unit()).context(
274 TimestampOverflowSnafu {
275 timestamp: ts,
276 target_unit: t.unit(),
277 },
278 )?))
279 } else if let Ok(ts) = i64::from_str(s.as_str()) {
280 Ok(Value::Timestamp(Timestamp::new(ts, t.unit())))
281 } else {
282 ParseSqlValueSnafu {
283 msg: format!("Failed to parse {s} to Timestamp value"),
284 }
285 .fail()
286 }
287 }
288 ConcreteDataType::Decimal128(_) => {
289 if let Ok(val) = common_decimal::Decimal128::from_str(&s) {
290 Ok(Value::Decimal128(val))
291 } else {
292 ParseSqlValueSnafu {
293 msg: format!("Fail to parse number {s} to Decimal128 value"),
294 }
295 .fail()
296 }
297 }
298 ConcreteDataType::Binary(_) => Ok(Value::Binary(s.as_bytes().into())),
299 ConcreteDataType::Json(j) => {
300 let v = parse_string_to_json_type_value(&s, &j.format).context(DatatypeSnafu)?;
301 Ok(Value::Binary(v.into()))
302 }
303 ConcreteDataType::Vector(d) => {
304 let v = parse_string_to_vector_type_value(&s, Some(d.dim)).context(DatatypeSnafu)?;
305 Ok(Value::Binary(v.into()))
306 }
307 _ => ParseSqlValueSnafu {
308 msg: format!("Failed to parse {s} to {data_type} value"),
309 }
310 .fail(),
311 }
312}
313
314pub(crate) fn auto_cast_to_numeric(s: &str, data_type: &ConcreteDataType) -> Result<Option<Value>> {
319 let value = match data_type {
320 ConcreteDataType::Boolean(_) => s.parse::<bool>().map(Value::Boolean).ok(),
321 ConcreteDataType::Int8(_) => s.parse::<i8>().map(Value::Int8).ok(),
322 ConcreteDataType::Int16(_) => s.parse::<i16>().map(Value::Int16).ok(),
323 ConcreteDataType::Int32(_) => s.parse::<i32>().map(Value::Int32).ok(),
324 ConcreteDataType::Int64(_) => s.parse::<i64>().map(Value::Int64).ok(),
325 ConcreteDataType::UInt8(_) => s.parse::<u8>().map(Value::UInt8).ok(),
326 ConcreteDataType::UInt16(_) => s.parse::<u16>().map(Value::UInt16).ok(),
327 ConcreteDataType::UInt32(_) => s.parse::<u32>().map(Value::UInt32).ok(),
328 ConcreteDataType::UInt64(_) => s.parse::<u64>().map(Value::UInt64).ok(),
329 ConcreteDataType::Float32(_) => s
330 .parse::<f32>()
331 .map(|v| Value::Float32(OrderedF32::from(v)))
332 .ok(),
333 ConcreteDataType::Float64(_) => s
334 .parse::<f64>()
335 .map(|v| Value::Float64(OrderedF64::from(v)))
336 .ok(),
337 _ => return Ok(None),
338 };
339
340 match value {
341 Some(value) => Ok(Some(value)),
342 None => ConvertStrSnafu {
343 value: s,
344 datatype: data_type.clone(),
345 }
346 .fail(),
347 }
348}
349
350pub(crate) fn parse_hex_string(s: &str) -> Result<Value> {
351 match hex::decode(s) {
352 Ok(b) => Ok(Value::Binary(common_base::bytes::Bytes::from(b))),
353 Err(hex::FromHexError::InvalidHexCharacter { c, index }) => ParseSqlValueSnafu {
354 msg: format!(
355 "Fail to parse hex string to Byte: invalid character {c:?} at position {index}"
356 ),
357 }
358 .fail(),
359 Err(hex::FromHexError::OddLength) => ParseSqlValueSnafu {
360 msg: "Fail to parse hex string to Byte: odd number of digits".to_string(),
361 }
362 .fail(),
363 Err(e) => ParseSqlValueSnafu {
364 msg: format!("Fail to parse hex string to Byte {s}, {e:?}"),
365 }
366 .fail(),
367 }
368}
369
370pub fn deserialize_default_constraint(
372 bytes: &[u8],
373 column_name: &str,
374 data_type: &ConcreteDataType,
375) -> Result<Option<ColumnDefaultConstraint>> {
376 let json = String::from_utf8_lossy(bytes);
377 let default_constraint = serde_json::from_str(&json).context(DeserializeSnafu { json })?;
378 let column_def = sqlparser::ast::ColumnOptionDef {
379 name: None,
380 option: sqlparser::ast::ColumnOption::Default(default_constraint),
381 };
382
383 crate::default_constraint::parse_column_default_constraint(
384 column_name,
385 data_type,
386 &[column_def],
387 None,
388 )
389}
390
391#[cfg(test)]
392mod test {
393 use common_base::bytes::Bytes;
394 use common_time::timestamp::TimeUnit;
395 use datatypes::types::TimestampType;
396 use datatypes::value::OrderedFloat;
397
398 use super::*;
399
400 #[test]
401 fn test_string_to_value_auto_numeric() {
402 let result = parse_string_to_value(
404 "col",
405 "true".to_string(),
406 &ConcreteDataType::boolean_datatype(),
407 None,
408 true,
409 )
410 .unwrap();
411 assert_eq!(Value::Boolean(true), result);
412
413 let result = parse_string_to_value(
415 "col",
416 "not_a_boolean".to_string(),
417 &ConcreteDataType::boolean_datatype(),
418 None,
419 true,
420 );
421 assert!(result.is_err());
422
423 let result = parse_string_to_value(
425 "col",
426 "42".to_string(),
427 &ConcreteDataType::int8_datatype(),
428 None,
429 true,
430 )
431 .unwrap();
432 assert_eq!(Value::Int8(42), result);
433
434 let result = parse_string_to_value(
436 "col",
437 "not_an_int8".to_string(),
438 &ConcreteDataType::int8_datatype(),
439 None,
440 true,
441 );
442 assert!(result.is_err());
443
444 let result = parse_string_to_value(
446 "col",
447 "1000".to_string(),
448 &ConcreteDataType::int16_datatype(),
449 None,
450 true,
451 )
452 .unwrap();
453 assert_eq!(Value::Int16(1000), result);
454
455 let result = parse_string_to_value(
457 "col",
458 "not_an_int16".to_string(),
459 &ConcreteDataType::int16_datatype(),
460 None,
461 true,
462 );
463 assert!(result.is_err());
464
465 let result = parse_string_to_value(
467 "col",
468 "100000".to_string(),
469 &ConcreteDataType::int32_datatype(),
470 None,
471 true,
472 )
473 .unwrap();
474 assert_eq!(Value::Int32(100000), result);
475
476 let result = parse_string_to_value(
478 "col",
479 "not_an_int32".to_string(),
480 &ConcreteDataType::int32_datatype(),
481 None,
482 true,
483 );
484 assert!(result.is_err());
485
486 let result = parse_string_to_value(
488 "col",
489 "1000000".to_string(),
490 &ConcreteDataType::int64_datatype(),
491 None,
492 true,
493 )
494 .unwrap();
495 assert_eq!(Value::Int64(1000000), result);
496
497 let result = parse_string_to_value(
499 "col",
500 "not_an_int64".to_string(),
501 &ConcreteDataType::int64_datatype(),
502 None,
503 true,
504 );
505 assert!(result.is_err());
506
507 let result = parse_string_to_value(
509 "col",
510 "200".to_string(),
511 &ConcreteDataType::uint8_datatype(),
512 None,
513 true,
514 )
515 .unwrap();
516 assert_eq!(Value::UInt8(200), result);
517
518 let result = parse_string_to_value(
520 "col",
521 "not_a_uint8".to_string(),
522 &ConcreteDataType::uint8_datatype(),
523 None,
524 true,
525 );
526 assert!(result.is_err());
527
528 let result = parse_string_to_value(
530 "col",
531 "60000".to_string(),
532 &ConcreteDataType::uint16_datatype(),
533 None,
534 true,
535 )
536 .unwrap();
537 assert_eq!(Value::UInt16(60000), result);
538
539 let result = parse_string_to_value(
541 "col",
542 "not_a_uint16".to_string(),
543 &ConcreteDataType::uint16_datatype(),
544 None,
545 true,
546 );
547 assert!(result.is_err());
548
549 let result = parse_string_to_value(
551 "col",
552 "4000000000".to_string(),
553 &ConcreteDataType::uint32_datatype(),
554 None,
555 true,
556 )
557 .unwrap();
558 assert_eq!(Value::UInt32(4000000000), result);
559
560 let result = parse_string_to_value(
562 "col",
563 "not_a_uint32".to_string(),
564 &ConcreteDataType::uint32_datatype(),
565 None,
566 true,
567 );
568 assert!(result.is_err());
569
570 let result = parse_string_to_value(
572 "col",
573 "18446744073709551615".to_string(),
574 &ConcreteDataType::uint64_datatype(),
575 None,
576 true,
577 )
578 .unwrap();
579 assert_eq!(Value::UInt64(18446744073709551615), result);
580
581 let result = parse_string_to_value(
583 "col",
584 "not_a_uint64".to_string(),
585 &ConcreteDataType::uint64_datatype(),
586 None,
587 true,
588 );
589 assert!(result.is_err());
590
591 let result = parse_string_to_value(
593 "col",
594 "3.5".to_string(),
595 &ConcreteDataType::float32_datatype(),
596 None,
597 true,
598 )
599 .unwrap();
600 assert_eq!(Value::Float32(OrderedF32::from(3.5)), result);
601
602 let result = parse_string_to_value(
604 "col",
605 "not_a_float32".to_string(),
606 &ConcreteDataType::float32_datatype(),
607 None,
608 true,
609 );
610 assert!(result.is_err());
611
612 let result = parse_string_to_value(
614 "col",
615 "3.5".to_string(),
616 &ConcreteDataType::float64_datatype(),
617 None,
618 true,
619 )
620 .unwrap();
621 assert_eq!(Value::Float64(OrderedF64::from(3.5)), result);
622
623 let result = parse_string_to_value(
625 "col",
626 "not_a_float64".to_string(),
627 &ConcreteDataType::float64_datatype(),
628 None,
629 true,
630 );
631 assert!(result.is_err());
632 }
633
634 #[test]
635 fn test_sql_value_to_value() {
636 let sql_val = SqlValue::Null;
637 assert_eq!(
638 Value::Null,
639 sql_value_to_value(
640 "a",
641 &ConcreteDataType::float64_datatype(),
642 &sql_val,
643 None,
644 None,
645 false
646 )
647 .unwrap()
648 );
649
650 let sql_val = SqlValue::Boolean(true);
651 assert_eq!(
652 Value::Boolean(true),
653 sql_value_to_value(
654 "a",
655 &ConcreteDataType::boolean_datatype(),
656 &sql_val,
657 None,
658 None,
659 false
660 )
661 .unwrap()
662 );
663
664 let sql_val = SqlValue::Number("3.0".to_string(), false);
665 assert_eq!(
666 Value::Float64(OrderedFloat(3.0)),
667 sql_value_to_value(
668 "a",
669 &ConcreteDataType::float64_datatype(),
670 &sql_val,
671 None,
672 None,
673 false
674 )
675 .unwrap()
676 );
677
678 let sql_val = SqlValue::Number("3.0".to_string(), false);
679 let v = sql_value_to_value(
680 "a",
681 &ConcreteDataType::boolean_datatype(),
682 &sql_val,
683 None,
684 None,
685 false,
686 );
687 assert!(v.is_err());
688 assert!(format!("{v:?}").contains("Failed to parse number '3.0' to boolean column type"));
689
690 let sql_val = SqlValue::Boolean(true);
691 let v = sql_value_to_value(
692 "a",
693 &ConcreteDataType::float64_datatype(),
694 &sql_val,
695 None,
696 None,
697 false,
698 );
699 assert!(v.is_err());
700 assert!(
701 format!("{v:?}").contains(
702 "Column a expect type: Float64(Float64Type), actual: Boolean(BooleanType)"
703 ),
704 "v is {v:?}",
705 );
706
707 let sql_val = SqlValue::HexStringLiteral("48656c6c6f20776f726c6421".to_string());
708 let v = sql_value_to_value(
709 "a",
710 &ConcreteDataType::binary_datatype(),
711 &sql_val,
712 None,
713 None,
714 false,
715 )
716 .unwrap();
717 assert_eq!(Value::Binary(Bytes::from(b"Hello world!".as_slice())), v);
718
719 let sql_val = SqlValue::DoubleQuotedString("MorningMyFriends".to_string());
720 let v = sql_value_to_value(
721 "a",
722 &ConcreteDataType::binary_datatype(),
723 &sql_val,
724 None,
725 None,
726 false,
727 )
728 .unwrap();
729 assert_eq!(
730 Value::Binary(Bytes::from(b"MorningMyFriends".as_slice())),
731 v
732 );
733
734 let sql_val = SqlValue::HexStringLiteral("9AF".to_string());
735 let v = sql_value_to_value(
736 "a",
737 &ConcreteDataType::binary_datatype(),
738 &sql_val,
739 None,
740 None,
741 false,
742 );
743 assert!(v.is_err());
744 assert!(
745 format!("{v:?}").contains("odd number of digits"),
746 "v is {v:?}"
747 );
748
749 let sql_val = SqlValue::HexStringLiteral("AG".to_string());
750 let v = sql_value_to_value(
751 "a",
752 &ConcreteDataType::binary_datatype(),
753 &sql_val,
754 None,
755 None,
756 false,
757 );
758 assert!(v.is_err());
759 assert!(format!("{v:?}").contains("invalid character"), "v is {v:?}",);
760
761 let sql_val = SqlValue::DoubleQuotedString("MorningMyFriends".to_string());
762 let v = sql_value_to_value(
763 "a",
764 &ConcreteDataType::json_datatype(),
765 &sql_val,
766 None,
767 None,
768 false,
769 );
770 assert!(v.is_err());
771
772 let sql_val = SqlValue::DoubleQuotedString(r#"{"a":"b"}"#.to_string());
773 let v = sql_value_to_value(
774 "a",
775 &ConcreteDataType::json_datatype(),
776 &sql_val,
777 None,
778 None,
779 false,
780 )
781 .unwrap();
782 assert_eq!(
783 Value::Binary(Bytes::from(
784 jsonb::parse_value(r#"{"a":"b"}"#.as_bytes())
785 .unwrap()
786 .to_vec()
787 .as_slice()
788 )),
789 v
790 );
791 }
792
793 #[test]
794 fn test_parse_json_to_jsonb() {
795 match parse_string_to_value(
796 "json_col",
797 r#"{"a": "b"}"#.to_string(),
798 &ConcreteDataType::json_datatype(),
799 None,
800 false,
801 ) {
802 Ok(Value::Binary(b)) => {
803 assert_eq!(
804 b,
805 jsonb::parse_value(r#"{"a": "b"}"#.as_bytes())
806 .unwrap()
807 .to_vec()
808 );
809 }
810 _ => {
811 unreachable!()
812 }
813 }
814
815 assert!(
816 parse_string_to_value(
817 "json_col",
818 r#"Nicola Kovac is the best rifler in the world"#.to_string(),
819 &ConcreteDataType::json_datatype(),
820 None,
821 false,
822 )
823 .is_err()
824 )
825 }
826
827 #[test]
828 fn test_sql_number_to_value() {
829 let v = sql_number_to_value(&ConcreteDataType::float64_datatype(), "3.0").unwrap();
830 assert_eq!(Value::Float64(OrderedFloat(3.0)), v);
831
832 let v = sql_number_to_value(&ConcreteDataType::int32_datatype(), "999").unwrap();
833 assert_eq!(Value::Int32(999), v);
834
835 let v = sql_number_to_value(
836 &ConcreteDataType::timestamp_nanosecond_datatype(),
837 "1073741821",
838 )
839 .unwrap();
840 assert_eq!(Value::Timestamp(Timestamp::new_nanosecond(1073741821)), v);
841
842 let v = sql_number_to_value(
843 &ConcreteDataType::timestamp_millisecond_datatype(),
844 "999999",
845 )
846 .unwrap();
847 assert_eq!(Value::Timestamp(Timestamp::new_millisecond(999999)), v);
848
849 let v = sql_number_to_value(&ConcreteDataType::string_datatype(), "999");
850 assert!(v.is_err(), "parse value error is: {v:?}");
851
852 let v = sql_number_to_value(&ConcreteDataType::boolean_datatype(), "0").unwrap();
853 assert_eq!(v, Value::Boolean(false));
854 let v = sql_number_to_value(&ConcreteDataType::boolean_datatype(), "1").unwrap();
855 assert_eq!(v, Value::Boolean(true));
856 assert!(sql_number_to_value(&ConcreteDataType::boolean_datatype(), "2").is_err());
857 }
858
859 #[test]
860 fn test_parse_date_literal() {
861 let value = sql_value_to_value(
862 "date",
863 &ConcreteDataType::date_datatype(),
864 &SqlValue::DoubleQuotedString("2022-02-22".to_string()),
865 None,
866 None,
867 false,
868 )
869 .unwrap();
870 assert_eq!(ConcreteDataType::date_datatype(), value.data_type());
871 if let Value::Date(d) = value {
872 assert_eq!("2022-02-22", d.to_string());
873 } else {
874 unreachable!()
875 }
876
877 let value = sql_value_to_value(
879 "date",
880 &ConcreteDataType::date_datatype(),
881 &SqlValue::DoubleQuotedString("2022-02-22".to_string()),
882 Some(&Timezone::from_tz_string("+07:00").unwrap()),
883 None,
884 false,
885 )
886 .unwrap();
887 assert_eq!(ConcreteDataType::date_datatype(), value.data_type());
888 if let Value::Date(d) = value {
889 assert_eq!("2022-02-21", d.to_string());
890 } else {
891 unreachable!()
892 }
893 }
894
895 #[test]
896 fn test_parse_timestamp_literal() {
897 match parse_string_to_value(
898 "timestamp_col",
899 "2022-02-22T00:01:01+08:00".to_string(),
900 &ConcreteDataType::timestamp_millisecond_datatype(),
901 None,
902 false,
903 )
904 .unwrap()
905 {
906 Value::Timestamp(ts) => {
907 assert_eq!(1645459261000, ts.value());
908 assert_eq!(TimeUnit::Millisecond, ts.unit());
909 }
910 _ => {
911 unreachable!()
912 }
913 }
914
915 match parse_string_to_value(
916 "timestamp_col",
917 "2022-02-22T00:01:01+08:00".to_string(),
918 &ConcreteDataType::timestamp_datatype(TimeUnit::Second),
919 None,
920 false,
921 )
922 .unwrap()
923 {
924 Value::Timestamp(ts) => {
925 assert_eq!(1645459261, ts.value());
926 assert_eq!(TimeUnit::Second, ts.unit());
927 }
928 _ => {
929 unreachable!()
930 }
931 }
932
933 match parse_string_to_value(
934 "timestamp_col",
935 "2022-02-22T00:01:01+08:00".to_string(),
936 &ConcreteDataType::timestamp_datatype(TimeUnit::Microsecond),
937 None,
938 false,
939 )
940 .unwrap()
941 {
942 Value::Timestamp(ts) => {
943 assert_eq!(1645459261000000, ts.value());
944 assert_eq!(TimeUnit::Microsecond, ts.unit());
945 }
946 _ => {
947 unreachable!()
948 }
949 }
950
951 match parse_string_to_value(
952 "timestamp_col",
953 "2022-02-22T00:01:01+08:00".to_string(),
954 &ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond),
955 None,
956 false,
957 )
958 .unwrap()
959 {
960 Value::Timestamp(ts) => {
961 assert_eq!(1645459261000000000, ts.value());
962 assert_eq!(TimeUnit::Nanosecond, ts.unit());
963 }
964 _ => {
965 unreachable!()
966 }
967 }
968
969 assert!(
970 parse_string_to_value(
971 "timestamp_col",
972 "2022-02-22T00:01:01+08".to_string(),
973 &ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond),
974 None,
975 false,
976 )
977 .is_err()
978 );
979
980 match parse_string_to_value(
982 "timestamp_col",
983 "2022-02-22T00:01:01".to_string(),
984 &ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond),
985 Some(&Timezone::from_tz_string("Asia/Shanghai").unwrap()),
986 false,
987 )
988 .unwrap()
989 {
990 Value::Timestamp(ts) => {
991 assert_eq!(1645459261000000000, ts.value());
992 assert_eq!("2022-02-21 16:01:01+0000", ts.to_iso8601_string());
993 assert_eq!(TimeUnit::Nanosecond, ts.unit());
994 }
995 _ => {
996 unreachable!()
997 }
998 }
999 }
1000
1001 #[test]
1002 fn test_parse_placeholder_value() {
1003 assert!(
1004 sql_value_to_value(
1005 "test",
1006 &ConcreteDataType::string_datatype(),
1007 &SqlValue::Placeholder("default".into()),
1008 None,
1009 None,
1010 false
1011 )
1012 .is_err()
1013 );
1014 assert!(
1015 sql_value_to_value(
1016 "test",
1017 &ConcreteDataType::string_datatype(),
1018 &SqlValue::Placeholder("default".into()),
1019 None,
1020 Some(UnaryOperator::Minus),
1021 false
1022 )
1023 .is_err()
1024 );
1025 assert!(
1026 sql_value_to_value(
1027 "test",
1028 &ConcreteDataType::uint16_datatype(),
1029 &SqlValue::Number("3".into(), false),
1030 None,
1031 Some(UnaryOperator::Minus),
1032 false
1033 )
1034 .is_err()
1035 );
1036 assert!(
1037 sql_value_to_value(
1038 "test",
1039 &ConcreteDataType::uint16_datatype(),
1040 &SqlValue::Number("3".into(), false),
1041 None,
1042 None,
1043 false
1044 )
1045 .is_ok()
1046 );
1047 }
1048
1049 #[test]
1050 fn test_auto_string_to_numeric() {
1051 let sql_val = SqlValue::SingleQuotedString("123".to_string());
1053 let v = sql_value_to_value(
1054 "a",
1055 &ConcreteDataType::int32_datatype(),
1056 &sql_val,
1057 None,
1058 None,
1059 true,
1060 )
1061 .unwrap();
1062 assert_eq!(Value::Int32(123), v);
1063
1064 let sql_val = SqlValue::SingleQuotedString("3.5".to_string());
1066 let v = sql_value_to_value(
1067 "a",
1068 &ConcreteDataType::float64_datatype(),
1069 &sql_val,
1070 None,
1071 None,
1072 true,
1073 )
1074 .unwrap();
1075 assert_eq!(Value::Float64(OrderedFloat(3.5)), v);
1076
1077 let sql_val = SqlValue::SingleQuotedString("123".to_string());
1079 let v = sql_value_to_value(
1080 "a",
1081 &ConcreteDataType::int32_datatype(),
1082 &sql_val,
1083 None,
1084 None,
1085 false,
1086 );
1087 assert!(v.is_err());
1088
1089 let sql_val = SqlValue::SingleQuotedString("not_a_number".to_string());
1092 let v = sql_value_to_value(
1093 "a",
1094 &ConcreteDataType::int32_datatype(),
1095 &sql_val,
1096 None,
1097 None,
1098 true,
1099 );
1100 assert!(v.is_err());
1101
1102 let sql_val = SqlValue::SingleQuotedString("true".to_string());
1104 let v = sql_value_to_value(
1105 "a",
1106 &ConcreteDataType::boolean_datatype(),
1107 &sql_val,
1108 None,
1109 None,
1110 true,
1111 )
1112 .unwrap();
1113 assert_eq!(Value::Boolean(true), v);
1114
1115 let sql_val = SqlValue::SingleQuotedString("hello".to_string());
1117 let v = sql_value_to_value(
1118 "a",
1119 &ConcreteDataType::string_datatype(),
1120 &sql_val,
1121 None,
1122 None,
1123 true,
1124 );
1125 assert!(v.is_ok());
1126 }
1127
1128 #[test]
1129 fn test_sql_number_to_value_timestamp_strict_typing() {
1130 let timestamp_type = TimestampType::Millisecond(datatypes::types::TimestampMillisecondType);
1132 let data_type = ConcreteDataType::Timestamp(timestamp_type);
1133
1134 let millisecond_str = "1747814093865";
1136 let result = sql_number_to_value(&data_type, millisecond_str).unwrap();
1137 if let Value::Timestamp(ts) = result {
1138 assert_eq!(ts.unit(), TimeUnit::Millisecond);
1139 assert_eq!(ts.value(), 1747814093865);
1140 } else {
1141 panic!("Expected timestamp value");
1142 }
1143
1144 let nanosecond_str = "1747814093865000000"; let result = sql_number_to_value(&data_type, nanosecond_str);
1147 assert!(
1148 result.is_err(),
1149 "Should reject overly large timestamp values"
1150 );
1151 }
1152
1153 #[test]
1154 fn test_sql_number_to_value_timestamp_different_units() {
1155 let second_type = TimestampType::Second(datatypes::types::TimestampSecondType);
1157 let second_data_type = ConcreteDataType::Timestamp(second_type);
1158
1159 let second_str = "1747814093";
1160 let result = sql_number_to_value(&second_data_type, second_str).unwrap();
1161 if let Value::Timestamp(ts) = result {
1162 assert_eq!(ts.unit(), TimeUnit::Second);
1163 assert_eq!(ts.value(), 1747814093);
1164 } else {
1165 panic!("Expected timestamp value");
1166 }
1167
1168 let nanosecond_type = TimestampType::Nanosecond(datatypes::types::TimestampNanosecondType);
1170 let nanosecond_data_type = ConcreteDataType::Timestamp(nanosecond_type);
1171
1172 let nanosecond_str = "1747814093865000000";
1173 let result = sql_number_to_value(&nanosecond_data_type, nanosecond_str).unwrap();
1174 if let Value::Timestamp(ts) = result {
1175 assert_eq!(ts.unit(), TimeUnit::Nanosecond);
1176 assert_eq!(ts.value(), 1747814093865000000);
1177 } else {
1178 panic!("Expected timestamp value");
1179 }
1180 }
1181
1182 #[test]
1183 fn test_timestamp_range_validation() {
1184 let nanosecond_value = 1747814093865000000i64; let nanosecond_type = TimestampType::Nanosecond(datatypes::types::TimestampNanosecondType);
1189 let nanosecond_data_type = ConcreteDataType::Timestamp(nanosecond_type);
1190 let result = sql_number_to_value(&nanosecond_data_type, "1747814093865000000");
1191 assert!(
1192 result.is_ok(),
1193 "Nanosecond value should be valid for nanosecond column"
1194 );
1195
1196 let millisecond_type =
1198 TimestampType::Millisecond(datatypes::types::TimestampMillisecondType);
1199 let millisecond_data_type = ConcreteDataType::Timestamp(millisecond_type);
1200 let result = sql_number_to_value(&millisecond_data_type, "1747814093865000000");
1201 assert!(
1202 result.is_err(),
1203 "Nanosecond value should be rejected for millisecond column"
1204 );
1205
1206 assert!(
1208 nanosecond_value > Timestamp::MAX_MILLISECOND.value(),
1209 "Test value should exceed millisecond range"
1210 );
1211 }
1212}