diff --git a/src/common/src/types/jsonb.rs b/src/common/src/types/jsonb.rs index 707704ad5aacd..4a625faec1cb8 100644 --- a/src/common/src/types/jsonb.rs +++ b/src/common/src/types/jsonb.rs @@ -16,13 +16,10 @@ use std::fmt; use std::hash::Hash; use bytes::Buf; -use jsonbb::{Builder, Value, ValueRef}; +use jsonbb::{Value, ValueRef}; use crate::estimate_size::EstimateSize; -use crate::types::{ - Date, Decimal, Int256Ref, Interval, Scalar, ScalarRef, Serial, Time, Timestamp, ToText, F32, - F64, -}; +use crate::types::{Scalar, ScalarRef}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct JsonbVal(pub(crate) Value); @@ -196,6 +193,18 @@ impl From for JsonbVal { } } +impl From> for JsonbVal { + fn from(v: JsonbRef<'_>) -> Self { + Self(v.0.to_owned()) + } +} + +impl From for JsonbVal { + fn from(v: f64) -> Self { + Self(v.into()) + } +} + impl<'a> From> for ValueRef<'a> { fn from(v: JsonbRef<'a>) -> Self { v.0 @@ -416,100 +425,3 @@ impl std::io::Write for FmtToIoUnchecked { Ok(()) } } -impl From for Value { - fn from(v: F32) -> Self { - if v.0 == f32::INFINITY { - "Infinity".into() - } else if v.0 == f32::NEG_INFINITY { - "-Infinity".into() - } else if v.0.is_nan() { - "NaN".into() - } else { - v.0.into() - } - } -} - -// NOTE: Infinite or NaN values are not JSON numbers. They are stored as strings in Postgres. -impl From for Value { - fn from(v: F64) -> Self { - if v.0 == f64::INFINITY { - "Infinity".into() - } else if v.0 == f64::NEG_INFINITY { - "-Infinity".into() - } else if v.0.is_nan() { - "NaN".into() - } else { - v.0.into() - } - } -} - -impl From> for Value { - fn from(v: JsonbRef<'_>) -> Self { - v.0.to_owned() - } -} - -impl From for Value { - fn from(v: Decimal) -> Self { - // Make it numeric if it can be converted to IEEE 754 double, otherwise a string. - // May loss precision here. - let res: Result = v.try_into(); - if let Ok(value) = res { - value.into() - } else { - v.to_text().as_str().into() - } - } -} - -impl From for Value { - fn from(v: Timestamp) -> Self { - let mut builder = Builder::default(); - builder.display(format!("{}T{}", v.0.date(), v.0.time())); - builder.finish() - } -} - -macro_rules! impl_convert_to_value { - ($scalar_type:ty) => { - impl From<$scalar_type> for Value { - fn from(v: $scalar_type) -> Self { - v.to_text().as_str().into() - } - } - }; -} - -impl_convert_to_value!(Serial); -impl_convert_to_value!(Int256Ref<'_>); -impl_convert_to_value!(Date); -impl_convert_to_value!(Time); -impl_convert_to_value!(Interval); - -macro_rules! impl_convert_to_jsonb_val { - ($scalar_ref:ty) => { - impl<'scalar> From<$scalar_ref> for JsonbVal { - fn from(val: $scalar_ref) -> Self { - Self(val.into()) - } - } - }; -} - -impl_convert_to_jsonb_val!(bool); -impl_convert_to_jsonb_val!(i16); -impl_convert_to_jsonb_val!(i32); -impl_convert_to_jsonb_val!(i64); -impl_convert_to_jsonb_val!(Int256Ref<'_>); -impl_convert_to_jsonb_val!(F32); -impl_convert_to_jsonb_val!(F64); -impl_convert_to_jsonb_val!(Decimal); -impl_convert_to_jsonb_val!(Serial); -impl_convert_to_jsonb_val!(Date); -impl_convert_to_jsonb_val!(Time); -impl_convert_to_jsonb_val!(Timestamp); -impl_convert_to_jsonb_val!(Interval); -impl_convert_to_jsonb_val!(&str); -impl_convert_to_jsonb_val!(JsonbRef<'_>); diff --git a/src/expr/impl/benches/expr.rs b/src/expr/impl/benches/expr.rs index 010508c8de45e..685b5de98c1e8 100644 --- a/src/expr/impl/benches/expr.rs +++ b/src/expr/impl/benches/expr.rs @@ -170,7 +170,7 @@ fn bench_expr(c: &mut Criterion) { // 25: serial array SerialArray::from_iter((1..=CHUNK_SIZE).map(|i| Serial::from(i as i64))).into_ref(), // 26: jsonb array - JsonbArray::from_iter((1..=CHUNK_SIZE).map(|i| JsonbVal::from(i as i64))).into_ref(), + JsonbArray::from_iter((1..=CHUNK_SIZE).map(|i| JsonbVal::from(i as f64))).into_ref(), // 27: int256 array Int256Array::from_iter((1..=CHUNK_SIZE).map(|_| Int256::from(1))).into_ref(), // 28: extract field for interval diff --git a/src/expr/impl/src/scalar/to_jsonb.rs b/src/expr/impl/src/scalar/to_jsonb.rs index 16e4763639630..8bf24be4e9542 100644 --- a/src/expr/impl/src/scalar/to_jsonb.rs +++ b/src/expr/impl/src/scalar/to_jsonb.rs @@ -204,7 +204,7 @@ impl ToJsonb for F64 { } else if self.0.is_nan() { "NaN".add_to(builder)?; } else { - builder.add_f64(self.0 as f64); + builder.add_f64(self.0); } Ok(()) }