From cd6536b4aa9972fa293d3672c39ff7fac7075f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karol=20Bary=C5=82a?= Date: Sat, 11 Nov 2023 20:24:56 +0100 Subject: [PATCH] SerializeRow: Add is_empty method Currently ongoing serialization refactor requires to only perform queries with values using prepared statements. Session interface still allows to pass values in query* methods, so we need a way to know if we can perform unprepared query or not. One way is to always perform prepared queries, but that is not optimal. Before ongoing refactor we could serialize values and check if they are empty. This will no longer be possible soon, because serializing will require knowing column types, which in this case means having a prepared statement. This commit implements third way - additional method on SerializeRow trait that allows us to check if values are empty (in which case we can skip the prepare). --- scylla-cql/src/types/serialize/row.rs | 34 +++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/scylla-cql/src/types/serialize/row.rs b/scylla-cql/src/types/serialize/row.rs index c2d8a45246..a6becae851 100644 --- a/scylla-cql/src/types/serialize/row.rs +++ b/scylla-cql/src/types/serialize/row.rs @@ -53,6 +53,8 @@ pub trait SerializeRow { ctx: &RowSerializationContext<'_>, writer: &mut W, ) -> Result<(), SerializationError>; + + fn is_empty(&self) -> bool; } macro_rules! fallback_impl_contents { @@ -69,6 +71,9 @@ macro_rules! fallback_impl_contents { ) -> Result<(), SerializationError> { serialize_legacy_row(self, ctx, writer) } + fn is_empty(&self) -> bool { + SerializedValues::is_empty(self) + } }; } @@ -96,6 +101,10 @@ macro_rules! impl_serialize_row_for_unit { // Row is empty - do nothing Ok(()) } + + fn is_empty(&self) -> bool { + true + } }; } @@ -152,6 +161,10 @@ macro_rules! impl_serialize_row_for_slice { } Ok(()) } + + fn is_empty(&self) -> bool { + <[T]>::is_empty(self.as_ref()) + } }; } @@ -227,6 +240,12 @@ macro_rules! impl_serialize_row_for_map { Ok(()) } + + fn is_empty(&self) -> bool { + // Not sure how to make sure I call `is_empty` method from specific, not from a trait recursively, + // so I used `len()` which is not present in the trait. + self.len() == 0 + } }; } @@ -258,6 +277,10 @@ impl SerializeRow for &T { ) -> Result<(), SerializationError> { ::serialize(self, ctx, writer) } + + fn is_empty(&self) -> bool { + ::is_empty(self) + } } impl SerializeRow for SerializedValues { @@ -325,6 +348,10 @@ macro_rules! impl_tuple { )* Ok(()) } + + fn is_empty(&self) -> bool { + $length == 0 + } } }; } @@ -428,6 +455,13 @@ macro_rules! impl_serialize_row_via_value_list { ) -> ::std::result::Result<(), $crate::types::serialize::SerializationError> { $crate::types::serialize::row::serialize_legacy_row(self, ctx, writer) } + + fn is_empty(&self) -> bool { + match $crate::frame::value::ValueList::serialized(self) { + Ok(s) => s.is_empty(), + Err(e) => false + } + } } }; }