From 62d56b483730796174d0edf568d8e431512c5b26 Mon Sep 17 00:00:00 2001 From: Flavian Desverne Date: Wed, 17 Jul 2024 15:30:35 +0200 Subject: [PATCH] fix(qe): support MySQL base64 newlines Co-authored-by: Alexey Orlenko --- libs/prisma-value/src/lib.rs | 2 +- .../mysql_datamodel_connector.rs | 20 ++++++++++++++++++- .../queries/data_types/through_relation.rs | 6 +++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/libs/prisma-value/src/lib.rs b/libs/prisma-value/src/lib.rs index 0d6fe54a254e..1aff2618f597 100644 --- a/libs/prisma-value/src/lib.rs +++ b/libs/prisma-value/src/lib.rs @@ -69,7 +69,7 @@ pub fn encode_bytes(bytes: &[u8]) -> String { base64::encode(bytes) } -pub fn decode_bytes(s: &str) -> PrismaValueResult> { +pub fn decode_bytes(s: impl AsRef<[u8]>) -> PrismaValueResult> { base64::decode(s).map_err(|_| ConversionFailure::new("base64 encoded bytes", "PrismaValue::Bytes")) } diff --git a/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector.rs b/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector.rs index 3fbf98ed2bb3..69a1f3b6e05f 100644 --- a/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector.rs +++ b/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector.rs @@ -288,7 +288,10 @@ impl Connector for MySqlDatamodelConnector { // On MySQL, bytes are encoded as base64 in the database directly. fn parse_json_bytes(&self, str: &str, _nt: Option) -> PrismaValueResult> { - decode_bytes(str) + let mut buf = vec![0; str.len()]; + + // MySQL base64 encodes bytes with newlines every 76 characters. + decode_bytes(sanitize_base64(str, &mut buf)) } fn runtime_join_strategy_support(&self) -> JoinStrategySupport { @@ -300,3 +303,18 @@ impl Connector for MySqlDatamodelConnector { } } } + +/// Removes newlines from a base64 string. +fn sanitize_base64<'a>(mut s: &str, buf: &'a mut [u8]) -> &'a [u8] { + let mut pos = 0; + + while !s.is_empty() && pos < buf.len() { + let nl = s.find('\n').unwrap_or(s.len()); + let len = nl.min(buf.len() - pos); + buf[pos..pos + len].copy_from_slice(&s.as_bytes()[..len]); + pos += len; + s = &s[(nl + 1).min(s.len())..]; + } + + &buf[0..pos] +} diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/through_relation.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/through_relation.rs index 85389968417f..361953644395 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/through_relation.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/data_types/through_relation.rs @@ -37,12 +37,12 @@ mod scalar_relations { insta::assert_snapshot!( run_query!(&runner, r#"{ findManyParent { id children { childId string int bInt float bytes bool dt } } }"#), - @r###"{"data":{"findManyParent":[{"id":1,"children":[{"childId":1,"string":"abc","int":1,"bInt":"1","float":1.5,"bytes":"AQID","bool":false,"dt":"1900-10-10T01:10:10.001Z"},{"childId":2,"string":"def","int":-4234234,"bInt":"14324324234324","float":-2.54367,"bytes":"FDSF","bool":true,"dt":"1999-12-12T21:12:12.121Z"}]}]}}"### + @r###"{"data":{"findManyParent":[{"id":1,"children":[{"childId":1,"string":"abc","int":1,"bInt":"1","float":1.5,"bytes":"VGhpcyBpcyBhIGxhcmdlIGJhc2U2NCBzdHJpbmcgdGhhdCBlbnN1cmVzIHdlIHNhbml0aXplIHRoZSBvdXRwdXQgb2YgTXlTUUwgYmFzZTY0IHN0cmluZy4=","bool":false,"dt":"1900-10-10T01:10:10.001Z"},{"childId":2,"string":"def","int":-4234234,"bInt":"14324324234324","float":-2.54367,"bytes":"FDSF","bool":true,"dt":"1999-12-12T21:12:12.121Z"}]}]}}"### ); insta::assert_snapshot!( run_query!(&runner, r#"{ findUniqueParent(where: { id: 1 }) { id children { childId string int bInt float bytes bool dt } } }"#), - @r###"{"data":{"findUniqueParent":{"id":1,"children":[{"childId":1,"string":"abc","int":1,"bInt":"1","float":1.5,"bytes":"AQID","bool":false,"dt":"1900-10-10T01:10:10.001Z"},{"childId":2,"string":"def","int":-4234234,"bInt":"14324324234324","float":-2.54367,"bytes":"FDSF","bool":true,"dt":"1999-12-12T21:12:12.121Z"}]}}}"### + @r###"{"data":{"findUniqueParent":{"id":1,"children":[{"childId":1,"string":"abc","int":1,"bInt":"1","float":1.5,"bytes":"VGhpcyBpcyBhIGxhcmdlIGJhc2U2NCBzdHJpbmcgdGhhdCBlbnN1cmVzIHdlIHNhbml0aXplIHRoZSBvdXRwdXQgb2YgTXlTUUwgYmFzZTY0IHN0cmluZy4=","bool":false,"dt":"1900-10-10T01:10:10.001Z"},{"childId":2,"string":"def","int":-4234234,"bInt":"14324324234324","float":-2.54367,"bytes":"FDSF","bool":true,"dt":"1999-12-12T21:12:12.121Z"}]}}}"### ); insta::assert_snapshot!( @@ -327,7 +327,7 @@ mod scalar_relations { int: 1, bInt: 1, float: 1.5, - bytes: "AQID", + bytes: "VGhpcyBpcyBhIGxhcmdlIGJhc2U2NCBzdHJpbmcgdGhhdCBlbnN1cmVzIHdlIHNhbml0aXplIHRoZSBvdXRwdXQgb2YgTXlTUUwgYmFzZTY0IHN0cmluZy4=", bool: false, dt: "1900-10-10T01:10:10.001Z", }"#,