Skip to content

Commit 0d216b0

Browse files
committed
deserialize/value: accept shorter encoded tuples
When deserializing tuples, if the encoded data is shorter than expected (i.e., it contains fewer elements than the tuple type specifies), we should treat the missing elements as nulls instead of returning an error. This is what other drivers (Python, Java, Node.js) do, and it improves compatibility with ScyllaDB/Cassandra, which allow inserting tuples with fewer elements than the defined type. Fixes: #1452.
1 parent 78fb4de commit 0d216b0

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

scylla-cql/src/deserialize/value.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,17 +1340,26 @@ macro_rules! impl_tuple {
13401340
let mut v = ensure_not_null_frame_slice::<Self>(typ, v)?;
13411341
let ret = (
13421342
$(
1343-
v.read_cql_bytes()
1344-
.map_err(|err| DeserializationError::new(err))
1345-
.and_then(|cql_bytes| <$Ti>::deserialize($idf, cql_bytes))
1346-
.map_err(|err| mk_deser_err::<Self>(
1347-
typ,
1348-
TupleDeserializationErrorKind::FieldDeserializationFailed {
1349-
position: $idx,
1350-
err,
1351-
}
1352-
)
1353-
)?,
1343+
{
1344+
let cql_bytes = if v.is_empty() {
1345+
// Special case: if there are no bytes left to read, consider the tuple element as null.
1346+
// This is needed to handle tuples with less elements than expected
1347+
// (see https://github.com/scylladb/scylla-rust-driver/issues/1452 for context).
1348+
None
1349+
} else {
1350+
v.read_cql_bytes().map_err(|err| DeserializationError::new(err))?
1351+
};
1352+
1353+
<$Ti>::deserialize($idf, cql_bytes)
1354+
.map_err(|err| mk_deser_err::<Self>(
1355+
typ,
1356+
TupleDeserializationErrorKind::FieldDeserializationFailed {
1357+
position: $idx,
1358+
err,
1359+
}
1360+
)
1361+
)?
1362+
},
13541363
)*
13551364
);
13561365
Ok(ret)

0 commit comments

Comments
 (0)