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