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 if value.data_type() != *data_type {
235 datatypes::types::cast(value, data_type).with_context(|_| InvalidCastSnafu {
236 sql_value: sql_val.clone(),
237 datatype: data_type,
238 })
239 } else {
240 Ok(value)
241 }
242}
243
244pub(crate) fn parse_string_to_value(
245 column_name: &str,
246 s: String,
247 data_type: &ConcreteDataType,
248 timezone: Option<&Timezone>,
249 auto_string_to_numeric: bool,
250) -> Result<Value> {
251 if auto_string_to_numeric && let Some(value) = auto_cast_to_numeric(&s, data_type)? {
252 return Ok(value);
253 }
254
255 ensure!(
256 data_type.is_stringifiable(),
257 ColumnTypeMismatchSnafu {
258 column_name,
259 expect: data_type.clone(),
260 actual: ConcreteDataType::string_datatype(),
261 }
262 );
263
264 match data_type {
265 ConcreteDataType::String(_) => Ok(Value::String(s.into())),
266 ConcreteDataType::Date(_) => {
267 if let Ok(date) = common_time::date::Date::from_str(&s, timezone) {
268 Ok(Value::Date(date))
269 } else {
270 ParseSqlValueSnafu {
271 msg: format!("Failed to parse {s} to Date value"),
272 }
273 .fail()
274 }
275 }
276 ConcreteDataType::Timestamp(t) => {
277 if let Ok(ts) = Timestamp::from_str(&s, timezone) {
278 Ok(Value::Timestamp(ts.convert_to(t.unit()).context(
279 TimestampOverflowSnafu {
280 timestamp: ts,
281 target_unit: t.unit(),
282 },
283 )?))
284 } else if let Ok(ts) = i64::from_str(s.as_str()) {
285 Ok(Value::Timestamp(Timestamp::new(ts, t.unit())))
286 } else {
287 ParseSqlValueSnafu {
288 msg: format!("Failed to parse {s} to Timestamp value"),
289 }
290 .fail()
291 }
292 }
293 ConcreteDataType::Decimal128(_) => {
294 if let Ok(val) = common_decimal::Decimal128::from_str(&s) {
295 Ok(Value::Decimal128(val))
296 } else {
297 ParseSqlValueSnafu {
298 msg: format!("Fail to parse number {s} to Decimal128 value"),
299 }
300 .fail()
301 }
302 }
303 ConcreteDataType::Binary(_) => Ok(Value::Binary(s.as_bytes().into())),
304 ConcreteDataType::Json(j) => {
305 match &j.format {
306 JsonFormat::Jsonb => {
307 let v = parse_string_to_jsonb(&s).context(DatatypeSnafu)?;
308 Ok(Value::Binary(v.into()))
309 }
310 JsonFormat::Native(_inner) => {
311 let serde_json_value =
313 serde_json::from_str(&s).context(DeserializeSnafu { json: s })?;
314 let json_structure_settings = JsonStructureSettings::Structured(None);
315 json_structure_settings
316 .encode(serde_json_value)
317 .context(DatatypeSnafu)
318 }
319 }
320 }
321 ConcreteDataType::Vector(d) => {
322 let v = parse_string_to_vector_type_value(&s, Some(d.dim)).context(DatatypeSnafu)?;
323 Ok(Value::Binary(v.into()))
324 }
325 _ => ParseSqlValueSnafu {
326 msg: format!("Failed to parse {s} to {data_type} value"),
327 }
328 .fail(),
329 }
330}
331
332pub(crate) fn auto_cast_to_numeric(s: &str, data_type: &ConcreteDataType) -> Result<Option<Value>> {
337 let value = match data_type {
338 ConcreteDataType::Boolean(_) => s.parse::<bool>().map(Value::Boolean).ok(),
339 ConcreteDataType::Int8(_) => s.parse::<i8>().map(Value::Int8).ok(),
340 ConcreteDataType::Int16(_) => s.parse::<i16>().map(Value::Int16).ok(),
341 ConcreteDataType::Int32(_) => s.parse::<i32>().map(Value::Int32).ok(),
342 ConcreteDataType::Int64(_) => s.parse::<i64>().map(Value::Int64).ok(),
343 ConcreteDataType::UInt8(_) => s.parse::<u8>().map(Value::UInt8).ok(),
344 ConcreteDataType::UInt16(_) => s.parse::<u16>().map(Value::UInt16).ok(),
345 ConcreteDataType::UInt32(_) => s.parse::<u32>().map(Value::UInt32).ok(),
346 ConcreteDataType::UInt64(_) => s.parse::<u64>().map(Value::UInt64).ok(),
347 ConcreteDataType::Float32(_) => s
348 .parse::<f32>()
349 .map(|v| Value::Float32(OrderedF32::from(v)))
350 .ok(),
351 ConcreteDataType::Float64(_) => s
352 .parse::<f64>()
353 .map(|v| Value::Float64(OrderedF64::from(v)))
354 .ok(),
355 _ => return Ok(None),
356 };
357
358 match value {
359 Some(value) => Ok(Some(value)),
360 None => ConvertStrSnafu {
361 value: s,
362 datatype: data_type.clone(),
363 }
364 .fail(),
365 }
366}
367
368pub(crate) fn parse_hex_string(s: &str) -> Result<Value> {
369 match hex::decode(s) {
370 Ok(b) => Ok(Value::Binary(common_base::bytes::Bytes::from(b))),
371 Err(hex::FromHexError::InvalidHexCharacter { c, index }) => ParseSqlValueSnafu {
372 msg: format!(
373 "Fail to parse hex string to Byte: invalid character {c:?} at position {index}"
374 ),
375 }
376 .fail(),
377 Err(hex::FromHexError::OddLength) => ParseSqlValueSnafu {
378 msg: "Fail to parse hex string to Byte: odd number of digits".to_string(),
379 }
380 .fail(),
381 Err(e) => ParseSqlValueSnafu {
382 msg: format!("Fail to parse hex string to Byte {s}, {e:?}"),
383 }
384 .fail(),
385 }
386}
387
388pub fn deserialize_default_constraint(
390 bytes: &[u8],
391 column_name: &str,
392 data_type: &ConcreteDataType,
393) -> Result<Option<ColumnDefaultConstraint>> {
394 let json = String::from_utf8_lossy(bytes);
395 let default_constraint = serde_json::from_str(&json).context(DeserializeSnafu { json })?;
396 let column_def = sqlparser::ast::ColumnOptionDef {
397 name: None,
398 option: sqlparser::ast::ColumnOption::Default(default_constraint),
399 };
400
401 crate::default_constraint::parse_column_default_constraint(
402 column_name,
403 data_type,
404 &[column_def],
405 None,
406 )
407}
408
409#[cfg(test)]
410mod test {
411 use common_base::bytes::Bytes;
412 use common_time::timestamp::TimeUnit;
413 use datatypes::types::TimestampType;
414 use datatypes::value::OrderedFloat;
415
416 use super::*;
417
418 #[test]
419 fn test_string_to_value_auto_numeric() {
420 let result = parse_string_to_value(
422 "col",
423 "true".to_string(),
424 &ConcreteDataType::boolean_datatype(),
425 None,
426 true,
427 )
428 .unwrap();
429 assert_eq!(Value::Boolean(true), result);
430
431 let result = parse_string_to_value(
433 "col",
434 "not_a_boolean".to_string(),
435 &ConcreteDataType::boolean_datatype(),
436 None,
437 true,
438 );
439 assert!(result.is_err());
440
441 let result = parse_string_to_value(
443 "col",
444 "42".to_string(),
445 &ConcreteDataType::int8_datatype(),
446 None,
447 true,
448 )
449 .unwrap();
450 assert_eq!(Value::Int8(42), result);
451
452 let result = parse_string_to_value(
454 "col",
455 "not_an_int8".to_string(),
456 &ConcreteDataType::int8_datatype(),
457 None,
458 true,
459 );
460 assert!(result.is_err());
461
462 let result = parse_string_to_value(
464 "col",
465 "1000".to_string(),
466 &ConcreteDataType::int16_datatype(),
467 None,
468 true,
469 )
470 .unwrap();
471 assert_eq!(Value::Int16(1000), result);
472
473 let result = parse_string_to_value(
475 "col",
476 "not_an_int16".to_string(),
477 &ConcreteDataType::int16_datatype(),
478 None,
479 true,
480 );
481 assert!(result.is_err());
482
483 let result = parse_string_to_value(
485 "col",
486 "100000".to_string(),
487 &ConcreteDataType::int32_datatype(),
488 None,
489 true,
490 )
491 .unwrap();
492 assert_eq!(Value::Int32(100000), result);
493
494 let result = parse_string_to_value(
496 "col",
497 "not_an_int32".to_string(),
498 &ConcreteDataType::int32_datatype(),
499 None,
500 true,
501 );
502 assert!(result.is_err());
503
504 let result = parse_string_to_value(
506 "col",
507 "1000000".to_string(),
508 &ConcreteDataType::int64_datatype(),
509 None,
510 true,
511 )
512 .unwrap();
513 assert_eq!(Value::Int64(1000000), result);
514
515 let result = parse_string_to_value(
517 "col",
518 "not_an_int64".to_string(),
519 &ConcreteDataType::int64_datatype(),
520 None,
521 true,
522 );
523 assert!(result.is_err());
524
525 let result = parse_string_to_value(
527 "col",
528 "200".to_string(),
529 &ConcreteDataType::uint8_datatype(),
530 None,
531 true,
532 )
533 .unwrap();
534 assert_eq!(Value::UInt8(200), result);
535
536 let result = parse_string_to_value(
538 "col",
539 "not_a_uint8".to_string(),
540 &ConcreteDataType::uint8_datatype(),
541 None,
542 true,
543 );
544 assert!(result.is_err());
545
546 let result = parse_string_to_value(
548 "col",
549 "60000".to_string(),
550 &ConcreteDataType::uint16_datatype(),
551 None,
552 true,
553 )
554 .unwrap();
555 assert_eq!(Value::UInt16(60000), result);
556
557 let result = parse_string_to_value(
559 "col",
560 "not_a_uint16".to_string(),
561 &ConcreteDataType::uint16_datatype(),
562 None,
563 true,
564 );
565 assert!(result.is_err());
566
567 let result = parse_string_to_value(
569 "col",
570 "4000000000".to_string(),
571 &ConcreteDataType::uint32_datatype(),
572 None,
573 true,
574 )
575 .unwrap();
576 assert_eq!(Value::UInt32(4000000000), result);
577
578 let result = parse_string_to_value(
580 "col",
581 "not_a_uint32".to_string(),
582 &ConcreteDataType::uint32_datatype(),
583 None,
584 true,
585 );
586 assert!(result.is_err());
587
588 let result = parse_string_to_value(
590 "col",
591 "18446744073709551615".to_string(),
592 &ConcreteDataType::uint64_datatype(),
593 None,
594 true,
595 )
596 .unwrap();
597 assert_eq!(Value::UInt64(18446744073709551615), result);
598
599 let result = parse_string_to_value(
601 "col",
602 "not_a_uint64".to_string(),
603 &ConcreteDataType::uint64_datatype(),
604 None,
605 true,
606 );
607 assert!(result.is_err());
608
609 let result = parse_string_to_value(
611 "col",
612 "3.5".to_string(),
613 &ConcreteDataType::float32_datatype(),
614 None,
615 true,
616 )
617 .unwrap();
618 assert_eq!(Value::Float32(OrderedF32::from(3.5)), result);
619
620 let result = parse_string_to_value(
622 "col",
623 "not_a_float32".to_string(),
624 &ConcreteDataType::float32_datatype(),
625 None,
626 true,
627 );
628 assert!(result.is_err());
629
630 let result = parse_string_to_value(
632 "col",
633 "3.5".to_string(),
634 &ConcreteDataType::float64_datatype(),
635 None,
636 true,
637 )
638 .unwrap();
639 assert_eq!(Value::Float64(OrderedF64::from(3.5)), result);
640
641 let result = parse_string_to_value(
643 "col",
644 "not_a_float64".to_string(),
645 &ConcreteDataType::float64_datatype(),
646 None,
647 true,
648 );
649 assert!(result.is_err());
650 }
651
652 #[test]
653 fn test_sql_value_to_value() {
654 let sql_val = SqlValue::Null;
655 assert_eq!(
656 Value::Null,
657 sql_value_to_value(
658 "a",
659 &ConcreteDataType::float64_datatype(),
660 &sql_val,
661 None,
662 None,
663 false
664 )
665 .unwrap()
666 );
667
668 let sql_val = SqlValue::Boolean(true);
669 assert_eq!(
670 Value::Boolean(true),
671 sql_value_to_value(
672 "a",
673 &ConcreteDataType::boolean_datatype(),
674 &sql_val,
675 None,
676 None,
677 false
678 )
679 .unwrap()
680 );
681
682 let sql_val = SqlValue::Number("3.0".to_string(), false);
683 assert_eq!(
684 Value::Float64(OrderedFloat(3.0)),
685 sql_value_to_value(
686 "a",
687 &ConcreteDataType::float64_datatype(),
688 &sql_val,
689 None,
690 None,
691 false
692 )
693 .unwrap()
694 );
695
696 let sql_val = SqlValue::Number("3.0".to_string(), false);
697 let v = sql_value_to_value(
698 "a",
699 &ConcreteDataType::boolean_datatype(),
700 &sql_val,
701 None,
702 None,
703 false,
704 );
705 assert!(v.is_err());
706 assert!(format!("{v:?}").contains("Failed to parse number '3.0' to boolean column type"));
707
708 let sql_val = SqlValue::Boolean(true);
709 let v = sql_value_to_value(
710 "a",
711 &ConcreteDataType::float64_datatype(),
712 &sql_val,
713 None,
714 None,
715 false,
716 );
717 assert!(v.is_err());
718 assert!(
719 format!("{v:?}").contains(
720 "Column a expect type: Float64(Float64Type), actual: Boolean(BooleanType)"
721 ),
722 "v is {v:?}",
723 );
724
725 let sql_val = SqlValue::HexStringLiteral("48656c6c6f20776f726c6421".to_string());
726 let v = sql_value_to_value(
727 "a",
728 &ConcreteDataType::binary_datatype(),
729 &sql_val,
730 None,
731 None,
732 false,
733 )
734 .unwrap();
735 assert_eq!(Value::Binary(Bytes::from(b"Hello world!".as_slice())), v);
736
737 let sql_val = SqlValue::DoubleQuotedString("MorningMyFriends".to_string());
738 let v = sql_value_to_value(
739 "a",
740 &ConcreteDataType::binary_datatype(),
741 &sql_val,
742 None,
743 None,
744 false,
745 )
746 .unwrap();
747 assert_eq!(
748 Value::Binary(Bytes::from(b"MorningMyFriends".as_slice())),
749 v
750 );
751
752 let sql_val = SqlValue::HexStringLiteral("9AF".to_string());
753 let v = sql_value_to_value(
754 "a",
755 &ConcreteDataType::binary_datatype(),
756 &sql_val,
757 None,
758 None,
759 false,
760 );
761 assert!(v.is_err());
762 assert!(
763 format!("{v:?}").contains("odd number of digits"),
764 "v is {v:?}"
765 );
766
767 let sql_val = SqlValue::HexStringLiteral("AG".to_string());
768 let v = sql_value_to_value(
769 "a",
770 &ConcreteDataType::binary_datatype(),
771 &sql_val,
772 None,
773 None,
774 false,
775 );
776 assert!(v.is_err());
777 assert!(format!("{v:?}").contains("invalid character"), "v is {v:?}",);
778
779 let sql_val = SqlValue::DoubleQuotedString("MorningMyFriends".to_string());
780 let v = sql_value_to_value(
781 "a",
782 &ConcreteDataType::json_datatype(),
783 &sql_val,
784 None,
785 None,
786 false,
787 );
788 assert!(v.is_err());
789
790 let sql_val = SqlValue::DoubleQuotedString(r#"{"a":"b"}"#.to_string());
791 let v = sql_value_to_value(
792 "a",
793 &ConcreteDataType::json_datatype(),
794 &sql_val,
795 None,
796 None,
797 false,
798 )
799 .unwrap();
800 assert_eq!(
801 Value::Binary(Bytes::from(
802 jsonb::parse_value(r#"{"a":"b"}"#.as_bytes())
803 .unwrap()
804 .to_vec()
805 .as_slice()
806 )),
807 v
808 );
809 }
810
811 #[test]
812 fn test_parse_json_to_jsonb() {
813 match parse_string_to_value(
814 "json_col",
815 r#"{"a": "b"}"#.to_string(),
816 &ConcreteDataType::json_datatype(),
817 None,
818 false,
819 ) {
820 Ok(Value::Binary(b)) => {
821 assert_eq!(
822 b,
823 jsonb::parse_value(r#"{"a": "b"}"#.as_bytes())
824 .unwrap()
825 .to_vec()
826 );
827 }
828 _ => {
829 unreachable!()
830 }
831 }
832
833 assert!(
834 parse_string_to_value(
835 "json_col",
836 r#"Nicola Kovac is the best rifler in the world"#.to_string(),
837 &ConcreteDataType::json_datatype(),
838 None,
839 false,
840 )
841 .is_err()
842 )
843 }
844
845 #[test]
846 fn test_sql_number_to_value() {
847 let v = sql_number_to_value(&ConcreteDataType::float64_datatype(), "3.0").unwrap();
848 assert_eq!(Value::Float64(OrderedFloat(3.0)), v);
849
850 let v = sql_number_to_value(&ConcreteDataType::int32_datatype(), "999").unwrap();
851 assert_eq!(Value::Int32(999), v);
852
853 let v = sql_number_to_value(
854 &ConcreteDataType::timestamp_nanosecond_datatype(),
855 "1073741821",
856 )
857 .unwrap();
858 assert_eq!(Value::Timestamp(Timestamp::new_nanosecond(1073741821)), v);
859
860 let v = sql_number_to_value(
861 &ConcreteDataType::timestamp_millisecond_datatype(),
862 "999999",
863 )
864 .unwrap();
865 assert_eq!(Value::Timestamp(Timestamp::new_millisecond(999999)), v);
866
867 let v = sql_number_to_value(&ConcreteDataType::string_datatype(), "999");
868 assert!(v.is_err(), "parse value error is: {v:?}");
869
870 let v = sql_number_to_value(&ConcreteDataType::boolean_datatype(), "0").unwrap();
871 assert_eq!(v, Value::Boolean(false));
872 let v = sql_number_to_value(&ConcreteDataType::boolean_datatype(), "1").unwrap();
873 assert_eq!(v, Value::Boolean(true));
874 assert!(sql_number_to_value(&ConcreteDataType::boolean_datatype(), "2").is_err());
875 }
876
877 #[test]
878 fn test_parse_date_literal() {
879 let value = sql_value_to_value(
880 "date",
881 &ConcreteDataType::date_datatype(),
882 &SqlValue::DoubleQuotedString("2022-02-22".to_string()),
883 None,
884 None,
885 false,
886 )
887 .unwrap();
888 assert_eq!(ConcreteDataType::date_datatype(), value.data_type());
889 if let Value::Date(d) = value {
890 assert_eq!("2022-02-22", d.to_string());
891 } else {
892 unreachable!()
893 }
894
895 let value = sql_value_to_value(
897 "date",
898 &ConcreteDataType::date_datatype(),
899 &SqlValue::DoubleQuotedString("2022-02-22".to_string()),
900 Some(&Timezone::from_tz_string("+07:00").unwrap()),
901 None,
902 false,
903 )
904 .unwrap();
905 assert_eq!(ConcreteDataType::date_datatype(), value.data_type());
906 if let Value::Date(d) = value {
907 assert_eq!("2022-02-21", d.to_string());
908 } else {
909 unreachable!()
910 }
911 }
912
913 #[test]
914 fn test_parse_timestamp_literal() {
915 match parse_string_to_value(
916 "timestamp_col",
917 "2022-02-22T00:01:01+08:00".to_string(),
918 &ConcreteDataType::timestamp_millisecond_datatype(),
919 None,
920 false,
921 )
922 .unwrap()
923 {
924 Value::Timestamp(ts) => {
925 assert_eq!(1645459261000, ts.value());
926 assert_eq!(TimeUnit::Millisecond, 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::Second),
937 None,
938 false,
939 )
940 .unwrap()
941 {
942 Value::Timestamp(ts) => {
943 assert_eq!(1645459261, ts.value());
944 assert_eq!(TimeUnit::Second, 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::Microsecond),
955 None,
956 false,
957 )
958 .unwrap()
959 {
960 Value::Timestamp(ts) => {
961 assert_eq!(1645459261000000, ts.value());
962 assert_eq!(TimeUnit::Microsecond, ts.unit());
963 }
964 _ => {
965 unreachable!()
966 }
967 }
968
969 match parse_string_to_value(
970 "timestamp_col",
971 "2022-02-22T00:01:01+08:00".to_string(),
972 &ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond),
973 None,
974 false,
975 )
976 .unwrap()
977 {
978 Value::Timestamp(ts) => {
979 assert_eq!(1645459261000000000, ts.value());
980 assert_eq!(TimeUnit::Nanosecond, ts.unit());
981 }
982 _ => {
983 unreachable!()
984 }
985 }
986
987 assert!(
988 parse_string_to_value(
989 "timestamp_col",
990 "2022-02-22T00:01:01+08".to_string(),
991 &ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond),
992 None,
993 false,
994 )
995 .is_err()
996 );
997
998 match parse_string_to_value(
1000 "timestamp_col",
1001 "2022-02-22T00:01:01".to_string(),
1002 &ConcreteDataType::timestamp_datatype(TimeUnit::Nanosecond),
1003 Some(&Timezone::from_tz_string("Asia/Shanghai").unwrap()),
1004 false,
1005 )
1006 .unwrap()
1007 {
1008 Value::Timestamp(ts) => {
1009 assert_eq!(1645459261000000000, ts.value());
1010 assert_eq!("2022-02-21 16:01:01+0000", ts.to_iso8601_string());
1011 assert_eq!(TimeUnit::Nanosecond, ts.unit());
1012 }
1013 _ => {
1014 unreachable!()
1015 }
1016 }
1017 }
1018
1019 #[test]
1020 fn test_parse_placeholder_value() {
1021 assert!(
1022 sql_value_to_value(
1023 "test",
1024 &ConcreteDataType::string_datatype(),
1025 &SqlValue::Placeholder("default".into()),
1026 None,
1027 None,
1028 false
1029 )
1030 .is_err()
1031 );
1032 assert!(
1033 sql_value_to_value(
1034 "test",
1035 &ConcreteDataType::string_datatype(),
1036 &SqlValue::Placeholder("default".into()),
1037 None,
1038 Some(UnaryOperator::Minus),
1039 false
1040 )
1041 .is_err()
1042 );
1043 assert!(
1044 sql_value_to_value(
1045 "test",
1046 &ConcreteDataType::uint16_datatype(),
1047 &SqlValue::Number("3".into(), false),
1048 None,
1049 Some(UnaryOperator::Minus),
1050 false
1051 )
1052 .is_err()
1053 );
1054 assert!(
1055 sql_value_to_value(
1056 "test",
1057 &ConcreteDataType::uint16_datatype(),
1058 &SqlValue::Number("3".into(), false),
1059 None,
1060 None,
1061 false
1062 )
1063 .is_ok()
1064 );
1065 }
1066
1067 #[test]
1068 fn test_auto_string_to_numeric() {
1069 let sql_val = SqlValue::SingleQuotedString("123".to_string());
1071 let v = sql_value_to_value(
1072 "a",
1073 &ConcreteDataType::int32_datatype(),
1074 &sql_val,
1075 None,
1076 None,
1077 true,
1078 )
1079 .unwrap();
1080 assert_eq!(Value::Int32(123), v);
1081
1082 let sql_val = SqlValue::SingleQuotedString("3.5".to_string());
1084 let v = sql_value_to_value(
1085 "a",
1086 &ConcreteDataType::float64_datatype(),
1087 &sql_val,
1088 None,
1089 None,
1090 true,
1091 )
1092 .unwrap();
1093 assert_eq!(Value::Float64(OrderedFloat(3.5)), v);
1094
1095 let sql_val = SqlValue::SingleQuotedString("123".to_string());
1097 let v = sql_value_to_value(
1098 "a",
1099 &ConcreteDataType::int32_datatype(),
1100 &sql_val,
1101 None,
1102 None,
1103 false,
1104 );
1105 assert!(v.is_err());
1106
1107 let sql_val = SqlValue::SingleQuotedString("not_a_number".to_string());
1110 let v = sql_value_to_value(
1111 "a",
1112 &ConcreteDataType::int32_datatype(),
1113 &sql_val,
1114 None,
1115 None,
1116 true,
1117 );
1118 assert!(v.is_err());
1119
1120 let sql_val = SqlValue::SingleQuotedString("true".to_string());
1122 let v = sql_value_to_value(
1123 "a",
1124 &ConcreteDataType::boolean_datatype(),
1125 &sql_val,
1126 None,
1127 None,
1128 true,
1129 )
1130 .unwrap();
1131 assert_eq!(Value::Boolean(true), v);
1132
1133 let sql_val = SqlValue::SingleQuotedString("hello".to_string());
1135 let v = sql_value_to_value(
1136 "a",
1137 &ConcreteDataType::string_datatype(),
1138 &sql_val,
1139 None,
1140 None,
1141 true,
1142 );
1143 assert!(v.is_ok());
1144 }
1145
1146 #[test]
1147 fn test_sql_number_to_value_timestamp_strict_typing() {
1148 let timestamp_type = TimestampType::Millisecond(datatypes::types::TimestampMillisecondType);
1150 let data_type = ConcreteDataType::Timestamp(timestamp_type);
1151
1152 let millisecond_str = "1747814093865";
1154 let result = sql_number_to_value(&data_type, millisecond_str).unwrap();
1155 if let Value::Timestamp(ts) = result {
1156 assert_eq!(ts.unit(), TimeUnit::Millisecond);
1157 assert_eq!(ts.value(), 1747814093865);
1158 } else {
1159 panic!("Expected timestamp value");
1160 }
1161
1162 let nanosecond_str = "1747814093865000000"; let result = sql_number_to_value(&data_type, nanosecond_str);
1165 assert!(
1166 result.is_err(),
1167 "Should reject overly large timestamp values"
1168 );
1169 }
1170
1171 #[test]
1172 fn test_sql_number_to_value_timestamp_different_units() {
1173 let second_type = TimestampType::Second(datatypes::types::TimestampSecondType);
1175 let second_data_type = ConcreteDataType::Timestamp(second_type);
1176
1177 let second_str = "1747814093";
1178 let result = sql_number_to_value(&second_data_type, second_str).unwrap();
1179 if let Value::Timestamp(ts) = result {
1180 assert_eq!(ts.unit(), TimeUnit::Second);
1181 assert_eq!(ts.value(), 1747814093);
1182 } else {
1183 panic!("Expected timestamp value");
1184 }
1185
1186 let nanosecond_type = TimestampType::Nanosecond(datatypes::types::TimestampNanosecondType);
1188 let nanosecond_data_type = ConcreteDataType::Timestamp(nanosecond_type);
1189
1190 let nanosecond_str = "1747814093865000000";
1191 let result = sql_number_to_value(&nanosecond_data_type, nanosecond_str).unwrap();
1192 if let Value::Timestamp(ts) = result {
1193 assert_eq!(ts.unit(), TimeUnit::Nanosecond);
1194 assert_eq!(ts.value(), 1747814093865000000);
1195 } else {
1196 panic!("Expected timestamp value");
1197 }
1198 }
1199
1200 #[test]
1201 fn test_timestamp_range_validation() {
1202 let nanosecond_value = 1747814093865000000i64; let nanosecond_type = TimestampType::Nanosecond(datatypes::types::TimestampNanosecondType);
1207 let nanosecond_data_type = ConcreteDataType::Timestamp(nanosecond_type);
1208 let result = sql_number_to_value(&nanosecond_data_type, "1747814093865000000");
1209 assert!(
1210 result.is_ok(),
1211 "Nanosecond value should be valid for nanosecond column"
1212 );
1213
1214 let millisecond_type =
1216 TimestampType::Millisecond(datatypes::types::TimestampMillisecondType);
1217 let millisecond_data_type = ConcreteDataType::Timestamp(millisecond_type);
1218 let result = sql_number_to_value(&millisecond_data_type, "1747814093865000000");
1219 assert!(
1220 result.is_err(),
1221 "Nanosecond value should be rejected for millisecond column"
1222 );
1223
1224 assert!(
1226 nanosecond_value > Timestamp::MAX_MILLISECOND.value(),
1227 "Test value should exceed millisecond range"
1228 );
1229 }
1230}