diff --git a/libs/prisma-value/src/lib.rs b/libs/prisma-value/src/lib.rs index 1aff2618f597..575ab97465a4 100644 --- a/libs/prisma-value/src/lib.rs +++ b/libs/prisma-value/src/lib.rs @@ -73,6 +73,10 @@ pub fn decode_bytes(s: impl AsRef<[u8]>) -> PrismaValueResult> { base64::decode(s).map_err(|_| ConversionFailure::new("base64 encoded bytes", "PrismaValue::Bytes")) } +pub fn parse_decimal(str: &str) -> std::result::Result { + BigDecimal::from_str(str).map(|bd| bd.normalized()) +} + impl TryFrom for PrismaValue { type Error = crate::error::ConversionFailure; diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/float.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/float.rs index 46454291ffe9..6dfb6fbc2ff3 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/float.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/float.rs @@ -55,7 +55,7 @@ mod float { insta::assert_snapshot!( res, - @r###"{"data":{"findManyTestModel":[{"float":1.2},{"float":13.37},{"float":null}]}}"### + @r###"{"data":{"findManyTestModel":[{"float":1.2},{"float":13.37},{"float":1.234567891011121},{"float":null}]}}"### ); } EngineProtocol::Json => { @@ -75,7 +75,7 @@ mod float { insta::assert_snapshot!( res.to_string(), - @r###"{"data":{"findManyTestModel":[{"float":1.2},{"float":13.37},{"float":null}]}}"### + @r###"{"data":{"findManyTestModel":[{"float":1.2},{"float":13.37},{"float":1.234567891011121},{"float":null}]}}"### ); } } @@ -86,7 +86,8 @@ mod float { async fn create_test_data(runner: &Runner) -> TestResult<()> { create_row(runner, r#"{ id: 1, float: 1.2 }"#).await?; create_row(runner, r#"{ id: 2, float: 13.37 }"#).await?; - create_row(runner, r#"{ id: 3 }"#).await?; + create_row(runner, r#"{ id: 3, float: 1.23456789101112131415161718192 }"#).await?; + create_row(runner, r#"{ id: 4 }"#).await?; Ok(()) } diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/native/postgres.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/native/postgres.rs index 28cc1d40ff40..f99f850987b8 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/native/postgres.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/native/postgres.rs @@ -108,10 +108,10 @@ mod decimal { id: 1, child: { create: { id: 1, - float: 1.1, - dfloat: 2.2, - decFloat: 3.1234, - money: 3.51, + float: 1.23456789101112131415161718192, + dfloat: 1.23456789101112131415161718192, + decFloat: 1.23456789101112131415161718192, + money: 1.23456789101112131415161718192, }} }"#, ) @@ -119,7 +119,12 @@ mod decimal { insta::assert_snapshot!( run_query!(&runner, r#"{ findManyParent { id child { float dfloat decFloat money } } }"#), - @r###"{"data":{"findManyParent":[{"id":1,"child":{"float":1.1,"dfloat":2.2,"decFloat":"3.1","money":"3.51"}}]}}"### + @r###"{"data":{"findManyParent":[{"id":1,"child":{"float":1.2345679,"dfloat":1.234567891011121,"decFloat":"1.2","money":"1.23"}}]}}"### + ); + + insta::assert_snapshot!( + run_query!(&runner, r#"{ findManyChild { float dfloat decFloat money } }"#), + @r###"{"data":{"findManyChild":[{"float":1.2345679,"dfloat":1.234567891011121,"decFloat":"1.2","money":"1.23"}]}}"### ); Ok(()) diff --git a/query-engine/connectors/sql-query-connector/src/database/operations/read/coerce.rs b/query-engine/connectors/sql-query-connector/src/database/operations/read/coerce.rs index d570eab105a7..87fbe8ce86ef 100644 --- a/query-engine/connectors/sql-query-connector/src/database/operations/read/coerce.rs +++ b/query-engine/connectors/sql-query-connector/src/database/operations/read/coerce.rs @@ -1,7 +1,6 @@ -use bigdecimal::{BigDecimal, ParseBigDecimalError}; use itertools::Itertools; use query_structure::*; -use std::{borrow::Cow, io, str::FromStr}; +use std::{borrow::Cow, io}; use crate::SqlError; @@ -301,7 +300,3 @@ fn build_generic_conversion_error(message: String) -> SqlError { let error = io::Error::new(io::ErrorKind::InvalidData, message); SqlError::ConversionError(error.into()) } - -fn parse_decimal(str: &str) -> std::result::Result { - BigDecimal::from_str(str).map(|bd| bd.normalized()) -} diff --git a/query-engine/connectors/sql-query-connector/src/row.rs b/query-engine/connectors/sql-query-connector/src/row.rs index e4687acca83f..32bf928dd7b1 100644 --- a/query-engine/connectors/sql-query-connector/src/row.rs +++ b/query-engine/connectors/sql-query-connector/src/row.rs @@ -2,6 +2,7 @@ use crate::{column_metadata::ColumnMetadata, error::SqlError, value::to_prisma_v use bigdecimal::{BigDecimal, FromPrimitive, ToPrimitive}; use chrono::{DateTime, NaiveDate, Utc}; use connector_interface::{coerce_null_to_zero_value, AggregationResult, AggregationSelection}; +use prisma_value::parse_decimal; use quaint::{connector::ResultRow, Value, ValueType}; use query_structure::{ConversionFailure, FieldArity, PrismaValue, Record, TypeIdentifier}; use std::{io, str::FromStr}; @@ -209,7 +210,7 @@ fn row_value_to_prisma_value(p_value: Value, meta: ColumnMetadata<'_>) -> Result ValueType::Float(Some(f)) => match f { f if f.is_nan() => return Err(create_error(&p_value)), f if f.is_infinite() => return Err(create_error(&p_value)), - _ => PrismaValue::Float(BigDecimal::from_f32(f).unwrap().normalized()), + _ => PrismaValue::Float(parse_decimal(&f.to_string()).unwrap()), }, ValueType::Int32(Some(i)) => match BigDecimal::from_i32(i) { Some(dec) => PrismaValue::Float(dec),