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